Обнаружение пиков измеряемого сигнала - PullRequest
58 голосов
/ 06 августа 2008

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

Это хорошо работает, если наибольшее значение - это пик, который мы ищем, но если устройство работает неправильно, мы можем увидеть второй пик, который может быть выше, чем начальный пик. Мы принимаем 10 показаний в секунду с 16 устройств в течение 90 секунд.

Мои первые мысли заключаются в том, чтобы циклически проверять показания, чтобы увидеть, меньше ли предыдущая и следующая точки, чем текущая, чтобы найти пик и построить массив пиков. Возможно, мы должны смотреть на среднее число точек по обе стороны от текущей позиции, чтобы учесть шум в системе. Это лучший способ продолжить или есть лучшие методы?


Мы используем LabVIEW, и я проверил LAVA форумы , и есть много интересных примеров. Это часть нашего тестового программного обеспечения, и мы стараемся избегать использования слишком большого количества нестандартных библиотек VI, поэтому я надеялся получить отзывы о задействованных процессах / алгоритмах, а не о конкретном коде.

Ответы [ 9 ]

83 голосов
/ 04 сентября 2008

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

  1. Между любыми двумя точками в ваших данных, (x(0), y(0)) и (x(n), y(n)), сложите y(i + 1) - y(i) для 0 <= i < n и назовите это T ("путешествие") и установите R ("повышение) ") до y(n) - y(0) + k для достаточно малого k. T/R > 1 обозначает пик. Это работает нормально, если большое перемещение из-за шума маловероятно или если шум распределяется симметрично вокруг формы базовой кривой. Для вашего приложения примите самый ранний пик с оценкой выше заданного порогового значения или проанализируйте значения кривой перемещения на подъем для более интересных свойств.

  2. Используйте согласованные фильтры для оценки сходства со стандартной формой пика (по существу, используйте нормализованный точечный продукт для некоторой формы, чтобы получить косинометрическую метрику сходства)

  3. Деконволюция по стандартной форме пика и проверка на высокие значения (хотя я часто нахожу 2 менее чувствительными к шуму для простого вывода инструментов).

  4. Сгладьте данные и проверьте на наличие тройки точек с равным интервалом, если, если x0 < x1 < x2, y1 > 0.5 * (y0 + y2), или проверьте евклидовы расстояния следующим образом: D((x0, y0), (x1, y1)) + D((x1, y1), (x2, y2)) > D((x0, y0),(x2, y2)), что основано на неравенстве треугольника. Использование простых соотношений снова предоставит вам механизм подсчета очков.

  5. Установите очень простую 2-гауссову модель смеси для ваших данных (например, в Numeric Recipes есть хороший готовый кусок кода). Возьми ранний пик. Это будет правильно работать с перекрывающимися пиками.

  6. Найдите наилучшее совпадение в данных с простой кривой Гаусса, Коши, Пуассона или «что у вас есть». Оцените эту кривую в широком диапазоне и вычтите ее из копии данных, отметив ее пиковое местоположение. Повторение. Возьмем самый ранний пик, чьи параметры модели (возможно, стандартное отклонение, но некоторые приложения могут заботиться о куртозе или других особенностях) соответствуют некоторому критерию. Остерегайтесь артефактов, оставшихся позади, когда пики вычитаются из данных. Наилучшее совпадение может определяться видом подсчета совпадений, предложенным в # 2 выше.

Я делал то, что вы делаете раньше: находя пики в данных последовательности ДНК, находя пики в производных, оцененных по измеренным кривым, и находя пики в гистограммах.

Я призываю вас внимательно следить за надлежащим базовым уровнем. Фильтрация Винера или другая фильтрация или простой анализ гистограммы часто являются простым способом определения базовой линии при наличии шума.

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

10 голосов
/ 06 августа 2008

Вы можете попробовать усреднение сигнала, то есть для каждой точки, усредните значение с окружающими 3 или более точками. Если шумовые помехи огромны, то даже это может не помочь.

Я понимаю, что это не зависело от языка, но, предположив, что вы используете LabView, есть много готовых VI для обработки сигналов, которые поставляются с LabView, которые вы можете использовать для сглаживания и уменьшения шума. NI форумы - отличное место, чтобы получить более специализированную помощь по таким вопросам.

6 голосов
/ 04 ноября 2015

Я бы хотел добавить в эту ветку алгоритм, который я разработал сам :

