Обнаружение закономерностей в волнах - PullRequest
74 голосов
/ 04 февраля 2010

Я пытаюсь прочитать изображение с электрокардиографии и определить каждую из основных волн в нем (зубец Р, комплекс QRS и зубец Т). Теперь я могу прочитать изображение и получить вектор, подобный (4.2; 4.4; 4.9; 4.7; ...), представляющий значения в электрокардиографии, что составляет половину проблемы. Мне нужен алгоритм, который может пройти через этот вектор и определить, когда каждая из волн начинается и заканчивается.

Вот пример одного из его графиков:

alt text

Было бы легко, если бы у них всегда был один и тот же размер, но это не так, как если бы он работал, или если бы я знал, сколько волн будет иметь ЭКГ, но он также может варьироваться. У кого-нибудь есть идеи?

Спасибо!

Обновление

Пример того, чего я пытаюсь достичь:

Учитывая волну

alt text

Я могу извлечь вектор

[0; 0; 20; 20; 20; 19; 18; 17; 17; 17; 17; 17; 16; 16; 16; 16; 16; 16; 16; 17; 17; 18; 19; 20; 21; 22; 23; 23; 23; 25; 25; 23; 22; 20; 19; 17; 16; 16; 14; 13; 14; 13; 13; 12; 12; 12; 12; 12; 11; 11; 10; 12; 16; 22; 31; 38; 45; 51; 47; 41; 33; 26; 21; 17; 17; 16; 16; 15; 16; 17; 17; 18; 18; 17; 18; 18; 18; 18; 18; 18; 18; 17; 17; 18; 19; 18; 18; 19; 19; 19; 19; 20; 20; 19; 20; 22; 24; 24; 25; 26; 27; 28; 29; 30; 31; 31; 31; 32; 32; 32; 31; 29; 28; 26; 24; 22; 20; 20; 19; 18; 18; 17; 17; 16; 16; 15; 15; 16; 15; 15; 15; 15; 15; 15; 15; 15; 15; 14; 15; 16; 16; 16; 16; 16; 16; 16; 16; 16; 15; 16; 15; 15; 15; 16; 16; 16; 16; 16; 16; 16; 16; 15; 16; 16; 16; 16; 16; 15; 15; 15; 15; 15; 16; 16; 17; 18; 18; 19; 19; 19; 20; 21; 22; 22; 22; 22; 21; 20; 18; 17; 17; 15; 15; 14; 14; 13; 13; 14; 13; 13; 13; 12; 12; 12; 12; 13; 18; 23; 30; 38; 47; 51; 44; 39; 31; 24; 18; 16; 15; 15; 15; 15; 15; 15; 16; 16; 16; 17; 16; 16; 17; 17; 16; 17; 17; 17; 17; 18; 18; 18; 18; 19; 19; 20; 20; 20; 20; 21; 22; 22; 24; 25; 26; 27; 28; 29; 30; 31; 32; 33; 32; 33; 33; 33; 32; 30; 28; 26; 24; 23; 23; 22; 20; 19; 19; 18; 17; 17; 18; 17; 18; 18; 17; 18; 17; 18; 18; 17; 17; 17; 17; 16; 17; 17; 17; 18; 18; 17; 17; 18; 18; 18; 19; 18; 18; 17; 18; 18; 17; 17; 17; 17; 17; 18; 17; 17; 18; 17; 17; 17; 17; 17; 17; 17; 18; 17; 17; 18; 18; 18; 20; 20; 21; 21; 22; 23; 24; 23; 23; 21; 21; 20; 18; 18; 17; 16; 14; 13; 13; 13; 13; 13; 13; 13; 13; 13; 12; 12; 12; 16; 19; 28; 36; 47; 51; 46; 40; 32; 24; 20; 18; 16; 16; 16; 16; 15; 16; 16; 16; 17; 17; 17; 18; 17; 17; 18; 18; 18; 18; 19; 18; 18; 19; 20; 20; 20; 20; 20; 21; 21; 22; 22; 23; 25; 26; 27; 29; 29; 30; 31; 32; 33; 33; 33; 34; 35; 35; 35; 0; 0; 0; 0;]

