gusucode.com > 能检测心电特征点PQRST,用matlab编写了界面,并能计算识别率 > ecg/PQRST_detect.m
function [R Q S P T X1 Y4 Y1 se Qstart Send]=PQRST_detect(X,sfreq) %差分阈值法特征点检测 %确定QRS波群 for n=2:3599 Y1(n)=X(n+1)-X(n-1); %一阶导数 end for n=3:3598 Y2(n)=X(n+2)-2*X(n)+X(n-2); %二阶导数 end max1=max(Y1); max2=max(Y2); for n=3:3598 Y3(n)=max1*Y1(n)+max2*Y2(n); end a=0.25; max3=max(Y3); for i=3:3598 if (abs(Y3(i))>max3*a) Y4(i)=1; else Y4(i)=0; end end %对Y4的处理1,去毛刺 for i=4:3597 if (Y4(i)==1&&Y4(i-1)==0&&Y4(i+1)==0) Y4(i)=0; end end %对Y4的处理2,使QRS波群范围内一阶导数全为1,无“零点”,最终确定QRS波群 L=280; %窗口大小,根据两个R峰之间的点数来确定 for i=3:3542 if (Y4(i)==0&&Y4(i-1)==1) for j=1:L/5 if Y4(i+j)==1 Y4(i)=1; break; end end end end for i=3598:-1:3542 if Y4(i)==1 for j=3543:i Y4(j)=1; end break; end end %确定R峰 B=[]; for i=4:3597 %找出QRS波群的起始点 if (Y4(i)==1&&Y4(i-1)==0) B=[B,i]; elseif (Y4(i)==1&&Y4(i+1)==0) B=[B,i]; end end s=size(B); R=[]; for j=1:2:s(2) a=B(j); b=B(j+1); [maxR,r0]=max(X(1,a:b)); %找出QRS波群内幅值最大的一点,即为R峰 r=a+r0-1; %得出的最大值的位置是以a开头向后数(R0-1)位 R=[R,r]; end %求峰域值 dsum=[]; for n=2:3599 d=Y1(n).^2; dsum=[dsum,d]; end dert=sum(dsum)/3598; %方差 se=26*dert; %R峰起点 Rnum=size(R); Rstart=[]; for i=1:Rnum(2) s1=0; for j=(R(i)-1):-1:1 if abs(Y1(j))>se s1=j; %R峰左边斜率首先超过se线的点为起点s1 break; end end for m=s1:-1:1 if (abs(Y1(m))<se) %第一个斜率穿过se线的即为R峰起点 Rstart=[Rstart,m]; break; end end end %Q峰位置 Q=[]; for i=1:Rnum(2) for j=Rstart(i):-1:1 if (Rstart(i)-j)<0.04*sfreq %由R峰起点向前0.04s内(因为Q波的宽度小于0.04s) if (abs(X(j))>=abs(X(j-1))&&abs(X(j))>=abs(X(j+1))) %第一个绝对值极大值即为Q峰 Q=[Q,j]; break; end end end end %R峰终点 Rend=[]; for i=1:Rnum(2) s2=0; c1=0; c2=0; for j=(R(i)+1):3598 if abs(Y1(j))>se %R峰右边斜率首先超过se线的点为起点s2 s2=j; break; end end for k=(s2+1):3598 if (abs(Y1(k))>se&&abs(Y1(k+1))<se) %第一个自下而上穿越-se线的即为R峰终点 c2=k; break; end end Rend=[Rend,c2]; end %S峰位置 S=[]; len=round(0.15*sfreq); %由R峰起点向后0.15s内 for i=1:Rnum(2) a=Rend(i); [MIN s0]=min(X(1,(a:a+len))); s=a+s0-1; S=[S,s]; end %确定S峰终点 Send=[]; for i=1:Rnum(2) for j=S(i):3600 if (abs(Y1(j))>=abs(Y1(j+1))&&abs(Y1(j))>=abs(Y1(j-1))) %S峰之后第一个斜率的绝对值极大值点即为S峰终点 Send=[Send,j]; break; end end end %确定Q峰起点 Qstart=[]; for i=1:Rnum(2) for j=Q(i):-1:1 if (abs(Y1(j))>=abs(Y1(j+1))&&abs(Y1(j))>=abs(Y1(j-1))) %Q峰之前第一个斜率的绝对值极大值点即为Q峰起点 Qstart=[Qstart,j]; break; end end end %心电去噪 for i=5:3596 X1(i)=(X(i-4)+2*X(i-3)+3*X(i-2)+4*X(i-1)+5*X(i)+4*X(i+1)+3*X(i+2)+2*X(i+3)+X(i+4))/25; end X1(1)=X(1); X1(2)=X(2); X1(3)=X(3); X1(4)=X(4); X1(3597)=X(3597); X1(3598)=X(3598); X1(3599)=X(3599); X1(3600)=X(3600); %确定窗的宽度 wsum=0; for i=2:Rnum(2) wsum=wsum+R(i)-R(i-1); end RRavi=wsum/(Rnum(2)-1); RRav=RRavi/sfreq; if RRav>0.7 bw=0.03*sfreq; ew=0.4*sfreq; else bw=0.02*sfreq; ew=0.4*RRav*sfreq; end %确定T峰 wstart=round(Send+bw); %S峰之后的窗 wend=round(Send+ew); T=[]; for i=1:Rnum(2) [tmax,t0]=max(X1(1,wstart(i):wend(i))); %窗内心电信号的最大值即为T峰 t=wstart(i)+t0-1; T=[T,t]; end %确定P峰 w1start=round(Qstart-ew); %Q峰之前的窗 w1end=round(Qstart-bw); if w1start(1)<0 w1start(1)=1; end P=[]; for i=1:Rnum(2) [pmax,p0]=max(X1(1,w1start(i):w1end(i))); %窗内心电信号的最大值即为P峰 p=w1start(i)+p0-1; P=[P,p]; end end