基于集成经验模态分解的心电信号降噪和基于希尔伯特变换的R峰检测(MATLAB R2018)

近年来,心脏病已成为危害人类健康最常见的疾病。为了有效预防心脏疾病的发生,往往需要更加准确地采集与诊断心电信号,以便于更好地反映心脏情况。心电信号作为人体生理信号,对于识别心脏异常和心脏疾病具有重要的参考价值。心电信号,是由心脏的电活动引起心脏周围的导电组织和体液反映到身体表面上而产生的电压变化。正常心电信号主要由P波、QRS复合波、T波与U波组成。由于心电信号频率与振幅较低,在采集心电信号时往往伴随着不可避免的噪声,因而降噪成为心电信号处理的核心。心电信号中存在多种低频和高频噪声,常见的噪声有加性高斯白噪声(AdditiveWhiteGaussianNoise,AWGN)、基线漂移(BaselineWander,BW)、肌电干扰(MuscleArtefacts,MA)、运动伪影(ElectrodeMotion,EM)、工频干扰(PowerLineInterference,PLI)。

基线漂移(BW):BW是一种低频噪声信号,主要是由呼吸、身体运动、电极接触不良与皮肤电极阻抗所引起的。BW噪声会使心电信号中的ST段与其他低频成分失真。

工频干扰(PLI):PLI主要是由供电设备产生的,它会扭曲低振幅心电信号波(P波或T波)的振幅与形状。

肌电干扰(MA):MA作为最主要的心电噪声信号之一,是由肌肉的收缩与颤动或身体突然运动而产生的电活动。肌电信号导致心电信号的局部波失真。

运动伪影(EM):由测量心电信号的电极与皮肤之间的阻抗随着相对位移而发生改变所引起的,与P波、T波的频谱几乎完全重合。

ECG处理主要是从采集到有噪声的信号中通过技术提取纯信号,以便于更精确地分析与诊断心脏问题。因此,希望设计一种能够完全消除噪声而不影响信号的技术。然而事实上,这是不可能的。因为噪声的频率与信号的频率在一个阶段非常接近以至于重叠,会无法滤除噪声或会使信号失真。因此,尽最大可能去除噪声而不影响信号是目前最主要的技术。近年来,众多学者采用不同学科不同领域方法来研究如何降噪,取得了较满意效果。

鉴于此,提出一种基于集成经验模态分解的心电信号降噪和基于希尔伯特变换的R峰检测,运行环境为MATLAB 2018,主代码如下:

%% Data Loading
ecg=load ('ecg1.mat');          % loading the signal 
ecg=struct2cell(ecg);
ecg=cell2mat(ecg);
ecg = (ecg - 1024)/200;     % you have to remove "base" and "gain"
ecg1=ecg(1,:);              %Noisy ecg
ecg2=ecg(2,:);              %filtered ecg
Fs =500;                    % sampling frequecy
t =linspace(0,length(ecg1)/Fs,length(ecg1)); %time vector%% ECG signal denoising
imf=eemd(ecg1,.2,70); %Apply the EEMD to the noisy signal .2->ratio of the standard deviation 70->ensemble number
imfs=imf';             %transpose the imf's matrix
reconstruction=imfs(4,:)+imfs(5,:)+imfs(6,:);  %We consider that these 3 imf's possess the important information%4 order Butterworth filter bandpass .05-230Hz. 
fclowpass=230; % Low pass cut-off frequency 230Hz
fchighpass=.05; % Low pass cut-off frequency .05Hz
filterorder=4;  %filter order[b,a]=butter(filterorder,[filterorder*fchighpass/Fs,2*fclowpass/Fs]);
filtered_ECG=filter(b,a,reconstruction);%% Emphasizing R peaks of the ECG
%Getting the maxima and minima of the ECG signal, to emphasize the R peaks
decg=(1/Fs)*(diff(filtered_ECG));  %derivative of the ecg
hecg=hilbert(decg); %hilbert transform of the derivative. 
envelope=abs(hecg);  %It returns the envelope of the ecg%% R peaks detection 
maximum=(max(envelope));
Threshold=.6*(maximum); 
[pks,locs] = findpeaks(envelope,'MinPeakHeight',Threshold);
time=(1/Fs)*length(ecg1);
timefactor=60/time;
cardiacFreq=round(timefactor*length(pks));
%% Plots
figure (1)
plot(t,ecg1); xlabel('time (s)'); ylabel('mV'); title('Raw ECG');
figure(2)
subplot(7,1,1);
plot(t,imfs(1,:)); xlabel('time (s)'); ylabel('mV'); title('Original ECG');
subplot(7,1,2);
plot(t,imfs(2,:)); xlabel('time (s)'); ylabel('mV'); title('1st IMF');
subplot(7,1,3);
plot(t,imfs(3,:)); xlabel('time (s)'); ylabel('mV'); title('2nd IMF');
subplot(7,1,4);
plot(t,imfs(4,:)); xlabel('time (s)'); ylabel('mV'); title('3rd IMF');
subplot(7,1,5);
plot(t,imfs(5,:)); xlabel('time (s)'); ylabel('mV'); title('4th IMF');
subplot(7,1,6);
plot(t,imfs(6,:)); xlabel('time (s)'); ylabel('mV'); title('5th IMF');
subplot(7,1,7);
plot(t,imfs(7,:)); xlabel('time (s)'); ylabel('mV'); title('6th IMF');
figure (3)
subplot(7,1,1);
plot(t,imfs(8,:)); xlabel('time (s)'); ylabel('mV'); title('7th IMF');
subplot(7,1,2);
plot(t,imfs(9,:)); xlabel('time (s)'); ylabel('mV'); title('8th IMF');
subplot(7,1,3);
plot(t,imfs(10,:)); xlabel('time (s)'); ylabel('mV'); title('9th IMF');
subplot(7,1,4);
plot(t,imfs(11,:)); xlabel('time (s)'); ylabel('mV'); title('10th IMF');
subplot(7,1,5);
plot(t,imfs(12,:)); xlabel('time (s)'); ylabel('mV'); title('11th IMF');
subplot(7,1,6);
plot(t,imfs(13,:)); xlabel('time (s)'); ylabel('mV'); title('12th IMF');
subplot(7,1,7);
plot(t,imfs(14,:)); xlabel('time (s)'); ylabel('mV'); title('13th IMF');
figure (4)
plot(t,reconstruction); xlabel('time (s)'); ylabel('mV'); title('IMFs reconstruction');
figure(5)
plot(t,filtered_ECG); xlabel('time (s)'); ylabel('mV'); title('Filtered ECG (IMF+bandPass)');
figure(6)
plot(t(1:9999),decg); xlabel('time (s)'); ylabel('d(ECG)/dt'); title('ECG derivative');
figure(7)
plot(t(1:9999),hecg); xlabel('time (s)'); ylabel('H(d(ECG)/dt)'); title('Hilbert Transform of derivate');
figure(8)
plot(t(1:9999),envelope); xlabel('time (s)'); ylabel('B(d(ECG)/dt)'); title('Envelope');
figure (9)
plot(t(1:9999),envelope,locs,pks,'or');
%完整代码:mbd.pub/o/bread/mbd-ZJablZ5x
legend('ECG','R peaks','Location','NorthWest');

