这学期选了神经网络的课程,最后作业是处理ECG信号,并利用神经网络进行识别。

1  ECG介绍与读取ECG信号

1)ECG介绍

   具体ECG背景应用就不介绍了,大家可以参考百度 谷歌。只是简单说下ECG的结构:

   一个完整周期的ECG信号有 QRS P T 波组成,不同的人对应不用的波形,同一个人在不同的阶段波形也不同。我们需要根据各个波形的特点,提取出相应的特征,对不同的人进行身份识别。

2)ECG信号读取

首先需要到MIT-BIH数据库中下载ECG信号,具体的下载地址与程序读取内容介绍可以参考一下地址(讲述的很详细):http://blog.csdn.net/chenyusiyuan/article/details/2027887。
   读取代码(基于MATLAB)如下:
  
clc; clear all;
%------ SPECIFY DATA ------------------------------------------------------
%%选择文件名
stringname='111';
%选择你要处理的信号点数
points=10000;
PATH= 'F:\ECG\MIT-BIH database directory'; % path, where data are saved
HEADERFILE= strcat(stringname,'.hea');      % header-file in text format
ATRFILE= strcat(stringname,'.atr');        % attributes-file in binary format
DATAFILE=strcat(stringname,'.dat');        % data-file
SAMPLES2READ=points;         % number of samples to be read% in case of more than one signal:% 2*SAMPLES2READ samples are read%------ LOAD HEADER DATA --------------------------------------------------
fprintf(1,'\\n$> WORKING ON %s ...\n', HEADERFILE);
signalh= fullfile(PATH, HEADERFILE);
fid1=fopen(signalh,'r');
z= fgetl(fid1);
A= sscanf(z, '%*s %d %d %d',[1,3]);
nosig= A(1);  % number of signals
sfreq=A(2);   % sample rate of data
clear A;
for k=1:nosigz= fgetl(fid1);A= sscanf(z, '%*s %d %d %d %d %d',[1,5]);dformat(k)= A(1);           % format; here only 212 is allowedgain(k)= A(2);              % number of integers per mVbitres(k)= A(3);            % bitresolutionzerovalue(k)= A(4);         % integer value of ECG zero pointfirstvalue(k)= A(5);        % first integer value of signal (to test for errors)
end;
fclose(fid1);
clear A;%------ LOAD BINARY DATA --------------------------------------------------
if dformat~= [212,212], error('this script does not apply binary formats different to 212.'); end;
signald= fullfile(PATH, DATAFILE);            % data in format 212
fid2=fopen(signald,'r');
A= fread(fid2, [3, SAMPLES2READ], 'uint8')';  % matrix with 3 rows, each 8 bits long, = 2*12bit
fclose(fid2);
M2H= bitshift(A(:,2), -4);
M1H= bitand(A(:,2), 15);
PRL=bitshift(bitand(A(:,2),8),9);     % sign-bit
PRR=bitshift(bitand(A(:,2),128),5);   % sign-bit
M( : , 1)= bitshift(M1H,8)+ A(:,1)-PRL;
M( : , 2)= bitshift(M2H,8)+ A(:,3)-PRR;
if M(1,:) ~= firstvalue, error('inconsistency in the first bit values'); end;
switch nosig
case 2M( : , 1)= (M( : , 1)- zerovalue(1))/gain(1);M( : , 2)= (M( : , 2)- zerovalue(2))/gain(2);TIME=(0:(SAMPLES2READ-1))/sfreq;
case 1M( : , 1)= (M( : , 1)- zerovalue(1));M( : , 2)= (M( : , 2)- zerovalue(1));M=M';M(1)=[];sM=size(M);sM=sM(2)+1;M(sM)=0;M=M';M=M/gain(1);TIME=(0:2*(SAMPLES2READ)-1)/sfreq;
otherwise  % this case did not appear up to now!% here M has to be sorted!!!disp('Sorting algorithm for more than 2 signals not programmed yet!');
end;
clear A M1H M2H PRR PRL;
fprintf(1,'\\n$> LOADING DATA FINISHED \n');%------ LOAD ATTRIBUTES DATA ----------------------------------------------
atrd= fullfile(PATH, ATRFILE);      % attribute file with annotation data
fid3=fopen(atrd,'r');
A= fread(fid3, [2, inf], 'uint8')';
fclose(fid3);
ATRTIME=[];
ANNOT=[];
sa=size(A);
saa=sa(1);
i=1;
while i<=saaannoth=bitshift(A(i,2),-2);if annoth==59ANNOT=[ANNOT;bitshift(A(i+3,2),-2)];ATRTIME=[ATRTIME;A(i+2,1)+bitshift(A(i+2,2),8)+...bitshift(A(i+1,1),16)+bitshift(A(i+1,2),24)];i=i+3;elseif annoth==60% nothing to do!elseif annoth==61% nothing to do!elseif annoth==62% nothing to do!elseif annoth==63hilfe=bitshift(bitand(A(i,2),3),8)+A(i,1);hilfe=hilfe+mod(hilfe,2);i=i+hilfe/2;elseATRTIME=[ATRTIME;bitshift(bitand(A(i,2),3),8)+A(i,1)];ANNOT=[ANNOT;bitshift(A(i,2),-2)];end;i=i+1;
end;
ANNOT(length(ANNOT))=[];       % last line = EOF (=0)
ATRTIME(length(ATRTIME))=[];   % last line = EOF
clear A;
ATRTIME= (cumsum(ATRTIME))/sfreq;
ind= find(ATRTIME <= TIME(end));
ATRTIMED= ATRTIME(ind);
ANNOT=round(ANNOT);
ANNOTD= ANNOT(ind);%------ DISPLAY DATA ------------------------------------------------------
figure(1); clf, box on, hold on ;grid on ;
plot(TIME, M(:,1),'r');
if nosig==2plot(TIME, M(:,2),'b');
end;
for k=1:length(ATRTIMED)text(ATRTIMED(k),0,num2str(ANNOTD(k)));
end;
xlim([TIME(1), TIME(end)]);
xlabel('Time / s'); ylabel('Voltage / mV');
string=['ECG signal ',DATAFILE];
title(string);
fprintf(1,'\\n$> DISPLAYING DATA FINISHED \n');
% -------------------------------------------------------------------------
fprintf(1,'\\n$> ALL FINISHED \n');
以MIT-BIH数据库中111.dat 为例。



