웨이브 패턴 감지
저는 심전도에서 이미지를 읽고 그 안의 주요 파동 (P 파, QRS 복합체 및 T 파)을 감지하려고합니다. 이제 이미지를 읽고 심전도 값을 나타내는 (4.2; 4.4; 4.9; 4.7; ...)과 같은 벡터를 얻을 수 있습니다. 저는이 벡터를 통과 할 수있는 알고리즘이 필요하며이 각 파동의 시작과 끝을 감지합니다.
다음은 그래프 중 하나의 예입니다.
그들이 항상 같은 크기를 가지고 있다면 쉬울 것입니다. 그러나 그것이 효과가있는 것 같지 않거나 심전도가 얼마나 많은 파동을 가질 지 알았다면 그것은 다를 수 있습니다. 누구에게 아이디어가 있습니까?
감사!
업데이트 중
내가 달성하려는 것의 예 :
파도를 감안할 때
벡터를 추출 할 수 있습니다
[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;] 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;] 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; 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; 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;] 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;] 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;] 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;] 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;]
예를 들어 감지하고 싶습니다.
P 파 [19-37]
[51-64]의 QRS 콤플렉스
기타...
내가 할 첫 번째 일은 이미 거기에 무엇이 있는지 보는 것입니다 . 실제로이 특정 문제는 이미 많이 연구되었습니다. 다음은 몇 가지 매우 간단한 방법에 대한 간략한 개요입니다. link .
나는 또 다른 대답에도 응답해야한다. 신호 처리 및 음악 정보 검색에 대한 연구를합니다. 표면적으로이 문제는 발병 감지와 유사하게 보이지만 문제 컨텍스트는 동일하지 않습니다. 이러한 유형의 생물학적 신호 처리, 즉 P, QRS 및 T 위상 검출 은 이러한 각 파형 의 특정 시간 영역 특성 에 대한 지식을 활용할 수 있습니다 . MIR의 발병 감지는 실제로 그렇지 않습니다. (적어도 신뢰할 수는 없습니다.)
QRS 감지에 잘 작동하는 한 가지 접근 방식 (노트 시작 감지에 반드시 필요한 것은 아님)은 동적 시간 왜곡입니다. 시간 영역 특성이 변하지 않으면 DTW가 매우 잘 작동 할 수 있습니다. 다음은이 문제에 DTW를 사용하는 짧은 IEEE 문서입니다. link .
이것은 많은 방법을 비교하는 멋진 IEEE 잡지 기사입니다 : link . 많은 일반적인 신호 처리 모델이 시도되었음을 알 수 있습니다. 종이를 훑어보고 이해하는 것을 기본 수준에서 시도하십시오.
편집 :이 기사를 살펴본 후 웨이블릿 기반 접근 방식이 가장 직관적 인 것 같습니다. DTW도 잘 작동하고 거기에 DTW 모듈이 있지만 웨이블릿 접근 방식이 가장 좋습니다. 다른 누군가는 신호의 파생물을 이용하여 응답했습니다. 내 첫 번째 링크는 1990 년 이전의 방법을 조사하지만, 더 현대적인 방법만큼 강력하지 않다고 생각합니다.
편집 : 내가 기회를 얻을 때 간단한 솔루션을 제공하려고합니다, 그러나 이유 왜 그들이 관계없이 모양의 다양한 매개 변수화에 유용하기 때문에 내가 웨이블릿 여기에 적합 생각은 시간 또는 진폭 스케일링 . 즉, 반복되는 시간적 모양이 같지만 시간 척도와 진폭이 다른 신호가있는 경우 웨이블릿 분석은 이러한 모양이 유사한 것으로 인식 할 수 있습니다 (대략적으로 말하면). 또한 제가이 카테고리에 필터 뱅크를 집중시키는 것입니다. 비슷한 것들.
이 퍼즐의 한 조각은 " 발병 감지 " 이며이 문제를 해결하기 위해 여러 복잡한 알고리즘이 작성되었습니다. 여기에 발병에 대한 자세한 정보가 있습니다 .
다음 조각은 Hamming Distance 입니다. 이 알고리즘을 사용하면 퍼지 비교를 수행 할 수 있습니다. 입력은 2 개의 배열이고 출력은 정수 "거리"또는 두 데이터 세트 간의 차이입니다. 숫자가 작을수록 2가 더 비슷합니다. 이것은 당신이 필요로하는 것에 매우 가깝지만 정확하지는 않습니다. 나는 새로운 거리를 계산하기 위해 Hamming Distance 알고리즘을 약간 수정했습니다. 아마도 이름이 있지만 그것이 무엇인지 모르겠습니다. 기본적으로 배열의 각 요소 사이의 절대 거리를 더하고 합계를 반환합니다. 다음은 파이썬 코드입니다.
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-Wave를 치면 숫자는 0이 아니지만 훨씬 더 작아집니다. P-Wave와 T-Wave 사이의 거리는 매우 작지만 다음과 같은 가정을하면 문제가되지 않습니다.
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 ... p-wave와 t-wave는 서로 바로 옆에 있지만이 시퀀스는 예측 가능하기 때문에 읽기가 더 쉽습니다.
그렇지 않은 편에는이 문제에 대한 미적분 기반 솔루션이있을 것입니다. 그러나 내 마음에 커브 피팅과 적분은이 문제를 더 엉망으로 만듭니다. 내가 작성한 거리 함수 는 두 곡선의 적분을 뺀 매우 유사한 면적 차이 를 찾을 수 있습니다 .
한 번에 1 포인트 씩 반복하여 O (n) 거리 계산을 수행하는 대신 시작 계산을 희생 할 수 있습니다. 여기서 n은 그래프의 포인트 수입니다. 이러한 모든 거리 계산 목록이 있고 50 개의 pQt 시퀀스가 어디에 있는지 알고 있다면 p- 파의 모든 위치에서 겹치지 않는 50 개의 최단 거리를 알 수 있습니다. 빙고! 단순함을 위해 어떻습니까? 그러나 트레이드 오프는 거리 계산의 증가로 인한 효율성 손실입니다.
상호 상관을 사용할 수 있습니다 . 각 패턴의 모델 샘플을 가져와 신호와 연관시킵니다. 상관 관계가 높은 곳에서 피크를 얻을 수 있습니다. 나는 qrs와 t 파를 추출하는이 기술로 좋은 결과를 기대할 것이다. 그 후에 qrs 이전의 상관 신호에서 피크를 찾아 p 파를 추출 할 수 있습니다.
상호 상관은 알고리즘을 구현하기가 매우 쉽습니다. 원래:
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에서 피크를 찾습니다 (예 : 임계 값을 초과하는 값).
가장 먼저 할 일은 데이터를 단순화하는 것입니다.
절대 데이터를 분석하는 대신 한 데이터 포인트에서 다음 데이터 포인트로의 변화량을 분석하십시오.
다음은 ;
분리 된 데이터를 입력으로 받아 해당 데이터의 델타를 출력 하는 빠른 라이너입니다 .
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;
출력에 원래 존재하지 않는 위의 텍스트에 삽입 된 개행이 있습니다.
그 후에 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
.
To find the other data points you will have to rely on pattern matching.
If you look at the first p wave, you can clearly see a pattern.
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 _________/
It isn't as easy to see the pattern on the second p wave though. This is because the second one is spread out further
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 ________________/
The third p wave is a little more erratic than the other two.
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 __________/
You would find the t waves in a similar manner to the p waves. The main difference is when they occur.
This should be enough information to get you started.
The two one-liners are for example only, not recommended for daily use.
Are those other two sharp peaks and valleys also qrs complexes?
Off the top of my head, I think what you need to do is calculate the slope of this graph at each point. Then you also need to see how quickly the slope changes (2nd derivative???). If you have an abrupt change then you know you've hit some kind of sharp peak. Of course, you want to limit the detection of the change, so you might want to do something like "if the slope changes by X over time interval T", so that you don't pick up the tiny bumps in the graph.
It's been a while since I did any math... and this seems like a math question ;) Oh, and I haven't done any sort of signal analysis either :).
Just adding another point. You can also try signal-averaging I think. For example, averaging the last 3 or 4 data points. I think you can detect abrupt changes that way too.
I'm no expert in this specific problem, but just off the top of my head from more general knowledge: Let's say you know the QRS complex (or one of the other features, but I'll use the QRS complex for this example) takes place in roughly some fixed time period of length L. I wonder if you could treat this as a classification problem as follows:
- Split your signal into overlapping windows of length L. Each window either does or doesn't have the full QRS complex in it.
- Fourier transform each window. Your features are the signal strength at each frequency.
- Train a decision tree, support vector machine, etc. on some hand-annotated data.
One approach that will very likely yield good results is curve fitting:
- Divide the continuous wave into intervals (probably it's best to have the interval borders about half way between the sharp peaks of the qrs complexes). Only consider a single interval at a time.
Define a model function that can be used to approximate all possible variations of electrocardiographic curves. This is not as difficult as it seems first. The model function can be constructed as a sum of three functions with parameters for the origin (t_), amplitude (a_) and width (w_) of each wave.
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)
The functions
f_p(t)
,f_qrs(t)
,f_t(t)
are some simple function that can be uses to model each of the three waves.Use a fitting algorithm (e.g. the Levenberg-Marquardt-Algorithm http://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm) to determine the fitting parameters a_p, t_p, w_p, a_qrs, t_qrs, w_qrs, a_t, t_t, w_t for the dataset of each intervall.
The parameters t_p, t_qrs and t_p are the ones you are interested in.
This is a wonderful question! I have a few thoughts:
Dynamic Time Warping could be an interesting tool here. You would establish "templates" for your three classes, and then using DTW could see the correlation between your template and "chunks" of the signal (break the signal up into, say, .5 second bits, ie. 0-.5 .1-.6 .2-.7...). I've worked with something similar for gait analysis with accelerometer data, it worked reasonably well.
Another option is a combined signal processing/ machine learning algorithm. Break your signal into "chunks" again. Make "templates" again (you'll want a dozen or so for each class) take the FFT of each chunk/template and then use a Naïve Bayes Classifier (or another ML classifier, but NB should cut it) to classify for each of your three classes. I've also tried this on gait data, and was able to get upwards of 98% precision and recall with relatively complicated signals. Let me know how this works, it's a very exciting problem.
"Wavelet transform" may be a relevant keyword. I've once attended a presentation by someone who used this technique to detect different heartbeat phases in a noisy ecg.
As far as my limited understanding goes, it's somewhat like a Fourier transform, but using (scaled) copies of a, in your case heartbeat-shaped, pulse.
Wavelets have been shown to be the best tool for locating peaks in this type of data where the peaks are "different sizes" - the scaling properties of wavelets make it an ideal tool for this type of multi-scale peak detection. This looks like a non-stationary signal so using a DFT would not be the right tool as some have suggested, but if this is an exploratory project you could look at using the spectrum of the signal (estimated using essentially the FFT of the autocorrelation of the signal.)
Here is a great paper reviewing several peak detection methods - this would be a good place to start.
-Paul
using BioSPPY
it is not presently possibly to implement T-wave analysis, as at present it only contains R-wave analysis. eg Tstart Tpeak Tend
are not automatically implimented
one would have to use your own analysis.
my suggestion would be to try and implement the below method
http://www.ncbi.nlm.nih.gov/pmc/articles/PMC3201026/
which is one that I have recently discovered and found to be very interesting
The other t-wave analysis method worth looking at is that by ECGlib team
http://ieeexplore.ieee.org/document/6713536/
hope this helps
I haven't read each other answer thoroughly but I have scanned them and I noticed that no one recommended looking at the Fourier Transform to segment these waves.
To me it seems like a clear cut application of Harmonic analysis in mathematics. There may be several subtle points that I may be missing.
The Discrete Fourier Transform coefficients give you the amplitude and phase of the different sinusoidal components that make up your discrete time signal, which is essentially what your problem states you want to find.
I may be missing something here though ...
First, the various components of the standard electrocardiogram wave can be missing from any given plot. Such a plot is generally abnormal and usually indicates some sort of problem, but you can't be promised that they're there.
Secondly, recognizing them is as much art as science, especially in the cases where something is going wrong.
My approach might be to try to train a neural network to identify the components. You would give it the previous 30 seconds of data, normalized so the lowest point was at 0 and the highest point at 1.0 and it would have 11 outputs. The outputs that weren't abnormality ratings would be a weighting for the last 10 seconds. A 0.0 would be -10 seconds from present, and a 1.0 would mean now. The outputs would be:
- Where the most recent P wave started
- Where the most recent P wave ended
- Abnormality rating of most recent P wave with one extreme being 'absent'.
- Where the most recent QRS complex started
- Where the Q portion of the most recent QRS complex turned into the R portion.
- Where the R portion of the most recent QRS complex turned into the S portion.
- Where the most recent QRS complex ended.
- 하나의 극단이 '부재'인 최신 QRS 복합체의 이상 등급.
- 가장 최근의 T 파가 시작된 곳.
- 가장 최근의 T 파가 끝난 곳.
- 가장 최근의 T 파의 이상 등급 중 하나는 '부재'입니다.
사람들이 제안한 다른 종류의 분석으로 이것을 다시 확인하거나 신경망의 출력과 함께 다른 종류의 분석을 사용하여 답을 줄 수 있습니다.
물론 신경망에 대한이 상세한 설명은 규범적인 것으로 받아 들여서는 안됩니다. 예를 들어, 가장 최적의 결과물을 반드시 선택하지는 않았다고 확신합니다. 그저 그것들이 무엇인지에 대해 약간의 아이디어를 던졌습니다.
참고 URL : https://stackoverflow.com/questions/2196124/detecting-patterns-in-waves
'IT박스' 카테고리의 다른 글
.NET Core RC2에서 .exe 파일 빌드 (0) | 2020.10.22 |
---|---|
BigInteger에 대한 상한이 있습니까? (0) | 2020.10.22 |
"실험용"Kotlin 코 루틴을 프로덕션에 사용할 수 있습니까? (0) | 2020.10.22 |
iPhone으로 서버에 사진을 업로드하려면 어떻게해야합니까? (0) | 2020.10.22 |
삽입 / 제거를 위해 NSMutableArray 관찰 (0) | 2020.10.22 |