图片

图片

图片

图片

图片

图片

图片

工学博士,担任《Mechanical System and Signal Processing》《中国电机工程学报》《控制与决策》等期刊审稿专家,擅长领域:现代信号处理,机器学习,深度学习,数字孪生,时间序列分析,设备缺陷检测、设备异常检测、设备智能故障诊断与健康管理PHM等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/16563.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu如何安装gitlab runner

一、什么是GitLab Runner GitLab Runner 是 GitLab 提供的一个开源工具,用于在构建、测试和部署过程中执行作业。它是 GitLab 持续集成和持续部署(CI/CD)工作流的核心组件之一。 GitLab Runner 有以下主要功能: 作业执行:GitLab Runner 会接收来自 GitLab 的作业请求,并在指定…

ROS基础学习-ROS通信机制研究

研究ROS通信机制 研究ROS通信机制 0.前言1.话题通信1.1 理论模型1.2 话题通讯的基本操作1.2.1 C++1.2.2 Python0.前言 机器人是一种高度复杂的系统性实现,在机器人上可能集成各种传感器(雷达、摄像头、GPS…)以及运动控制实现,为了解耦合,在ROS中每一个功能点都是一个单独的…

从File类开始,学习Java文件操作

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一…

windows安装SQL Server

1、下载 下载网页:SQL Server 下載 | Microsoft 2022版下载地址:https://go.microsoft.com/fwlink/p/?linkid2215158&clcid0x404&culturezh-tw&countrytw 下载结果:SQL2022-SSEI-Dev.exe 打开选第三个,下载介质&…

自定义Linux命令,显示docker镜像、容器信息

1、修改环境变量(仅对当前用户有效) vim ~/.bashrc2、给命令取别名 alias dpsdocker ps --format "table{{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}" alias disdocker images#保存并退出 :wq3、让配置重新生效 source ~/.bashrc4、测试&…

ChatGPT技术演进简介

chatGPT(chat generative pre-train transformer, 可以对话的预训练trasformer模型),讨论点: 1、chatGPT为什么突然火了 2、GPT 1.0、2.0、3.0、3.5 、4和4o区别和特性,在不同应用场景中如何选对模型 3、未…

基于ESP8266的无线通信系统设计

本文介绍了一种基于ESP8266的无线通信系统设计方案。ESP8266是一款功能强大且成本低廉的WiFi模块,非常适合用于构建无线通信系统。本设计主要围绕ESP8266模块的功能特点,阐述了系统的硬件组成、软件设计以及实际应用示例。 关键词:ESP8266&a…