2 去除高频噪声与基线漂移

   ECG读取完后,原始ECG信号含有高频噪声和基线漂移,利用小波方法可以去除相应噪声。具体原理如下:将一维的ECG信号进行8层的小波分解后(MATLAB下wavedec函数,小波类型是bior2.6)得到相应的细节系数与近似系数。根据小波原理我们可以知道,1,2层的细节系数包含了大部分高频噪声,8层的近似系数包含了基线漂移。基于此,我们将1,2层的细节系数(即高频系数置0),8成的近似系数(低频系数)置0;在对应进行小波重构,重构后我们可以明显得到去噪信号,信号无基线漂移。下面通过图片与代码进一步讲解:
   小波去噪代码:(matlab) 
  
%%%%%%%%%%%%%%%%%%%去除噪声和基线漂移%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
level=8; wavename='bior2.6';
ecgdata=ECGsignalM1;
figure(2);
plot(ecgdata(1:points));grid on ;axis tight;axis([1,points,-2,5]);
title('原始ECG信号');
%%%%%%%%%%进行小波变换8层
[C,L]=wavedec(ecgdata,level,wavename);
%%%%%%%提取尺度系数,
A1=appcoef(C,L,wavename,1);
A2=appcoef(C,L,wavename,2);
A3=appcoef(C,L,wavename,3);
A4=appcoef(C,L,wavename,4);
A5=appcoef(C,L,wavename,5);
A6=appcoef(C,L,wavename,6);
A7=appcoef(C,L,wavename,7);
A8=appcoef(C,L,wavename,8);
%%%%%%%提取细节系数
D1=detcoef(C,L,1);
D2=detcoef(C,L,2);
D3=detcoef(C,L,3);
D4=detcoef(C,L,4);
D5=detcoef(C,L,5);
D6=detcoef(C,L,6);
D7=detcoef(C,L,7);
D8=detcoef(C,L,8);
%%%%%%%%%%%%重构
A8=zeros(length(A8),1); %去除基线漂移,8层低频信息
RA7=idwt(A8,D8,wavename);
RA6=idwt(RA7(1:length(D7)),D7,wavename);
RA5=idwt(RA6(1:length(D6)),D6,wavename);
RA4=idwt(RA5(1:length(D5)),D5,wavename);
RA3=idwt(RA4(1:length(D4)),D4,wavename);
RA2=idwt(RA3(1:length(D3)),D3,wavename);
D2=zeros(length(D2),1); %去除高频噪声,2层高频噪声
RA1=idwt(RA2(1:length(D2)),D2,wavename);
D1=zeros(length(D1),1);%去除高频噪声,1层高频噪声
DenoisingSignal=idwt(RA1,D1,wavename);
figure(3);
plot(DenoisingSignal);
title('去除噪声的ECG信号'); grid on; axis tight;axis([1,points,-2,5]);
clear ecgdata;
去噪前后对比图像如下:
去噪前:


去噪后:


3 QRS 检测

   QRS检测是处理ECG信号的基础,无论最后实现什么样的功能,QRS波的检测都是前提。所以准确的检测QRS波是特征提取的前提,我采用基于二进样条4层小波变换,在3层的细节系数中利用极大极小值方法可以很好的检测出R波。3层细节系数的选择是基于R波在3层系数下表现的与其他噪声差别最大;具体实现如下:
二进样条小波滤波器:  低通滤波器:[1/4 3/4 3/4 1/4]
                      高通滤波器:[-1/4 -3/4 3/4 1/4]
在第3层细节系数中首先找到极大极小值对:
1)找极大值方法:找出斜率大于0的值,并赋值为1,其余为0,极大值就在序列类似1, 0这样的点,即前面一个值比后面的大的值对应的位置点。
2)找极小值方法:类似极大值,找出斜率<0的值对应的位置,并赋值为1,其余的为0,极小值就在类似1,0的序列中对应的位置,即前面一个值比后面的大的值对应的位置点。
检测出的极大极小值如下:

