✅作者简介:热爱科研的Matlab仿真开发者,擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。
🍎 往期回顾关注个人主页:Matlab科研工作室
🍊个人信条:格物致知,完整Matlab代码及仿真咨询内容私信。
🔥 内容介绍
心电图 (ECG) 是反映心脏电活动的重要工具,QRS 波是 ECG 中最显著的特征,代表着心室除极过程。准确识别 QRS 波是心律失常诊断和心血管疾病研究的关键。近年来,基于小波变换的心电信号 QRS 波检测方法取得了显著进展。本文将详细介绍基于小波变换的心电信号 QRS 波检测方法,包括小波理论、QRS 波检测算法以及算法的评估指标。
1. 引言
心电图 (ECG) 是反映心脏电活动的重要工具,广泛应用于临床诊断和心血管疾病研究。ECG 信号包含丰富的生理信息,其中 QRS 波是 ECG 中最显著的特征,代表着心室除极过程。准确识别 QRS 波是心律失常诊断和心血管疾病研究的关键。
传统的心电信号 QRS 波检测方法主要包括基于阈值的方法、基于形态学的方法和基于滤波的方法。这些方法虽然能够在一定程度上识别 QRS 波,但存在着误检率高、抗噪声能力差等缺点。
近年来,基于小波变换的心电信号 QRS 波检测方法取得了显著进展。小波变换是一种时频分析方法,能够有效地提取信号的局部特征,并具有良好的抗噪声能力。基于小波变换的心电信号 QRS 波检测方法能够有效地克服传统方法的缺点,提高 QRS 波检测的准确率。
2. 小波理论
小波变换是一种时频分析方法,它将信号分解成一系列小波函数的线性组合。小波函数是一种具有良好局部化特性的函数,能够有效地提取信号的局部特征。
小波变换的基本原理如下:
-
选择一个母小波函数 ψ(t),它是一个具有良好局部化特性的函数。
-
将信号 f(t) 与母小波函数 ψ(t) 进行卷积运算,得到小波系数:
c(a, b) = ∫f(t)ψ(a, b)dt
其中,a 是尺度因子,b 是平移因子。
-
通过改变尺度因子 a 和平移因子 b,可以得到不同尺度和位置的小波系数。
小波系数包含了信号的时频信息,可以通过分析小波系数来提取信号的局部特征。
3. QRS 波检测算法
基于小波变换的心电信号 QRS 波检测算法主要包括以下步骤:
-
对心电信号进行小波分解,得到不同尺度的小波系数。
-
选择合适的尺度,提取 QRS 波的小波系数。
-
对 QRS 波的小波系数进行阈值处理,去除噪声和干扰。
-
根据 QRS 波的小波系数的特征,确定 QRS 波的起始点和终止点。
4. 结论
基于小波变换的心电信号 QRS 波检测方法是一种有效的方法,能够有效地克服传统方法的缺点,提高 QRS 波检测的准确率。该方法具有良好的抗噪声能力和鲁棒性,在心律失常诊断和心血管疾病研究中具有重要的应用价值。
📣 部分代码
file_ind = 0;
last_it_num = 0;
for n = 3:num_files %%%%still need to deal with iteration #1
keep n file_ind z virmen_channe l_number acquisitions
if contains(z(n).name,string)==1
file_ind = file_ind +1;
[sync_data,sync_sampling_interval,~]= abfload(z(n).name);
sync_sampling_rate = 1/sync_sampling_interval*1e6;
temp = sync_data(:,virmen_channel_number);
time = 1:length(temp).*1/sync_sampling_rate;
temp = double(temp);
temp = temp-median(temp);
[pks,locs] = findpeaks(abs(temp),'MINPEAKHEIGHT',0.09,'MinPeakDistance',5);
temp = temp./abs(mean(temp(locs)));
%temp = temp./abs(mean(temp(locs)))*1e3; %do I need to do this???
%%%if it's the first file, ignore Virmen initializing? Very negative
%%%initial pulse
it_values = temp(locs); %%%wavesurfer values at pulse times
it_times = locs; %%%in wavesurfer units
marked_its = find(it_values>0);
if isempty(marked_its)
disp('Error! Current file does not have positive values. File is probably too short')
n=n+1;
file_ind = file_ind +1;
else
%findpeaks could find peaks right next to each other this code will
%find the min of a group and use that as the marked_its
%it will get rid of extra neighbouring detected peaks and account for
%this by subtracting it from the marked_its
group = {}; count = 1;
temp2=[];
temp3=[];
if length(marked_its)>1
for m = 1:length(marked_its)-1
if marked_its(m)+2>marked_its(m+1) %if current value +2 is greater than current value+1
temp2 = [temp2,marked_its(m)];
temp3 = min(temp2);
group(count).group = temp3;
group(count).temp2 = temp2;
else
temp2 = [temp2,marked_its(m)];
group(count).temp2 = temp2;
group(count).group = min(group(count).temp2);
temp2=[];
count= count+1;
end
end
%dealing with if you have a last value with no group
if marked_its(length(marked_its)) - marked_its(length(marked_its)-1) >10 %10 value could change
group(length(group)+1).group = marked_its(length(marked_its));
group(length(group)).temp2 = marked_its(length(marked_its));
end
marked_its_old = marked_its;
extra_num = {};
marked_its=[];
marked_its_shifted = [];
for i =1:length(group)
extra_num(i).group = length(group(i).temp2)-1;
if i == 1 %no value in front of first one so this is the true value
marked_its(i) = group(i).group;
marked_its_shifted(i)=group(i).group;
else
temp5= [];
temp3 = group(i).group;
for j = i-1:-1:1
temp4 = sum(extra_num(j).group);
temp5 = [temp5, temp4];
end
marked_its(i) = temp3 - sum(temp5);
marked_its_shifted(i)= temp3;
end
end
extra_its = ~ismember(marked_its_old,marked_its_shifted);
it_times(marked_its_old(extra_its)) = [];
it_values = temp(it_times);
end
actual_it_values = zeros(1,length(it_values));
%if first 10000?
if round(it_values(marked_its(1)),0)==10 %round(it_values(marked_its(1)),1)==10 was set to 1 instead of 0
actual_it_values(marked_its(1)) = 1;
else
actual_it_values(marked_its(1)) = round(((it_values(marked_its(1))*1e5)/1e4))*1e4;
next_value = actual_it_values((marked_its(1))); %%%changed cb 2/18/22
next_its = marked_its(1)-1:-1:1;
%%%count back from first known landmark,
for it = 1:length(next_its)
actual_it_values(next_its(it)) = next_value-1;
next_value = actual_it_values(next_its(it));
end
end
%%%and forward from first....
previous_value = actual_it_values((marked_its(1)))-1
if length(marked_its)>1
for m = 2:length(marked_its)
if m ==2
for it = marked_its(m-1):marked_its(m)-1 %% changed from it = marked_its(m-1):marked_its(m)-1
actual_it_values(it) = previous_value+1;
previous_value = actual_it_values(it);
end
end
% if round(it_values(marked_its(1)),1)==0.1
% if round(previous_value+1,-4)==round(((it_values(marked_its(m-1))*1e5)/1e4))*1e4
% if m <length(marked_its)
% for it = marked_its(m):marked_its(m+1)%length(it_values)%marked_its(m+1)-1%marked_its(m):marked_its(m+1) %have to figure out numbers
% actual_it_values(it) = previous_value+1;
% previous_value = actual_it_values(it);
% end
% else
% for it = marked_its(m):length(it_values)%%have to figure out numbers
% actual_it_values(it) = previous_value+1;
% previous_value = actual_it_values(it);
% end
% end
% else
% disp('Error! Iteration numbers do not match')
% keyboard
% end
% else
if round(previous_value+1,-4)==round(((it_values(marked_its(m))*1e5)/1e4))*1e4
if m <length(marked_its)
for it = marked_its(m):marked_its(m+1)%length(it_values)%marked_its(m+1)-1%marked_its(m):marked_its(m+1) %have to figure out numbers
actual_it_values(it) = previous_value+1;
previous_value = actual_it_values(it);
end
else
for it = marked_its(m):length(it_values)%%have to figure out numbers
actual_it_values(it) = round(((it_values(marked_its(m))*1e5)/1e4))*1e4+1;
previous_value = actual_it_values(it);
end
end
else
if m <length(marked_its)
for it = marked_its(m):marked_its(m+1)%length(it_values)%marked_its(m+1)-1%marked_its(m):marked_its(m+1) %have to figure out numbers
actual_it_values(it) = round(((it_values(marked_its(m))*1e5)/1e4))*1e4+1;
previous_value = actual_it_values(it);
end
else
for it = marked_its(m):length(it_values)%%have to figure out numbers
actual_it_values(it) = round(((it_values(marked_its(m))*1e5)/1e4))*1e4+1;
previous_value = actual_it_values(it);
end
end
end
end
else
for it = marked_its(1):length(actual_it_values) % marked_its(1)+1:length(actual_it_values)
actual_it_values(it) = previous_value+1;
previous_value = actual_it_values(it);
end
actual_it_values(length(actual_it_values))
end
%for dealing with weird zeros before acqusition counter for first file
if file_ind ==1
if length(find(actual_it_values==0)) >0
no_zeros = find(actual_it_values>0);
no_zeros = [no_zeros(1)-1,no_zeros];
acquisitions(file_ind).actual_it_values = actual_it_values(no_zeros);
acquisitions(file_ind).it_times = it_times(no_zeros);
else
acquisitions(file_ind).actual_it_values = actual_it_values;
acquisitions(file_ind).it_times = it_times;
end
else
acquisitions(file_ind).actual_it_values = actual_it_values;
acquisitions(file_ind).it_times = it_times;
end
figure(2);clf; hold on;plot(temp); plot(it_times(marked_its),0,'*c'); hold off
end
end
end
%figure(3);clf;hold on; for i= 1:length(acquisitions) ; plot(acquisitions(i).it_times,acquisitions(i).actual_it_values);end;hold off
%figure (3); clf;for i = 1:8; subplot(8,1,i); hold on; plot(ex_file_long(:,i)'); hold off; end
⛳️ 运行结果
🔗 参考文献
[1] 李卓妮.成人及胎儿心电信号R波检测算法的研究[D].华南理工大学[2024-04-26].DOI:CNKI:CDMD:2.1013.319172.
[2] 刘近贞,孙利飞,熊慧,等.基于能量分段与平稳小波变换的运动心电图特征波检测算法研究[J].生物医学工程学杂志, 2021, 38(6):1181-1192.
🎈 部分理论引用网络文献,若有侵权联系博主删除
🎁 关注我领取海量matlab电子书和数学建模资料
👇 私信完整代码和数据获取及论文数模仿真定制
1 各类智能优化算法改进及应用
生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化、背包问题、 风电场布局、时隙分配优化、 最佳分布式发电单元分配、多阶段管道维修、 工厂-中心-需求点三级选址问题、 应急生活物质配送中心选址、 基站选址、 道路灯柱布置、 枢纽节点部署、 输电线路台风监测装置、 集装箱船配载优化、 机组优化、 投资优化组合、云服务器组合优化、 天线线性阵列分布优化、CVRP问题、VRPPD问题、多中心VRP问题、多层网络的VRP问题、多中心多车型的VRP问题、 动态VRP问题、双层车辆路径规划(2E-VRP)、充电车辆路径规划(EVRP)、油电混合车辆路径规划、混合流水车间问题、 订单拆分调度问题、 公交车的调度排班优化问题、航班摆渡车辆调度问题、选址路径规划问题
2 机器学习和深度学习方面
2.1 bp时序、回归预测和分类
2.2 ENS声神经网络时序、回归预测和分类
2.3 SVM/CNN-SVM/LSSVM/RVM支持向量机系列时序、回归预测和分类
2.4 CNN/TCN卷积神经网络系列时序、回归预测和分类
2.5 ELM/KELM/RELM/DELM极限学习机系列时序、回归预测和分类
2.6 GRU/Bi-GRU/CNN-GRU/CNN-BiGRU门控神经网络时序、回归预测和分类
2.7 ELMAN递归神经网络时序、回归\预测和分类
2.8 LSTM/BiLSTM/CNN-LSTM/CNN-BiLSTM/长短记忆神经网络系列时序、回归预测和分类
2.9 RBF径向基神经网络时序、回归预测和分类