2009-05-08 4 views
3

MATLAB FAQ описывает метод однострочный для нахождения локальных Maximas:Нахождение приближенного локальных Maximas с зашумленных данных в Matlab

index = find(diff(sign(diff([0; x(:); 0]))) < 0); 

Но я считаю, это работает только, если данные более или менее гладко. Предположим, у вас есть данные, которые вскакивают вверх и вниз с небольшими интервалами, но при этом имеют приблизительные локальные максимы. Как бы вы решили найти эти моменты? Вы можете разделить вектор на n частей и найти наибольшее значение не на краю каждого, но должно быть более элегантное и быстрое решение.

Однострочное решение также будет отличным.

Редактировать: Я работаю с шумными биологическими изображениями, которые я пытаюсь разделить на отдельные разделы.

+0

Поскольку вы обновили свой вопрос, чтобы сказать, что работаете с изображениями, то уравнение максимума нахождения выше (что более конкретно относится к векторам) может быть не идеальным для вас. Я бы предложил посмотреть на Image Processing Toolbox в MATLAB, если у вас есть к нему доступ. Там могут быть некоторые операции, чтобы помочь вам; просто введите «справочные образы» в MATLAB, чтобы проверить список функций. – gnovice

ответ

2

В зависимости от того, что вы хотите, часто бывает полезно фильтровать шумные данные. Взгляните на MEDFILT1 или используя CONV вместе с FSPECIAL. В последнем подходе вы, вероятно, захотите использовать «тот же» аргумент для CONV и «гауссовский» фильтр, созданный FSPECIAL.

После того, как вы сделали фильтрацию, пропустите ее через поиск максимумов.

EDIT:выполнения сложности

Допустим, входной вектор имеет длину X и длину фильтра ядра является К.

Средний фильтр может работать, делая бегущий вставки рода, так что должен быть O (X K + K log K). Я не смотрел исходный код, и возможны другие реализации, но в основном это должно быть O (X K).

Когда K мало, conv использует прямолинейный алгоритм O (X * K). Когда X и K почти одинаковы, то быстрее использовать быстрое преобразование Фурье. Эта реализация O (X log X + K log K). Matlab достаточно умен, чтобы автоматически выбирать правильный алгоритм в зависимости от размеров ввода.

+0

Замечательно! Мой друг-ученик, насколько это дорого стоит время? –

3

Я не уверен, с какими данными вы имеете дело, но вот метод, который я использовал для обработки речевых данных, которые могут помочь вам найти локальные максимумы. Он использует три функции из инструментальной панели обработки сигналов: HILBERT, BUTTER и FILTFILT.

data = (...the waveform of noisy data...); 
Fs = (...the sampling rate of the data...); 
[b,a] = butter(5,20/(Fs/2),'low'); % Create a low-pass butterworth filter; 
            % adjust the values as needed. 
smoothData = filtfilt(b,a,abs(hilbert(data))); % Apply a hilbert transform 
               % and filter the data. 

Вы бы затем выполнить ваши максимумы нахождение на smoothData. Использование HILBERT сначала создает положительный огибающий данных, затем FILTFILT использует коэффициенты фильтра от BUTTER для фильтра нижних частот для конверта данных.

Для примера того, как эта обработка работает, приведены некоторые изображения, показывающие результаты для сегмента записанной речи. Синяя линия - это исходный речевой сигнал, красная линия - конверт (полученная с использованием HILBERT), а зеленая линия - результат фильтрации с низким проходом. Нижняя цифра - увеличенная версия первой.

alt text

НЕЧТО RANDOM ПОПРОБОВАТЬ:

Это была случайная идея, которую я имел в первый ... вы могли бы попробовать повторять процесс, находя Maximas из Maximas:

index = find(diff(sign(diff([0; x(:); 0]))) < 0); 
maxIndex = index(find(diff(sign(diff([0; x(index); 0]))) < 0)); 

Однако, в зависимости от отношения сигнал/шум, было бы непонятно, сколько раз это нужно будет повторять, чтобы получить локальные максимумы, которые вас интересуют. Это просто рандо m для нефильтрации. =)

MAXIMA ВЫВОД:

Только в случае, если вам интересно, еще одна линия максимумов ознакомительной алгоритм, который я видел (в дополнение к тому, который был указан) является:

index = find((x > [x(1) x(1:(end-1))]) & (x >= [x(2:end) x(end)])); 
+0

Ты потрясающий! filterfilt - это «цифровая фильтрация с нулевой фазой» - означает ли это, что он гарантирует, что точки с высокой точкой в ​​отфильтрованных данных являются высокими точками в исходных данных? См. Также мое редактирование вопроса. –

+0

+1 только для симпатичных графиков. :) –

+1

@Joe S: нет. Фильтрация с нулевой фазой означает, что если в качестве входных сигналов имеются чистые синусоидальные волны, выходы будут иметь одну и ту же фазу.filterfilt работает, фильтруя вперед во времени, а затем назад во времени (что-то, что вы не можете делать в обработке сигналов в реальном времени), чтобы отменить временные задержки, вызванные фильтрами нижних частот. –

1

Если ваши данные перепрыгивают вверх и вниз много, тогда функция будет иметь множество локальных максимумов. Итак, я предполагаю, что вы не хотите найти все локальные максимумы. Но каковы ваши критерии того, что такое локальный максимум? Если у вас есть критерии, то для этого можно разработать схему или алгоритм.

Я бы предположил, что, возможно, вам следует сначала применить фильтр низких частот к вашим данным, а затем найти локальные максимумы. Хотя положения локальных максимумов после фильтрации могут не соответствовать в точности тем, что были до этого.

1

Существует два способа просмотра такой проблемы. Можно рассматривать это как прежде всего проблему сглаживания, используя инструмент фильтрации для сглаживания данных, только после этого для интерполяции с использованием некоторого разнообразия интерполяции, возможно, интерполяционного сплайна. Поиск локального максимума интерполирующего сплайна - достаточно простая вещь. (Обратите внимание, что здесь вы обычно должны использовать истинный сплайн, а не интерполятор pchip.Pchip, метод, используемый при указании «кубической» интерполяции в interp1, не будет точно определять местный минимизатор, который находится между двумя точками данных.)

Другой подход к такой проблеме - это тот, который я предпочитаю. Здесь используется сплайн-модель наименьших квадратов для сглаживания данных и получения аппроксимации вместо интерполяции. Такой сплайн с наименьшими квадратами имеет то преимущество, что позволяет пользователю осуществлять большой контроль, чтобы представить свои знания проблемы в модели. Например, часто ученый или инженер имеет информацию, такую ​​как монотонность, о изучаемом процессе. Это может быть встроено в сплайн-модель наименьших квадратов. Другим, связанным с этим вариантом является использование сглаживающего сплайна. Они также могут быть построены с установленными в них регулятивными ограничениями. Если у вас есть панель инструментов spline, то spap2 будет иметь некоторую полезность, чтобы соответствовать сплайновой модели. Тогда fnmin найдет минимизатор. (Максимизатор легко получается из кода минимизации.)

Схемы сглаживания, которые используют методы фильтрации, как правило, просты, когда точки данных равномерно распределены. Неравномерность интервалов может привести к модели сплайна наименьших квадратов. С другой стороны, размещение узлов может быть проблемой в сплайнах наименьших квадратов. Моя точка зрения заключается в том, чтобы предположить, что любой из этих подходов имеет свои достоинства и может быть сделан для получения жизнеспособных результатов.