3)设置阈值,提取出R波。我们可以看出,R波的值要明显大于其他位置的值,其在3层细节系数的特点也类似于此。这样我们就可以设置一个可靠的阈值(将所有点分为4部分,求出每部分最大值的平均值T,阈值为T/3)来提取一组相邻的最大最小值对。这样最大最小值间的过0点就是对应于原始信号的R波点。
R波对应的极大极小值对如下:


4)补偿R波点。由于在二进样条小波变换的过程中,3层细节系数与原始信号的对应的位置有10个点的漂移,在程序中需要补偿。(这个在程序中会给出)。
5)找Q S 波。基于R波的位置,在R波位置(在1层细节系数下)的前3个极点为Q波,在R波位置(1细节系数下)的后3个极点为S波。这样我们就将QRS波定位出来。
6)由于不同的情况,可能造成R波的漏检和错检(把T波检测为R波),我们根据相邻R波的距离进行检测漏检与错检。当相邻R波的距离<0.4 mean(RR)平均距离时,这是错检,这样去除值小的R波。当相邻R波的距离>1.6mean(RR)时,在两个RR波间找到一个最大的极值对,定位R波,这是防止漏检。

经过上述方法,一个鲁棒性很好的QRS检测方法就出来了,经过测试,QRS检测能达到98%。检测结果R波用红线标注,Q S 波用黑线标注。

4 T P 波检测

P T 波的检测与R波检测有很大的相同性。只不过 P T 波在4层细节系数中可以表述出更好的特性。同样根据根据极大极小值原理,可以分别检测出T P波,以及他们的起始点与终止点,即TB,TE,PB PE。具体程序我会在稍后的程序中给出。
各波段检测结果如下:

具体QRS T P波检查代码如下:

4特征提取

将各波段的位置提取出来后,我们根据15个距离特征与6个幅值特征作为身份识别的特征。具体信息简下表:
距离特征:
R-Q R-S R-P
P-PB R-PE R-T
R-TB R-TE PB-PE
TB-TE Q-P S-T
P-T Q-PB S-TE

幅值特征:

Q-R S-R
PB-P P-Q
T-TB T-S
我们将MIT-BIH中的101.dat、103.dat、105.dat、106.dat、111.dat分别取出10个这样的特征,其中5个作为训练样本、5个作为测试样本,送入神经网络进行训练。
特征提取代码:
%%%%%%%%%%%%%%%%%%%%%%%%%提取特征向量,进行神经网络训练%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%特征向量根据你需要检测部位的不同,选取特征向量。
%%%%%%%%%%%%%%%本例进行身份识别,选取5组信号,即5个同的人,每组数据采取10例ECG信号,
%%%%%%%%%%%%%%%提取每例的15个距离特征向量、6个幅值特征向量作为特征数据
%%%%%%%%%%%%%%%距离特征:R-Q R-S R-P R-PBegin R-PEnd R-T R-TBegin R-TEnd
%%%%%%%%%%%%%%% PBegin-PEnd TBegin-TEnd Q-P S-T P-T Q-PBegin S-TEnd
%%%%%%%%%%%%%%%幅值特征: Q-R S-R PBegin-P P-Q T-TBegin T-S
%%%%%%%%%%%%%%每组的10例信号中5个训练5个测试
%%%%%%%%%%%%%%10组信号取第 2 4 6 8 10 12 14 16 18 20个周期, 2 6 10 14 18训练,其余测试%%%%首先找到R Q S P T峰值, 起点 终点 的位置
locatedR=find(countR);
locatedQ=find(countQ);
locatedS=find(countS);
locatedP=find(countP);
locatedPBegin=find(countPbegin);
locatedPEnd=find(countPend);
locatedTBegin=find(countTbegin);
locatedTEnd=find(countTend);
locatedT=find(countT);
%%%%%%初始化各种特征值
RQ=0;RS=0;RP=0;RPB=0;RPE=0;RT=0;RTB=0;RTE=0;
PBPE=0;TBTE=0;QP=0;ST=0;PT=0;QPB=0;STE=0;
ampQR=0;ampSR=0;ampPBP=0;ampPQ=0;ampTTB=0;ampTS=0;
testECG=zeros(5,21);
counttest=1;
trainECG=zeros(5,21);
counttrain=1;
%%%%%%%%%%%%%%%%%开始计算
for i=2:2:20%距离特征RQ=abs(locatedR(i)-locatedQ(i));RS=abs(locatedS(i)-locatedR(i));RP=abs(locatedR(i)-locatedP(i-1));RPB=abs(locatedR(i)-locatedPBegin(i-1));RPE=abs(locatedR(i)-locatedPEnd(i-1));RT=abs(locatedR(i)-locatedT(i));RTB=abs(locatedR(i)-locatedTBegin(i));RTE=abs(locatedR(i)-locatedTEnd(i));PBPE=abs(locatedPBegin(i-1)-locatedPEnd(i-1));TBTE=abs(locatedTBegin(i)-locatedTEnd(i));QP=abs(locatedQ(i)-locatedP(i-1));ST=abs(locatedS(i)-locatedT(i));PT=abs(locatedP(i-1)-locatedT(i));QPB=abs(locatedQ(i)-locatedPBegin(i-1));STE=abs(locatedS(i)-locatedTEnd(i));%幅值特征ampQR=ecgdata(locatedR(i))-ecgdata(locatedQ(i));ampSR=ecgdata(locatedR(i))-ecgdata(locatedS(i));ampPBP=ecgdata(locatedP(i-1))-ecgdata(locatedPBegin(i-1));ampPQ=ecgdata(locatedQ(i))-ecgdata(locatedP(i-1));ampTTB=ecgdata(locatedT(i))-ecgdata(locatedTBegin(i));ampTS=ecgdata(locatedT(i))-ecgdata(locatedS(i));%%%%组成向量,并归一化featureVector=[RQ,RS,RP,RPB,RPE,RT,RTB,RTE,PBPE,TBTE,QP,ST,PT,QPB,STE];maxFeature=max(featureVector);minFeature=min(featureVector);for j=1:length(featureVector)featureVector(j)=2*(featureVector(j)-minFeature)/(maxFeature-minFeature)-1;endamplitudeVector=[ampQR,ampSR,ampPBP,ampPQ,ampTTB,ampTS];maxAmplitude=max(amplitudeVector);minAmplitued=min(amplitudeVector);for j=1:length(amplitudeVector)amplitudeVector(j)=2*(amplitudeVector(j)-minAmplitued)/(maxAmplitude-minAmplitued)-1;endif rem(i,4)==0testECG(counttest,:)=[featureVector,amplitudeVector];counttest=counttest+1;elsetrainECG(counttrain,:)=[featureVector,amplitudeVector];counttrain=counttrain+1;endclear amplitudeVector  featureVector;
end
save testsample111.mat  testECG
save trainsample111.mat trainECG