【docker】仓库harbor的部署

harbor介绍 Harbor 是一个用于存储和管理 Docker 镜像的开源仓库。它提供了一系列的功能,比如用户管理、访问控制、镜像管理、日志审计和安全扫描等。Harbor 可以作为私有仓库来使用,也可以与公有仓库(如 Docker Hub)集成使用。 …

python数据分析——apply 1

参考资料:活用pandas库 apply是指把函数同时作用于DataFrame的每一行或每一列。类似于编写一些跨每行或每列的for循环,并同时调用apply函数。 1、函数 函数是对python代码进行分组和复用的一种方法。如果某段代码会被多次使用,并且使用时是需…

JS Lab

如何用 JavaScript 在浏览器中弹窗如何在 JavaScript 中制作鼠标滑过按钮改变背景颜色如何在 JS 中点击按钮使数字增加如何在 JS 中循环打印多少次 HTML <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title…

优化FPGA SelectIO接口VREF生成电路

引言&#xff1a;FPGA设计中使用了各种PCB SelectIO™接口VREF生成电路。有时即使在以前的设计中已经成功的在电路板上设计了VREF生成电路&#xff0c;也会在VREF引脚上发现大量噪声&#xff08;200–400mV&#xff09;。大量VREF噪声的存在可能导致高性能SelectIO接口&#xf…

瑞昱半导体AMB82 MINI(RTL8735B)Arduino 方法介绍

介绍瑞昱半导体&#xff08;Realtek &#xff09;AMB82-Mini 物联网 AI开发板 Ameba是一个易于编程的平台&#xff0c;用于开发各种物联网应用程序。AMB82 MINI配备了各种外设接口&#xff0c;包括WiFi、BLE、GPIO INT、I2C、UART、SPI、PWM、ADC。通过这些接口&#xff0c;AM…

找出只出现一次的数字

输入一些数字&#xff0c;每个数字以逗号分隔&#xff0c;其中有一个数字出现1次&#xff0c;其余数字均会出现2次。请找出那个只出现一次的数字! 提示&#xff1a;使用字典的方式实现 # 输入一些数字&#xff0c;每个数字以逗号分隔 input_nums input("请输入一些数字…

从0开始学统计-秩和检验

1.什么是秩和检验&#xff1f; 秩和检验&#xff0c;也称为Wilcoxon 秩和检验&#xff0c;是一种非参数统计检验方法&#xff0c;用于比较两个独立样本的中位数是否有显著差异。它不要求数据满足正态分布假设&#xff0c;因此适用于小样本或者数据不满足正态分布假设的情况。 …

51单片机-实机演示(单个数码管)

仿真单个数码管链接&#xff1a;http://t.csdnimg.cn/BLMut 一。插线 注意P00连接到A 测试代码为 #include <reg52.h> //此文件中定义了单片机的一些特殊功能寄存器// sbit KEY2 P3^2; // 独立按键2void main() {P0 0x00;while (1) {}…

Spring AOP实现Mapper层查询返回重新赋值

需求&#xff1a; 针对查询返回的数据&#xff0c;在数据库层处理可能会影响到性能&#xff0c;在考虑性能及维护方便的情况下&#xff0c;采用AOP实现 1&#xff0c;自定义注解 import java.lang.annotation.*;/*** 针对 mapper层返回值 按照一定规则进行特殊处理后返回*/ Ta…

Vue学习JSON.parse()与JSON.stringify()对象与字符串互转

Vue学习JSON.parse(&#xff09;与JSON.stringify(&#xff09;对象与字符串互转 一、前言1、代码 一、前言 JSON.parse() 和 JSON.stringify() 是 JavaScript 中用于处理 JSON 数据的两个方法。 JSON.parse() 方法将一个 JSON 字符串解析为对应的 JavaScript 对象或数组。例…

kaggle竞赛实战3

接前文&#xff0c;本文主要做以下几件事&#xff1a; 1、把前面处理完的几个表拼成一个大表 2、做特征衍生&#xff08;把离散特征和连续特征两两组合得出&#xff09; # In[89]: #开始拼接表 transaction pd.concat([new_transaction, history_transaction], axis0, ignor…

JAVA实现图书管理系统(初阶)

一.抽象出对象: 1.要有书架&#xff0c;图书&#xff0c;用户&#xff08;包括普通用户&#xff0c;管理员用户&#xff09;。根据这些我们可以建立几个包&#xff0c;来把繁杂的代码分开&#xff0c;再通过一个类来把这些&#xff0c;对象整合起来实现系统。说到整合&#xf…

[数组查找]2.图解二分查找及其代码实现

二分查找 二分查找也是一种在数组中查找数据的算法。和线性查找不同&#xff0c;它只能查找已经排好序的数据。二分查找通过比较数组中间的数据与目标数据的大小&#xff0c;可以得知目标数据是在数组的左边还是右边。因此&#xff0c;比较一次就可以把查找范围缩小一半。重复执…