Я бы хотел обнаружить, например

Р-волна в [19 - 37]

Комплекс QRS в [51 - 64]

и т.д ...

Ответы [ 13 ]

52 голосов
/ 04 февраля 2010

Первое, что сделает I , это посмотрим, что уже существует . Действительно, эта конкретная проблема уже была тщательно исследована. Вот краткий обзор некоторых действительно простых методов: ссылка .

Я должен ответить и на другой ответ. Я занимаюсь исследованиями в области обработки сигналов и поиска музыкальной информации. На первый взгляд, эта проблема действительно похожа на обнаружение начала, но контекст проблемы не тот. Этот тип обработки биологического сигнала, то есть обнаружение фаз P, QRS и T, может использовать знание определенных характеристик временной области каждой из этих форм волны. Обнаружение начала в MIR не, действительно. (По крайней мере, ненадежно.)

Одним из подходов, который будет хорошо работать для обнаружения QRS (но не обязательно для обнаружения начала заметок), является динамическое искажение времени. Когда характеристики во временной области остаются неизменными, DTW может работать замечательно хорошо. Вот краткий документ IEEE, в котором для этой проблемы используется DTW: ссылка .

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

РЕДАКТИРОВАТЬ: После просмотра этих статей, вейвлет-подход кажется мне наиболее интуитивно понятным. DTW тоже будет хорошо работать, и существуют модули DTW, но вейвлет-подход мне кажется лучшим. Кто-то еще ответил, используя производные сигнала. В моей первой ссылке рассматриваются методы до 1990 года, которые это делают, но я подозреваю, что они не так надежны, как более современные методы.

РЕДАКТИРОВАТЬ: я постараюсь дать простое решение, когда у меня будет такая возможность, но причина почему Я думаю, что здесь подходят вейвлеты, потому что они полезны для параметризации широкого спектра форм независимо от временное или амплитудное масштабирование . Другими словами, если у вас есть сигнал с одинаковой повторяющейся временной формой, но с различными временными масштабами и амплитудами, вейвлет-анализ все же может распознать эти формы как схожие (грубо говоря). Также обратите внимание, что я в некотором роде объединяю банки фильтров в эту категорию. Похожие вещи.

15 голосов
/ 04 февраля 2010

Частью этой головоломки является " обнаружение начала ", и для решения этой проблемы был написан ряд сложных алгоритмов. Вот больше информации о onsets .

Следующая часть - это Расстояние Хэмминга . Эти алгоритмы позволяют выполнять нечеткие сравнения, входные данные представляют собой 2 массива, а выходные данные представляют собой целочисленное «расстояние» или разницу между двумя наборами данных. Чем меньше число, тем более похожи 2. Это очень близко к тому, что вам нужно, но это не точно. Я сделал несколько изменений в алгоритме расстояния Хэмминга, чтобы вычислить новое расстояние, у него, вероятно, есть имя, но я не знаю, что это такое. По сути, это суммирует абсолютное расстояние между каждым элементом в массиве и возвращает общее количество. Вот код для этого в Python.

import math

def absolute_distance(a1, a2, length):
       total_distance=0
       for x in range(0,length):
               total_distance+=math.fabs(a1[x]-a2[x])
       return total_distance

print(absolute_distance([1,3,9,10],[1,3,8,11],4))

Этот скрипт выводит 2, которое является расстоянием между этими двумя массивами.

Теперь, чтобы собрать эти кусочки. Вы можете использовать Обнаружение начала, чтобы найти начало всех волн в наборе данных. Затем вы можете зациклить эти места, сравнивая каждую волну с образцом P-Wave. Если вы нажмете на QRS Complex, расстояние будет самым большим. Если вы нажмете еще одну P-волну, число не будет равно нулю, но будет намного меньше. Расстояние между любой Р-волной и любой Т-волной будет довольно небольшим, ОДНАКО это не проблема, если вы сделаете следующее предположение:

The distance between any p-wave and any other p-wave will be smaller than the distance between any p-wave and any t-wave.

Ряд выглядит примерно так: pQtpQtpQt ... Р-волна и Т-волна находятся рядом друг с другом, но поскольку эта последовательность предсказуема, ее будет легче читать.

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

Возможно, можно пожертвовать начальными вычислениями в пользу итерации по 1 точке за раз и, таким образом, выполнять вычисления расстояния O (n), где n - количество точек на графике. Если бы у вас был список всех этих вычислений расстояний и вы знали, где 50 последовательностей pQt, то вы знали бы 50 самых коротких расстояний, которые не перекрывают , где все местоположения p-волн. Бинго! Как это для простоты? Однако компромисс - это потеря эффективности из-за увеличения числа расчетов расстояния.

8 голосов
/ 04 февраля 2010

Можно использовать кросс-корреляция . Возьмите образец модели каждого паттерна и сопоставьте их с сигналом. Вы получите пики там, где корреляция высока. Я ожидал бы хороших результатов с этой техникой, извлекающей qrs и t-волны. После этого вы можете извлекать p-волны, отыскивая пики в корреляционном сигнале до qrs.

Кросс-корреляция - довольно простой в реализации алгоритм. В основном:

x is array with your signal of length Lx
y is an array containing a sample of the signal you want to recognize of length Ly
r is the resulting correlation

for (i=0; i<Lx - Ly; i++){
  r[i] = 0;
  for (j=0; j<Ly ; j++){
    r[i] += x[i+j]*y[j];
  }
}

И ищите пики в r (например, значения, превышающие порог)

7 голосов
/ 04 февраля 2010

Первое, что я хотел бы сделать, это упростить данные.

Вместо анализа абсолютных данных проанализируйте количество изменений от одной точки данных к следующей.

Вот быстрый однострочник, который будет принимать ; разделенные данные в качестве входных данных и выводить дельту этих данных.

perl -0x3b -ple'( $last, $_ ) = ( $_, $_-$last )' < test.in > test.out

Запустив его на предоставленных вами данных, это вывод:

0; 0; 20; 0; 0; -1; -1; -1; 0; 0; 0; 0; -1; 0; 0; 0; 0; 0; 0; 1; 0; 1 ; 1; 1; 1; 1; 1; 0; 0; 2; 0; -2; -1; -2; -1; -2; -1; 0; -2; -1; 1; -1; 0; -1; 0; 0; 0; 0; -1; 0; -1; 2; 4; 6; 9; 7; 7; 6; -4; -6; -8; -7; -5; -4; 0; -1; 0; - 1; 1; 1; 0; 1; 0; -1; 1; 0; 0; 0; 0; 0; 0; -1; 0; 1; 1; 1; 0; 1; 0; 0; 0 ; 1; 0; -1; 1; 2; 2; 0; 1; 1; 1; 1; 1; 1; 1; 0; 0; 1; 0; 0; -1; -2; -1; -2; -2; -2; -2 ; 0; -1; -1; 0; -1; 0; -1; 0; -1; 0; 1; -1; 0; 0; 0; 0; 0; 0; 0; 0; -1; 1; 1; 0; 0; 0; 0; 0; 0; 0; 0; -1; 1; -1; 0; 0; 1; 0; 0; 0; 0; 0; 0; 0; -1; 1; 0; 0; 0; 0 ; -1; 0; 0; 0; 0; 1; 0; 1; 1; 0; 1; 0; 0; 1; 1; 1; 0; 0; 0; -1; -1; -2; - 1; 0; -2; 0; -1; 0; -1; 0; 1; -1; 0; 0; -1; 0; 0; 0; 1; 5; 5; 7; 8; 9; 4; -7; -5; -8 ; -7; -6; -2; -1; 0; 0; 0; 0; 0; 1; 0; 0; 1; -1; 0; 1; 0; -1; 1; 0; 0; 0 ; 1; 0; 0; 0; 1; 0; 1; 0; 0; 0; 1; 1; 0; 2; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 1; 0; 0; -1; -2; -2; -2; -2; -1; 0; -1; -2; -1; 0; -1; -1; 0; 1; -1; 1; 0; -1; 1; -1; 1; 0; -1; 0; 0; 0; -1; 1; 0; 0; 1; 0; -1; 0; 1; 0; 0; 1; -1; 0; -1; 1; 0; -1; 0; 0 ; 0; 0; 1; -1; 0; 1; -1; 0; 0; 0; 0; 0; 0; 1; -1; 0; 1; 0; 0; 2; 0; 1; 0; 1; 1; 1; -1; 0; -2; 0; -1; -2; 0; -1; -1; -2; -1; 0; 0; 0; 0; 0; 0; 0; 0; -1; 0; 0; 4; 3; 9; 8; 11; 4; -5; -6; -8; -8; -4; -2; -2; 0; 0; 0; -1; 1; 0; 0; 1; 0; 0; 1; -1; 0; 1; 0; 0; 0; 1; -1; 0; 1; 1; 0; 0; 0; 0; 1; 0; 1; 0; 1; 2; 1; 1; 2; 0; 1 ; 1; 1; 1; 0; 0; 1; 1; 0; 0; -35; 0; 0; 0; * +1012 *