Он основан на принципе дисперсии : если новая точка данных представляет собой заданное число x стандартных отклонений от некоторого скользящего среднего, алгоритм подает сигнал (также называемый z-счет ). Алгоритм очень надежен, потому что он создает отдельное скользящее среднее и отклонение, так что сигналы не нарушают порог. Поэтому будущие сигналы идентифицируются примерно с одинаковой точностью, независимо от количества предыдущих сигналов. Алгоритм принимает 3 входа: lag = the lag of the moving window, threshold = the z-score at which the algorithm signals и influence = the influence (between 0 and 1) of new signals on the mean and standard deviation. Например, lag из 5 будет использовать последние 5 наблюдений для сглаживания данных. Значение threshold, равное 3,5, будет сигнализировать, если точка данных находится в 3,5 стандартных отклонениях от скользящего среднего. И influence 0,5 дает сигналы половину влияния, которое имеют нормальные точки данных. Аналогичным образом, influence из 0 полностью игнорирует сигналы для пересчета нового порога: поэтому влияние 0 является наиболее надежным вариантом.

Работает следующим образом:

псевдокод

# Let y be a vector of timeseries data of at least length lag+2
# Let mean() be a function that calculates the mean
# Let std() be a function that calculates the standard deviaton
# Let absolute() be the absolute value function

# Settings (the ones below are examples: choose what is best for your data)
set lag to 5;          # lag 5 for the smoothing functions
set threshold to 3.5;  # 3.5 standard deviations for signal
set influence to 0.5;  # between 0 and 1, where 1 is normal influence, 0.5 is half

# Initialise variables
set signals to vector 0,...,0 of length of y;   # Initialise signal results
set filteredY to y(1,...,lag)                   # Initialise filtered series
set avgFilter to null;                          # Initialise average filter
set stdFilter to null;                          # Initialise std. filter
set avgFilter(lag) to mean(y(1,...,lag));       # Initialise first value
set stdFilter(lag) to std(y(1,...,lag));        # Initialise first value

for i=lag+1,...,t do
  if absolute(y(i) - avgFilter(i-1)) > threshold*stdFilter(i-1) then
    if y(i) > avgFilter(i-1)
      set signals(i) to +1;                     # Positive signal
    else
      set signals(i) to -1;                     # Negative signal
    end
    # Adjust the filters
    set filteredY(i) to influence*y(i) + (1-influence)*filteredY(i-1);
    set avgFilter(i) to mean(filteredY(i-lag,i),lag);
    set stdFilter(i) to std(filteredY(i-lag,i),lag);
  else
    set signals(i) to 0;                        # No signal
    # Adjust the filters
    set filteredY(i) to y(i);
    set avgFilter(i) to mean(filteredY(i-lag,i),lag);
    set stdFilter(i) to std(filteredY(i-lag,i),lag);
  end
end

Демо

Demonstration of robust thresholding algorithm

> Оригинальный ответ

6 голосов
/ 23 августа 2008

Эта проблема была детально изучена.

Существует ряд очень современных реализаций в классах TSpectrum* ROOT (инструмент анализа ядерной физики / физики элементарных частиц). Код работает в одно- и трехмерных данных.

Доступен исходный код ROOT, поэтому вы можете получить эту реализацию, если хотите.

Из документации TSpectrum :

Алгоритмы, используемые в этом классе, были опубликованы в следующих ссылках:

[1] М. Морхач и др .: Фон методы устранения для многомерное совпадение гамма-лучей спектры. Ядерные инструменты и Методы в физике исследований А 401 (1997) 113- 132.

[2] М. Морхак и др .: Эффективное одно- и двумерное золото деконволюция и ее применение к декомпозиция гамма-спектров. Ядерные приборы и методы в Physics Research A 401 (1997) 385-408.

[3] М. Морхач и др .: Идентификация пиков в многомерное совпадение гамма-лучей спектры. Ядерные инструменты и Методы исследования физики А 443 (2000), 108-125.

Документы связаны с документацией класса для тех из вас, у кого нет онлайн-подписки NIM.


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

4 голосов
/ 02 сентября 2008

Этот метод в основном из книги Дэвида Марра "Видение"

Гауссово размытие вашего сигнала с ожидаемой шириной ваших пиков. это избавляет от всплесков шума и ваши данные фазы не повреждены.

Затем обнаружение края (LOG сделает)

Тогда ваши края были краями элементов (например, пиков). ищите пики между краями, сортируйте пики по размеру, и все готово.

Я использовал эти варианты, и они работают очень хорошо.

2 голосов
/ 06 августа 2008

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

0 голосов
/ 02 сентября 2008

Есть ли качественная разница между желаемым пиком и нежелательным вторым пиком? Если оба пика являются «острыми» - то есть короткими по времени - при просмотре сигнала в частотной области (выполняя БПФ) вы получите энергию в большинстве полос. Но если в «хорошем» пике надежно присутствует энергия на частотах, которых нет в «плохом» пике, или наоборот, вы можете автоматически их дифференцировать.

0 голосов
/ 06 августа 2008

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

0 голосов
/ 06 августа 2008

Вы можете применить Стандартное отклонение к вашей логике и заметить пики свыше x%.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...