5 BP神经网络训练与检测

我相信很多人对神经网络比较熟悉了,这里我就不多讲了,在matlab中,主要有三个函数, newff 负责建立网络, train 负责训练网络, sim 负责进行仿真。调整好参数。就可以进行训练与测试啦。
具体代码如下:
clear all;
load testsample101.mat;
test101=testECG;
load testsample103.mat;
test103=testECG;
load testsample105.mat;
test105=testECG;
load testsample106.mat;
test106=testECG;
load testsample111.mat;
test111=testECG;load trainsample101.mat;
train101=trainECG;
load trainsample103.mat;
train103=trainECG;
load trainsample105.mat;
train105=trainECG;
load trainsample106.mat;
train106=trainECG;
load trainsample111.mat;
train111=trainECG;
%训练样本
train_sample=[ train103' train101' train105' train106' train111']; %21*25
%测试样本
test_sample=[test103' test101' test105' test106' test111'];
%输出类别
t=[2 2 2 2 2 1 1 1 1 1 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5];
train_result=ind2vec(t);
test_result=ind2vec(t);
pr(1:21,1)=-1;
pr(1:21,2)=1;
net = newff(pr,[21,5],{'tansig' 'purelin'},'traingdx','learngdm');
net.trainParam.epochs=1000;
net.trainParam.goal=0.0002;
net.trainParam.lr=0.0003;
net = train(net,train_sample,train_result);
result_sim=sim(net,test_sample);
result_sim_ind=vec2ind(result_sim);
correct=0;
for i=1:length(t)if result_sim_ind(i)==t(i);correct=correct+1;end
end
disp('正确率:');correct/length(t)

运行结果:正确率为 0.96 左右,效果还不错。

6:本次ECG实现的所有代码与相关原理信息的下载地址(0积分):http://download.csdn.net/detail/yuansanwan123/7530687
希望大家给予批评。有错误之处务必指正。最后感谢能够坚持看到最后的人们!
勉励自己一句话:勤学如春起之苗,不见其长,日有所赠;
辍学如磨刀之石,不见其损,日有所亏。
奋斗吧--碗。
<pre name="code" class="cpp">level=4;    sr=360;
%读入ECG信号
%load ecgdata.mat;
%load ECGsignalM1.mat;
%load Rsignal.mat
mydata = DenoisingSignal;
ecgdata=mydata';
swa=zeros(4,points);%存储概貌信息
swd=zeros(4,points);%存储细节信息
signal=ecgdata(0*points+1:1*points); %取点信号%算小波系数和尺度系数
%低通滤波器 1/4 3/4 3/4 1/4
%高通滤波器 -1/4 -3/4 3/4 1/4
%二进样条小波for i=1:points-3swa(1,i+3)=1/4*signal(i+3-2^0*0)+3/4*signal(i+3-2^0*1)+3/4*signal(i+3-2^0*2)+1/4*signal(i+3-2^0*3);swd(1,i+3)=-1/4*signal(i+3-2^0*0)-3/4*signal(i+3-2^0*1)+3/4*signal(i+3-2^0*2)+1/4*signal(i+3-2^0*3);
end
j=2;
while j<=levelfor i=1:points-24swa(j,i+24)=1/4*swa(j-1,i+24-2^(j-1)*0)+3/4*swa(j-1,i+24-2^(j-1)*1)+3/4*swa(j-1,i+24-2^(j-1)*2)+1/4*swa(j-1,i+24-2^(j-1)*3);swd(j,i+24)=-1/4*swa(j-1,i+24-2^(j-1)*0)-3/4*swa(j-1,i+24-2^(j-1)*1)+3/4*swa(j-1,i+24-2^(j-1)*2)+1/4*swa(j-1,i+24-2^(j-1)*3);endj=j+1;
end
%画出原信号和尺度系数,小波系数
%figure(10);
%subplot(level+1,1,1);plot(ecgdata(1:points));grid on ;axis tight;
%title('ECG信号在j=1,2,3,4尺度下的尺度系数对比');
%for i=1:level
%    subplot(level+1,1,i+1);
%    plot(swa(i,:));axis tight;grid on; xlabel('time');ylabel(strcat('a  ',num2str(i)));
%end
%figure(11);
%subplot(level,1,1); plot(ecgdata(1:points)); grid on;axis tight;
%title('ECG信号及其在j=1,2,3,4尺度下的尺度系数及小波系数');
%for i=1:level
%    subplot(level+1,2,2*(i)+1);
%    plot(swa(i,:)); axis tight;grid on;xlabel('time');
%    ylabel(strcat('a   ',num2str(i)));
%    subplot(level+1,2,2*(i)+2);
%    plot(swd(i,:)); axis tight;grid on;
%    ylabel(strcat('d   ',num2str(i)));
%end%画出原图及小波系数
%figure(12);
%subplot(level,1,1); plot(real(ecgdata(1:points)),'b'); grid on;axis tight;
%title('ECG信号及其在j=1,2,3,4尺度下的小波系数');
%for i=1:level
%    subplot(level+1,1,i+1);
%    plot(swd(i,:),'b'); axis tight;grid on;
%    ylabel(strcat('d   ',num2str(i)));
%end%**************************************求正负极大值对**********************%
ddw=zeros(size(swd));
pddw=ddw;
nddw=ddw;
%小波系数的大于0的点
posw=swd.*(swd>0);
%斜率大于0
pdw=((posw(:,1:points-1)-posw(:,2:points))<0);
%正极大值点
pddw(:,2:points-1)=((pdw(:,1:points-2)-pdw(:,2:points-1))>0);
%小波系数小于0的点
negw=swd.*(swd<0);
ndw=((negw(:,1:points-1)-negw(:,2:points))>0);
%负极大值点
nddw(:,2:points-1)=((ndw(:,1:points-2)-ndw(:,2:points-1))>0);
%或运算
ddw=pddw|nddw;
ddw(:,1)=1;
ddw(:,points)=1;
%求出极值点的值,其他点置0
wpeak=ddw.*swd;
wpeak(:,1)=wpeak(:,1)+1e-10;
wpeak(:,points)=wpeak(:,points)+1e-10;%画出各尺度下极值点
%figure(13);
%for i=1:level
%    subplot(level,1,i);
%    plot(wpeak(i,:)); axis tight;grid on;
%ylabel(strcat('j=   ',num2str(i)));
%end
%subplot(4,1,1);
%title('ECG信号在j=1,2,3,4尺度下的小波系数的模极大值点');interva2=zeros(1,points);
intervaqs=zeros(1,points);
Mj1=wpeak(1,:);
Mj3=wpeak(3,:);
Mj4=wpeak(4,:);
%画出尺度3极值点
figure(14);
plot (Mj3);
%title('尺度3下小波系数的模极大值点');posi=Mj3.*(Mj3>0);
%求正极大值的平均
thposi=(max(posi(1:round(points/4)))+max(posi(round(points/4):2*round(points/4)))+max(posi(2*round(points/4):3*round(points/4)))+max(posi(3*round(points/4):4*round(points/4))))/4;
posi=(posi>thposi/3);
nega=Mj3.*(Mj3<0);
%求负极大值的平均
thnega=(min(nega(1:round(points/4)))+min(nega(round(points/4):2*round(points/4)))+min(nega(2*round(points/4):3*round(points/4)))+min(nega(3*round(points/4):4*round(points/4))))/4;
nega=-1*(nega<thnega/4);
%找出非0点
interva=posi+nega;
loca=find(interva);
for i=1:length(loca)-1if abs(loca(i)-loca(i+1))<80diff(i)=interva(loca(i))-interva(loca(i+1));elsediff(i)=0;end
end
%找出极值对
loca2=find(diff==-2);
%负极大值点
interva2(loca(loca2(1:length(loca2))))=interva(loca(loca2(1:length(loca2))));
%正极大值点
interva2(loca(loca2(1:length(loca2))+1))=interva(loca(loca2(1:length(loca2))+1));
intervaqs(1:points-10)=interva2(11:points);
countR=zeros(1,1);
countQ=zeros(1,1);
countS=zeros(1,1);
mark1=0;
mark2=0;
mark3=0;
i=1;
j=1;
Rnum=0;
%*************************求正负极值对过零,即R波峰值,并检测出QRS波起点及终点*******************%
while i<pointsif interva2(i)==-1mark1=i;i=i+1;while(i<points&interva2(i)==0)i=i+1;endmark2=i;
%求极大值对的过零点mark3= round((abs(Mj3(mark2))*mark1+mark2*abs(Mj3(mark1)))/(abs(Mj3(mark2))+abs(Mj3(mark1))));
%R波极大值点R_result(j)=mark3-10;%为何-10?经验值吧countR(mark3-10)=1;
%求出QRS波起点kqs=mark3-10;markq=0;while (kqs>1)&&( markq< 3)if Mj1(kqs)~=0markq=markq+1;endkqs= kqs -1;endcountQ(kqs)=-1;%求出QRS波终点  kqs=mark3-10;marks=0;while (kqs<points)&&( marks<3)if Mj1(kqs)~=0marks=marks+1;endkqs= kqs+1;endcountS(kqs)=-1;i=i+60;j=j+1;Rnum=Rnum+1;end
i=i+1;
end%************************删除多检点,补偿漏检点**************************%
num2=1;
while(num2~=0)num2=0;
%j=3,过零点R=find(countR);
%过零点间隔R_R=R(2:length(R))-R(1:length(R)-1);RRmean=mean(R_R);
%当两个R波间隔小于0.4RRmean时,去掉值小的R波
for i=2:length(R)if (R(i)-R(i-1))<=0.4*RRmeannum2=num2+1;if signal(R(i))>signal(R(i-1))countR(R(i-1))=0;elsecountR(R(i))=0;endend
end
endnum1=2;
while(num1>0)num1=num1-1;R=find(countR);R_R=R(2:length(R))-R(1:length(R)-1);RRmean=mean(R_R);
%当发现R波间隔大于1.6RRmean时,减小阈值,在这一段检测R波
for i=2:length(R)if (R(i)-R(i-1))>1.6*RRmeanMjadjust=wpeak(4,R(i-1)+80:R(i)-80);points2=(R(i)-80)-(R(i-1)+80)+1;
%求正极大值点adjustposi=Mjadjust.*(Mjadjust>0);adjustposi=(adjustposi>thposi/4);
%求负极大值点adjustnega=Mjadjust.*(Mjadjust<0);adjustnega=-1*(adjustnega<thnega/5);
%或运算interva4=adjustposi+adjustnega;
%找出非0点loca3=find(interva4);diff2=interva4(loca3(1:length(loca3)-1))-interva4(loca3(2:length(loca3)));
%如果有极大值对,找出极大值对loca4=find(diff2==-2);interva3=zeros(points2,1)';for j=1:length(loca4)interva3(loca3(loca4(j)))=interva4(loca3(loca4(j)));interva3(loca3(loca4(j)+1))=interva4(loca3(loca4(j)+1));endmark4=0;mark5=0;mark6=0;while j<points2if interva3(j)==-1;mark4=j;j=j+1;while(j<points2&interva3(j)==0)j=j+1;endmark5=j;
%求过零点mark6= round((abs(Mjadjust(mark5))*mark4+mark5*abs(Mjadjust(mark4)))/(abs(Mjadjust(mark5))+abs(Mjadjust(mark4))));countR(R(i-1)+80+mark6-10)=1;j=j+60;endj=j+1;endendend
end
%画出原图及标出检测结果
%%%%%%%%%%%%%%%%%%%%%%%%%%开始求PT波段
%对R波点前的波用加窗法,窗口大小为100,然后计算窗口内极大极小的距离
%figure(20);
%plot(Mj4);
%title('j=4 细节系数'); hold on
%%%%%%%还是直接求j=4时的R过零点吧
Mj4posi=Mj4.*(Mj4>0);
%求正极大值的平均
Mj4thposi=(max(Mj4posi(1:round(points/4)))+max(Mj4posi(round(points/4):2*round(points/4)))+max(Mj4posi(2*round(points/4):3*round(points/4)))+max(Mj4posi(3*round(points/4):4*round(points/4))))/4;
Mj4posi=(Mj4posi>Mj4thposi/3);
Mj4nega=Mj4.*(Mj4<0);
%求负极大值的平均
Mj4thnega=(min(Mj4nega(1:round(points/4)))+min(Mj4nega(round(points/4):2*round(points/4)))+min(Mj4nega(2*round(points/4):3*round(points/4)))+min(Mj4nega(3*round(points/4):4*round(points/4))))/4;
Mj4nega=-1*(Mj4nega<Mj4thnega/4);
Mj4interval=Mj4posi+Mj4nega;
Mj4local=find(Mj4interval);
Mj4interva2=zeros(1,points);
for i=1:length(Mj4local)-1if abs(Mj4local(i)-Mj4local(i+1))<80Mj4diff(i)=Mj4interval(Mj4local(i))-Mj4interval(Mj4local(i+1));elseMj4diff(i)=0;end
end
%找出极值对
Mj4local2=find(Mj4diff==-2);
%负极大值点
Mj4interva2(Mj4local(Mj4local2(1:length(Mj4local2))))=Mj4interval(Mj4local(Mj4local2(1:length(Mj4local2))));
%正极大值点
Mj4interva2(Mj4local(Mj4local2(1:length(Mj4local2))+1))=Mj4interval(Mj4local(Mj4local2(1:length(Mj4local2))+1));
mark1=0;
mark2=0;
mark3=0;
Mj4countR=zeros(1,1);
Mj4countQ=zeros(1,1);
Mj4countS=zeros(1,1);
flag=0;
while i<pointsif Mj4interva2(i)==-1mark1=i;i=i+1;while(i<points&Mj4interva2(i)==0)i=i+1;endmark2=i;
%求极大值对的过零点,在R4中极值之间过零点就是R点。mark3= round((abs(Mj4(mark2))*mark1+mark2*abs(Mj4(mark1)))/(abs(Mj4(mark2))+abs(Mj4(mark1))));Mj4countR(mark3)=1;Mj4countQ(mark1)=-1;Mj4countS(mark2)=-1;flag=1;endif flag==1i=i+200;flag=0;elsei=i+1;end
end
%%%%%%%%%%%%%%%%%%%%%%%%找到MJ4的QRS点后,这里缺少对R点的漏点检测和冗余检测,先不去细究了。
%%%%%
%%%%%对尺度4下R点检测不够好,需要改进的地方
%%%%%%
%figure(200);
%plot(Mj4);
%title('j=4');
%hold on;
%plot(Mj4countR,'r');
%plot(Mj4countQ,'g');
%plot(Mj4countS,'g');%%%%%%%%%%%%%%%%%%%%%%%%%%Mj4过零点找到%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Rlocated=find(Mj4countR);
Qlocated=find(Mj4countQ);
Slocated=find(Mj4countS);
countPMj4=zeros(1,1);
countTMj4=zeros(1,1);
countP=zeros(1,1);
countPbegin=zeros(1,1);
countPend=zeros(1,1);
countT=zeros(1,1);
countTbegin = zeros(1,1);
countTend = zeros(1,1);
windowSize=100;
%%%%%%%%%%%%%%%%%%%%%%%P波检测%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Rlocated Qlocated 是在尺度4下的坐标
for i=2:length(Rlocated)flag=0;mark4=0;RRinteral=Rlocated(i)-Rlocated(i-1);for j=1:5:(RRinteral*2/3)% windowEnd=Rlocated(i)-30-j;windowEnd=Qlocated(i)-j;windowBegin=windowEnd-windowSize;if windowBegin<Rlocated(i-1)+RRinteral/3break;end%求窗内的极大极小值%windowposi=Mj4.*(Mj4>0);%windowthposi=(max(Mj4(windowBegin:windowBegin+windowSize/2))+max(Mj4(windowBegin+windowSize/2+1:windowEnd)))/2;[windowMax,maxindex]=max(Mj4(windowBegin:windowEnd));[windowMin,minindex]=min(Mj4(windowBegin:windowEnd));if minindex < maxindex &&((maxindex-minindex)<windowSize*2/3)&&windowMax>0.01&&windowMin<-0.1flag=1;mark4=round((maxindex+minindex)/2+windowBegin);countPMj4(mark4)=1;countP(mark4-20)=1;countPbegin(windowBegin+minindex-20)=-1;countPend(windowBegin+maxindex-20)=-1;endif flag==1break; endendif mark4==0&&flag==0 %如果没有P波,在R波左间隔1/3处赋值-1mark4=round(Rlocated(i)-RRinteral/3);countP(mark4-20)=-1;end
end%plot(countPMj4,'g');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%T波检测%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear windowBegin windowEnd maxindex minindex windowMax windowMin mark4 RRinteral;windowSizeQ=100;
for i=1:length(Rlocated)-1;flag=0;mark5=0;RRinteral=Rlocated(i+1)-Rlocated(i);for j=1:5:(RRinteral*2/3)% windowBegin=Rlocated(i)+30+j;windowBegin=Slocated(i)+j;windowEnd  =windowBegin+windowSizeQ;if windowEnd >Rlocated(i+1)-RRinteral/4break;end%%%%%求窗口内的极大极小值[windowMax,maxindex]=max(Mj4(windowBegin:windowEnd));[windowMin,minindex]=min(Mj4(windowBegin:windowEnd));if minindex < maxindex &&((maxindex-minindex)<windowSizeQ)&&windowMax>0.1&&windowMin<-0.1flag=1;mark5=round((maxindex+minindex)/2+windowBegin);countTMj4(mark5)=1;countT(mark5-20)=1;%找到T波峰值点%%%%%确定T波起始点和终点countTbegin(windowBegin+minindex-20)=-1;countTend(windowBegin+maxindex-20)=-1;endif flag==1break;endendif mark5==0 %如果没有T波,在R波右 间隔1/3处赋值-2mark5=round(Rlocated(i)+ RRinteral/3);countT(mark5)=-2;end
end
%plot(countTMj4,'g');
%hold off;
figure(4);
plot(ecgdata(0*points+1:1*points)),grid on,axis tight,axis([1,points,-2,5]);
title('ECG信号的各波波段检测');
hold on
plot(countR,'r');
plot(countQ,'k');
plot(countS,'k');for i=1:Rnumif R_result(i)==0;breakendplot(R_result(i),ecgdata(R_result(i)),'bo','MarkerSize',10,'MarkerEdgeColor','g');
end
plot(countP,'r');
plot(countT,'r');
plot(countPbegin,'k');
plot(countPend,'k');
plot(countTbegin,'k');
plot(countTend,'k');hold off
												

ECG信号读取,检测QRS,P,T 波(基于小波去噪与检测),基于BP神经网络的身份识别相关推荐

  1. ECG信号读出,检测QRS,P,T 波(小波去噪,并根据检测),基于BP辨识的神经网络

    这学期的课程选择神经网络.最后的作业处理ECG信号,并利用神经网络识别. 1  ECG引进和阅读ECG信号 1)ECG介绍 详细ECG背景应用就不介绍了,大家能够參考百度 谷歌.仅仅是简单说下ECG的 ...

  2. ECG信号读出,检测QRS,P,T 波(小波去噪,并根据检测),基于BP辨识的神经网络...

    这学期的课程选择神经网络.最后的作业处理ECG信号,并利用神经网络识别. 1  ECG引进和阅读ECG信号 1)ECG介绍 详细ECG背景应用就不介绍了,大家能够參考百度 谷歌.仅仅是简单说下ECG的 ...

  3. matlab模式识别提取特征向量,一种基于小波特征向量提取的手机检测方法与流程...

    本发明涉及到手机检测领域,尤其涉及到一种基于小波特征向量提取的手机检测方法. 背景技术: 随着保密要求的不断提高,很多场合严禁携带手机.录音笔.录像机等电子产品,亟需一种设备可以检测出该类电子产品.目 ...

  4. matlab复杂噪声产生实验报告,基于小波信号的噪声消除matlab实验报告.docx

    基于小波信号的噪声消除matlab实验报告.docx 南京师范大学物理科学与技术学院医用电子学论文论文名称:基于小波变换的心电信号噪声消除院系:物科院专业:电路与系统姓名:聂梦雅学号:12100204 ...

  5. bp神经网络预测未来五年数据_基于小波神经网络的数据中心KPI预测

    随着软件和微服务的发展,智能运维越来越受到人们的重视.在大量的运维数据里,最不可忽视的就是各种关键性能指标数据(Key Performance Indicators,KPI),它们在数学上都可以被表达 ...

  6. 什么是小波?小波是什么?

    小波,不严格的说即有限持续时间的波形,其平均值为零.许多我们感兴趣的信号和图像表现出瞬变行为.例如语音信号的特点是辅音短脉冲编码,然后元音稳态振荡:自然图像边缘突变:金融时间序列表现出瞬态行为,经济状 ...

  7. 基于小波的图像边缘检测,小波变换边缘检测原理

    1.什么是"小波神经网络"?能干什么用呀 小波神经网络(Wavelet Neural Network, WNN)是在小波分析研究获得突破的基础上提出的一种人工神经网络.它是基于小波 ...

  8. matlab中daubechie小波,[转载]小波滤波器

    滤波器组完美重构与小波快速算法. 前面的分析可以知道Vj相当于在j分辨率的逼近,Vj-1相当于j-1分辨率的逼近,这样Wj-1相当于两个分辨率逼近的差.在高分辨率下,我们可以用f在(2^j*t)的采样 ...

  9. 002基于小波的多类癫痫类型分类系统-2021

    WAVELET-BASED MULTI-CLASS SEIZURE TYPE CLASSIFICATION SYSTEM ABSTRACT 癫痫是最常见的脑部疾病之一,影响着全球1%以上的人口.它的特 ...

