✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。
🍎个人主页:Matlab科研工作室
🍊个人信条:格物致知。
更多Matlab仿真内容点击👇
⛄ 内容介绍
从原始心电图信号中去除不一致和尖峰,并将心电信号分离为P波、QRS波和T波是心电信号处理的关键步骤。下面是一个基本的处理框架:
- 去噪:使用数字滤波技术,例如低通滤波器或中值滤波器,去除原始心电图信号中的高频噪声和不一致成分。这有助于平滑信号并减少突发尖峰。
- R波检测:应用R波检测算法来定位QRS波群的峰值。这可以使用峰值检测、阈值检测或相关方法等进行实现。R波处于QRS复合波的最高点。
- 分割:基于R波的位置,将QRS复合波从原始心电图信号中分割出来,以获得每个心搏的独立波形。
- P波和T波分离:在QRS波形区域之外,使用特定方法(如滑动窗口平均或自适应阈值)识别和提取P波和T波。P波位于QRS波群之前,而T波位于QRS波群之后。
需要注意的是,心电信号处理是一个复杂且具有挑战性的程,可能涉及到信号噪声、基线干扰、不一致理现象等多个方面的问题。因此,为了获得准心电波形分离和去除尖峰,可能需要结合更高级的信号处理技术和机器学习算法。
⛄ 部分代码
function [data_extracted,average_heart_beat_rate] = ECG_Anormaly_Detection_Algorithm(ECG_data,Fs,ECG_distance_threshold_sensivity,ECG_peak_sensivity)if (nargin<3) %these thresholds are used to choose ECG segments that are most similar to each other. %the more the value, the more ECG segments'similarity it takes ECG_distance_threshold_sensivity=5; % threshold for finding ECG signal by the distance difference ECG_peak_sensivity=35; % threshold for finding ECG signal by the peak differencesendformat longBL=[1 zeros(1,5) -2 zeros(1,5) 1];AL=[32,-64,32];BH=[-1 zeros(1,15) 32 -32 zeros(1,14) 1];AH=[32 -32];AINT=[8];BINT=[2 1 0 -1 -2 ];BMOV=ones(1,30)./30;AMOV=[1];min_distance=(Fs/2)-round(Fs/6);[preB,preA]=butter(4,[2/Fs 60/Fs]);y=filtfilt(preB,preA,ECG_data);yL=filter(BL,AL,y);yH=filter(BH,AH,yL);yder=filter(BINT,AINT,yH);yder=filter(BINT,AINT,yH);ysqu=yder.^2;yaov=filter(BMOV,AMOV,ysqu);[pks,locs]=findpeaks(yaov,'MinPeakDistance',Fs);ECG_range=median(pks)+median(pks)/ECG_distance_threshold_sensivity;if(max(pks>=ECG_range)) pks= pks(~(pks>=ECG_range)); locs=locs(~(pks>=ECG_range));endThreshold=max(pks)*ECG_peak_sensivity/100;clear pks locs[pks,locs]=findpeaks(yaov,'MinPeakHeight',Threshold,'MinPeakDistance',min_distance);new_locs=zeros([size(locs)]);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%The value 23 is the group delay of Pan-Tompkins filters.%It is used to match the original ECG signals with the R points found by using output of Pan-Tompkins filtersgroup_delay=23;if(locs(1,1)>round(Fs/group_delay)) new_locs=locs-round(Fs/group_delay);else new_locs=locs(2:end)-round(Fs/group_delay); pks=pks(2:end);end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%for i=1:length(new_locs) if(new_locs(i)>(Fs/2) && new_locs(i)+(Fs/2)<length(yaov)) X=yaov(new_locs(i)-(Fs/2):new_locs(i)+(Fs/2)); X=ECG_data(new_locs(i)-(Fs/2):new_locs(i)+(Fs/2)); else X=0; end mu=mean(X); sigma(i) = std(X)-mu; clear XendECG_signal_ortalama=median(sigma);Threshold_ECG_Signal=(ECG_signal_ortalama/ECG_distance_threshold_sensivity);%Erase the signal locationslocs_remove=[];j=1;z=1;locs2=0;for i=1:length(sigma) if((ECG_signal_ortalama+Threshold_ECG_Signal)<sigma(i)||(ECG_signal_ortalama-Threshold_ECG_Signal)>sigma(i)) locs_remove(j)=new_locs(i); j=j+1; else locs2(z)=new_locs(i); z=z+1; endendclear zaverage=0;for i=1:length(locs2)-1 average=average+abs(locs2(i)-locs2(i+1));endaverage_heart_beat_rate=(Fs/(average/(length(locs2))))*60;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Double Check if there is anything unusual between two R pointsstart=1;range=0;data_extracted{1}=0;for i=2:length(locs2) range=range+abs(locs2(i-1)-locs2(i));endrange=range/length(locs2);Threshols_ayrim_h=range+range/(ECG_distance_threshold_sensivity/2);Threshols_ayrim_l=range-range/(ECG_distance_threshold_sensivity/2);for i=2:length(locs2) X(i)=std(ECG_data(locs2(i-1):locs2(i)))-mean(ECG_data(locs2(i-1):locs2(i)));endif(length(locs2)==1) X=0;endThreshols_ayrim_2h=abs(median(X)+median(X)/(ECG_distance_threshold_sensivity/1));Threshols_ayrim_2l=abs(median(X)-median(X)/(ECG_distance_threshold_sensivity/1));k=1;i=2;first_index=1;while i<=length(locs2) sigma1=std(ECG_data(locs2(i-1):locs2(i)))-mean(ECG_data(locs2(i-1):locs2(i))); if(((abs(locs2(i-1)-locs2(i))>=Threshols_ayrim_h)||((abs(locs2(i-1)-locs2(i))<=Threshols_ayrim_l)))||((sigma1>=Threshols_ayrim_2h)||(sigma1<=Threshols_ayrim_2l))) if(start==1) clear data_extracted start=0; end if(~(abs(locs2(first_index)-locs2(i-1))<=Fs*2)) data_extracted{k}(:)=ECG_data(locs2(first_index):locs2(i-1)); k=k+1; end first_index=i; end i=i+1;endif((start==1 || (first_index~=1 && start==0))&& (length(locs2)~=1)) if(start==1) clear data_extracted end data_extracted{k}(:)=ECG_data(locs2(first_index):locs2(i-1));end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%figo=figure('WindowState','maximized');plot(0:1/Fs:length(ECG_data)/Fs-1/Fs,ECG_data)hold onif(length(locs2)~=1) plot(locs2/Fs,(ECG_data(locs2)),'o','MarkerSize',6)endpos = get(figo,'position');set(figo,'position',[pos(1:2)/4 pos(3:4)*1.5]);set(gca,'Fontsize',16)title('Raw ECG Signal','fontsize',32);hold offxlabel('Time in Seconds','fontsize',24);ylabel('12 bits Raw ECG','fontsize',24);end
⛄ 运行结果
⛄ 参考文献
Guven, Gokhan, et al. “A Novel Biometric Identification System Based on Fingertip Electrocardiogram and Speech Signals.” Digital Signal Processing, vol. 121, Elsevier BV, Mar. 2022, p. 103306, doi:10.1016/j.dsp.2021.103306.