В приведенный выше текст вставлены новые строки, которых изначально не было в выводе.


После того, как вы это сделаете, найти комплекс qrs тривиально.

perl -F';' -ane'@F = map { abs($_) > 2 and $_ } @F; print join ";", @F'< test.out

;; 20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;; 4; 6; 9; 7; 7; 6; -4; -6; -8; -7; -5; -4;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;; 5; 5; 7; 8; 9; 4; -7; -5; -8; -7; -6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; 4; 3; 9; 8; 11; 4; -5; -6; -8; -8; -4;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - 35 ;;;

Точки данных 20 и -35 являются результатом исходных данных, начинающихся и заканчивающихся 0.

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


Если вы посмотрите на первую волну p, вы можете ясно увидеть паттерн.

0;0;0;0;0;0;1;0;1;1;1;1;1;1;0;0;2;0;-2;-1;-2;-1;-2;-1;0;-2;-1;1;-1;0;-1;0;0;0;0;
#           \________ up _______/   \________ down _________/

Хотя не так просто увидеть паттерн на второй волне. Это потому, что второй распространяется дальше

0;0;0;1;0;1;1;0;1;0;0;1;1;1;0;0;0;-1;-1;-2;-1;0;-2;0;-1;0;-1;0;1;-1;0;0;-1;0;0;0;
#     \________ up _______/       \________________ down ________________/

Третья р-волна немного более хаотична, чем две другие.

0;0;0;0;0;1;-1;0;1;0;0;2;0;1;0;1;1;1;-1;0;-2;0;-1;-2;0;-1;-1;-2;-1;0;0;0;0;0;
#                \_______ up ______/  \__________ down __________/

Вы найдете t-волны аналогично p-волнам. Основное различие заключается в том, когда они происходят.


Этого должно быть достаточно для начала работы.

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

4 голосов
/ 04 февраля 2010

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

  1. Разбейте ваш сигнал на перекрывающиеся окна длиной L. Каждое окно имеет или не содержит полный комплекс QRS.
  2. Фурье-преобразование каждого окна. Ваши особенности - это уровень сигнала на каждой частоте.
  3. Обрабатывать дерево решений, машину опорных векторов и т. Д. Для некоторых данных, помеченных вручную.
4 голосов
/ 04 февраля 2010

Являются ли эти два других острых пика и долины также комплексами qrs?