最新文章

  1. php网站怎么伪静态,php怎么实现网页伪静态
  2. LeetCode(9.回文数)JAVA
  3. 关于引用传递的测试题
  4. linux 多核线程 调度,通过轻型线程提高多核设备中的Linux实时性能
  5. 三星Galaxy S21系列将搭载One UI3.1系统:首发声音解锁
  6. boost学习之命令行参数解析库program_options
  7. PgSQL · 应用案例 · 聚集存储 与 BRIN索引
  8. 前端性能优化 —— 起步篇(一)
  9. 啦啦外卖41.7亲测可用!插件齐全!含顾客APP,商家APP ,骑手APP!需要的拿去研究
  10. 医疗器械/设备的法律法规汇总
  11. Android使用iconfont图标
  12. Java——反射(reflection)详解
  13. vivo手机怎么安装Android10,首批升级Android 10 Bate教程!vivo手机3步搞定
  14. c语言中分不分大小写,C语言高级语言程序设计(一)-第四章 程序设计方法-模块化与算法设计.ppt...
  15. PHP输出一段励志的话,100句关于励志的话,青春励志的话,写得好的励志句子
  16. 《禁闭岛》与脑前额叶,从白痴到天才看人类的认知
  17. 家里想养花了(持续更新)
  18. 关于魔兽世界封号机制的数据统计
  19. NLP的命名实体识别 -- 嵌套实体问题
  20. 搜商(人类的第三种能力)

热门文章

  1. FPGA开发之SD卡初始化
  2. 彻底搞懂 Nginx 五大应用场景!出去吹牛逼再也不担心了
  3. 考无忧计算机在线题库,考无忧2017职称计算机考试题库PC版
  4. 哲学核心概念和基本原理
  5. PCServer,刀片机,小型机,大型机这些都神马东东
  6. iphone 升级或者恢复出厂设置卡在进度条解决方法
  7. 静态HTML网页设计作品——火车票网上预订网站(4个页面) HTML+CSS+JavaScript web网页设计实例作业
  8. 储能控制器,风光储、风光储并网直流微电网simulink仿真模型
  9. Android Unity3D游戏开发之躲避方块
  10. 便宜西门子永宏B1系列PLC是否有电池?