Вверху моей головы, я думаю, что вам нужно сделать, это вычислить наклон этого графика в каждой точке.Затем вам также нужно посмотреть, как быстро меняется наклон (2-я производная ???).Если у вас есть резкое изменение, то вы знаете, что достигли какого-то острого пика.Конечно, вы хотите ограничить обнаружение изменения, поэтому вы можете захотеть сделать что-то вроде «если наклон изменяется на X за промежуток времени T», чтобы вы не уловили крошечные выпуклости на графике.

Прошло много времени с тех пор, как я разбирался в математике ... и это похоже на математический вопрос;) О, и я тоже не проводил никакого анализа сигналов:).

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

3 голосов
/ 21 июня 2010

Это замечательный вопрос! У меня есть несколько мыслей:

Динамическая деформация времени может быть интересным инструментом здесь. Вы должны установить «шаблоны» для ваших трех классов, а затем, используя DTW, увидеть корреляцию между вашим шаблоном и «кусками» сигнала (разбить сигнал на, скажем, 0,5 секунды, т. Е. 0 -5. 1-.6 .2-.7 ...). Я работал с чем-то похожим для анализа походки с данными акселерометра, он работал довольно хорошо.

Другой вариант - комбинированный алгоритм обработки сигналов / машинного обучения. Разбейте свой сигнал на «куски» снова. Снова создайте «шаблоны» (вам понадобится дюжина или около того для каждого класса), возьмите FFT каждого куска / шаблона и затем используйте Наивный байесовский классификатор (или другой классификатор ML). , но NB должен сократить его), чтобы классифицировать для каждого из ваших трех классов. Я также попробовал это на данных походки, и смог повысить точность до 98% и вспомнить с относительно сложными сигналами. Дайте мне знать, как это работает, это очень волнующая проблема.

3 голосов
/ 04 февраля 2010

Одним из подходов, который, скорее всего, даст хорошие результаты, является подгонка кривой:

  • Разделите непрерывную волну на интервалы (вероятно, лучше иметь границы интервалов примерно на полпути между острыми пиками qrs).комплексы).Рассматривайте только один интервал за раз.
  • Определите модельную функцию, которая может использоваться для аппроксимации всех возможных вариаций электрокардиографических кривых.Это не так сложно, как кажется сначала.Модельная функция может быть построена как сумма трех функций с параметрами для начала (t_), амплитуды (a_) и ширины (w_) каждой волны.

       f_model(t) = a_p   *  f_p  ((t-t_p  )/w_p) + 
                    a_qrs *  f_qrs((t-t_qrs)/w_qrs) +
                    a_t   *  f_t  ((t-t_t  )/w_t)
    

    Функции f_p(t), f_qrs(t), f_t(t) представляют собой простую функцию, которую можно использовать для моделирования каждой из трех волн.

  • Используйте алгоритм подбора (например, Левенберг-Марквардт)-Алгоритм http://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm) для определения параметров подгонки a_p, t_p, w_p, a_qrs, t_qrs, w_qrs, a_t, t_t, w_t для набора данных каждого интервала.

    Параметры t_p, t_qrs и t_pВы заинтересованы в этом

1 голос
/ 16 сентября 2016

с использованием BioSPPY

в настоящее время невозможно осуществить анализ зубца Т, поскольку в настоящее время он содержит только анализ зубца Р. например, Tstart Tpeak Tend

автоматически не выполняется

нужно было бы использовать собственный анализ.

Мое предложение было бы попытаться реализовать описанный ниже метод

http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3201026/

который я недавно обнаружил и нашел очень интересным

Другой метод анализа t-волн, на который стоит обратить внимание, это команда ECGlib

http://ieeexplore.ieee.org/document/6713536/

надеюсь, это поможет

1 голос
/ 07 февраля 2010

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

Здесь - отличная статья, в которой рассматриваются несколько методов обнаружения пиков - это было бы хорошим началом.

-Paul

...