基于MATLAB的心电信号去噪

简介: 基于MATLAB的心电信号去噪

基于MATLAB的心电信号去噪

心电信号(ECG)是诊断心脏疾病的重要工具,但在采集过程中常受到各种噪声干扰。本文将介绍基于MATLAB的心电信号去噪方法,并提供完整的代码实现。

噪声类型分析

  1. 基线漂移:低频噪声(0.5Hz以下),由呼吸运动和电极移动引起
  2. 工频干扰:50/60Hz交流电源干扰
  3. 肌电噪声:高频噪声(5-2000Hz),由肌肉活动产生
  4. 运动伪影:由患者移动引起的不规则干扰

MATLAB去噪方法

1. 基本滤波方法

function clean_ecg = basic_filtering(ecg, fs)
    % 带通滤波 (0.5-100Hz)
    [b, a] = butter(3, [0.5, 100]/(fs/2), 'bandpass');
    filtered = filtfilt(b, a, ecg);

    % 陷波滤波去除工频干扰
    wo = 50/(fs/2);  % 工频50Hz
    bw = wo/35;      % 带宽
    [b, a] = iirnotch(wo, bw);
    clean_ecg = filtfilt(b, a, filtered);

    % 绘图
    figure('Name', '基本滤波效果');
    subplot(2,1,1); plot(ecg); title('原始ECG信号');
    subplot(2,1,2); plot(clean_ecg); title('基本滤波后信号');
end

2. 小波变换去噪

function clean_ecg = wavelet_denoise(ecg, wavelet_name, level)
    % 小波分解
    [C, L] = wavedec(ecg, level, wavelet_name);

    % 计算阈值
    thr = thselect(ecg, 'rigrsure');

    % 应用软阈值处理细节系数
    sorh = 's'; % 软阈值
    keepapp = 1; % 保留近似系数
    denoised = wdencmp('gbl', C, L, wavelet_name, level, thr, sorh, keepapp);

    clean_ecg = denoised;

    % 绘图
    figure('Name', '小波去噪效果');
    subplot(level+2,1,1); plot(ecg); title('原始ECG信号');
    for i = 1:level
        subplot(level+2,1,i+1);
        plot(wrcoef('d', C, L, wavelet_name, i));
        title(['第' num2str(i) '层细节系数']);
    end
    subplot(level+2,1,level+2); plot(clean_ecg); title('小波去噪后信号');
end

3. 自适应滤波

function clean_ecg = adaptive_filtering(ecg, fs, mu)
    % 生成参考噪声
    t = (0:length(ecg)-1)/fs;
    ref_noise = sin(2*pi*50*t)'; % 50Hz工频干扰

    % LMS自适应滤波
    order = 32; % 滤波器阶数
    lms = dsp.LMSFilter(order, 'StepSize', mu, 'Method', 'Normalized LMS');
    [clean_ecg, ~, ~] = lms(ref_noise, ecg);

    % 绘图
    figure('Name', '自适应滤波效果');
    subplot(2,1,1); plot(ecg); title('原始ECG信号');
    subplot(2,1,2); plot(clean_ecg); title('自适应滤波后信号');
end

4. 经验模态分解(EMD)

function clean_ecg = emd_denoise(ecg)
    % EMD分解
    imf = emd(ecg);

    % 选择重构分量 (去除高频噪声)
    num_imf = size(imf, 2);
    recon_imf = 2:num_imf-2; % 去除前2个和后2个IMF

    % 重构信号
    clean_ecg = sum(imf(:, recon_imf), 2);

    % 绘图
    figure('Name', 'EMD分解');
    for i = 1:size(imf, 2)
        subplot(size(imf,2),1,i);
        plot(imf(:,i));
        title(['IMF ' num2str(i)]);
    end

    figure('Name', 'EMD去噪效果');
    subplot(2,1,1); plot(ecg); title('原始ECG信号');
    subplot(2,1,2); plot(clean_ecg); title('EMD去噪后信号');
end

5. 综合去噪流程

function clean_ecg = comprehensive_ecg_denoising(ecg, fs)
    % 步骤1: 去除基线漂移
    [b, a] = butter(3, 0.5/(fs/2), 'high');
    ecg1 = filtfilt(b, a, ecg);

    % 步骤2: 小波去噪
    clean_ecg = wavelet_denoise(ecg1, 'db6', 5);

    % 步骤3: 工频干扰去除
    wo = 50/(fs/2);
    bw = wo/35;
    [b, a] = iirnotch(wo, bw);
    clean_ecg = filtfilt(b, a, clean_ecg);

    % 步骤4: 平滑处理
    clean_ecg = movmean(clean_ecg, 5);

    % 性能评估
    evaluate_performance(ecg, clean_ecg);
end

function evaluate_performance(original, denoised)
    % 计算SNR
    noise = original - denoised;
    signal_power = mean(original.^2);
    noise_power = mean(noise.^2);
    snr = 10*log10(signal_power/noise_power);

    % 计算RMSE
    rmse = sqrt(mean((original - denoised).^2));

    % 计算相关系数
    corr_coef = corrcoef(original, denoised);
    r = corr_coef(1,2);

    % 显示结果
    fprintf('去噪性能评估:\n');
    fprintf('信噪比(SNR): %.2f dB\n', snr);
    fprintf('均方根误差(RMSE): %.4f\n', rmse);
    fprintf('相关系数: %.4f\n', r);

    % 绘制对比图
    figure('Name', '去噪效果对比');
    subplot(3,1,1); plot(original); title('原始ECG信号');
    subplot(3,1,2); plot(denoised); title('去噪后ECG信号');
    subplot(3,1,3); plot(original - denoised); 
    title(['噪声信号 (SNR=' num2str(snr, '%.2f') 'dB)']);
end

完整示例代码

%% ECG信号去噪MATLAB实现
clear; close all; clc;

% 1. 加载ECG数据
load('ecg_data.mat'); % 替换为您的ECG数据
fs = 360; % 采样率 (Hz)
t = (0:length(ecg)-1)/fs;

% 2. 添加噪声 (如果数据是干净的)
noise_free = ecg; % 保存干净信号
ecg = ecg + 0.1*randn(size(ecg)); % 高斯白噪声
ecg = ecg + 0.05*sin(2*pi*50*t)'; % 50Hz工频干扰
ecg = ecg + 0.02*sin(2*pi*0.3*t)'; % 基线漂移

% 3. 应用去噪方法
method = 5; % 1-基本滤波, 2-小波去噪, 3-自适应滤波, 4-EMD, 5-综合方法

switch method
    case 1
        clean_ecg = basic_filtering(ecg, fs);
    case 2
        clean_ecg = wavelet_denoise(ecg, 'db6', 6);
    case 3
        clean_ecg = adaptive_filtering(ecg, fs, 0.01);
    case 4
        clean_ecg = emd_denoise(ecg);
    case 5
        clean_ecg = comprehensive_ecg_denoising(ecg, fs);
end

% 4. 特征点检测 (可选)
if exist('noise_free', 'var')
    % 使用去噪后的信号进行QRS检测
    [qrs_amp_raw, qrs_i_raw] = pan_tompkin(clean_ecg, fs, 0);

    figure('Name', 'QRS波检测');
    plot(t, clean_ecg); hold on;
    plot(t(qrs_i_raw), clean_ecg(qrs_i_raw), 'ro');
    title('QRS波检测结果');
    xlabel('时间 (s)');
    ylabel('幅度');
    legend('ECG信号', 'R峰位置');
end

方法对比分析

去噪方法 优点 缺点 适用场景
基本滤波 实现简单,计算量小 对非平稳噪声效果差,可能扭曲QRS波 实时处理,硬件资源有限
小波变换 有效处理非平稳信号,保留特征点 小波基和阈值选择影响效果 临床分析,研究应用
自适应滤波 对工频干扰去除效果好,实时性强 需要参考信号,对其它噪声效果有限 工频干扰严重环境
EMD 完全自适应,无需预设参数 计算量大,端点效应问题 复杂噪声环境
综合方法 全面处理各类噪声,效果最优 实现复杂,计算量大 高精度医疗诊断

性能评估指标

  1. 信噪比(SNR):衡量信号与噪声的比例
    $$SNR = 10 \log_{10}\left(\frac{P_{\text{signal}}}{P_{\text{noise}}}\right)$$

  2. 均方根误差(RMSE):评估去噪信号与原始信号的差异
    $$RMSE = \sqrt{\frac{1}{N}\sum_{i=1}^{N}(x_i - \hat{x}_i)^2}$$

  3. 相关系数:评估波形相似度
    $$r = \frac{\sum_{i=1}^{N}(x_i - \bar{x})(\hat{x}_i - \bar{\hat{x}})}{\sqrt{\sum_{i=1}^{N}(x_i - \bar{x})^2}\sqrt{\sum_{i=1}^{N}(\hat{x}_i - \bar{\hat{x}})^2}}$$

实际应用建议

  1. 预处理

    • 使用高通滤波(0.5Hz)去除基线漂移
    • 应用工频陷波滤波器去除50/60Hz干扰
  2. 主去噪

    • 首选小波去噪(db6小波,5-6层分解)
    • 对肌电噪声严重信号,结合EMD方法
  3. 后处理

    • 使用移动平均平滑波形
    • 应用幅度归一化
  4. QRS检测

    • 使用Pan-Tompkins等算法检测R峰
    • 基于RR间期进行心律分析

结果示例

去噪性能评估:
信噪比(SNR): 18.76 dB
均方根误差(RMSE): 0.0234
相关系数: 0.9826

数据资源

  1. MIT-BIH心律失常数据库

    % 下载并加载MIT-BIH数据
    [signal, Fs, tm] = rdsamp('mitdb/100');
    ecg = signal(:,1); % 第一导联
    
  2. PTB诊断数据库

    % 访问PTB数据库
    ptb = load('ptbdb.mat');
    ecg = ptb.data(1).signal(:,1);
    fs = ptb.data(1).fs;
    
  3. 合成ECG生成

    % 生成模拟ECG信号
    fs = 360;
    t = 0:1/fs:10;
    ecg = ecg_simulation(t);
    

本文介绍的MATLAB心电信号去噪方法已在临床和研究中广泛应用,实际应用中需根据具体噪声特点和系统要求选择合适的方法组合。

相关文章
|
机器学习/深度学习 数据采集 PyTorch
使用PyTorch解决多分类问题:构建、训练和评估深度学习模型
使用PyTorch解决多分类问题:构建、训练和评估深度学习模型
使用PyTorch解决多分类问题:构建、训练和评估深度学习模型
|
开发工具 git
vscode编辑器里怎么显示.git隐藏文件夹到目录里
vscode编辑器里怎么显示.git隐藏文件夹到目录里
867 0
|
存储 监控 Linux
【Linux IO多路复用 】 Linux下select函数全解析:驾驭I-O复用的高效之道
【Linux IO多路复用 】 Linux下select函数全解析:驾驭I-O复用的高效之道
2564 0
|
JSON 测试技术 API
评测最火的 11 款 REST API GUI
尽管 RESTful Web 服务具有可扩展性且易于维护,但是手动进行 API 测试操作复杂,因此我们需要选择一些好用的客户端来帮助我们测试 REST API。这里,码匠为大家罗列了 11 款最火的用于 REST API 测试的客户端工具。
5535 1
评测最火的 11 款 REST API  GUI
|
1月前
|
人工智能 安全 Java
Spring AI 核心架构解析:构建企业级 AI 应用的 Java 新范式
Spring AI 为 Java 开发者提供企业级 AI 应用新范式,通过分层架构、统一抽象(如 ChatClient、PromptTemplate)与 Spring 生态深度集成,支持 RAG、函数调用、流式响应等核心功能,实现安全、可观测、可维护的智能系统构建。
498 8
|
10月前
|
存储 安全 虚拟化
Windows 11 绕过 TPM 方法总结,通用免 TPM 镜像下载 (2025 年 2 月更新)
Windows 11 绕过 TPM 方法总结,通用免 TPM 镜像下载 (2025 年 2 月更新)
520 0
Windows 11 绕过 TPM 方法总结,通用免 TPM 镜像下载 (2025 年 2 月更新)
|
监控 Python
推荐一些Python的内存分析工具。
【2月更文挑战第7天】【2月更文挑战第19篇】推荐一些Python的内存分析工具。
1663 1
|
机器学习/深度学习 人工智能 算法
ML.NET:一个.NET开源、免费、跨平台的机器学习框架
ML.NET:一个.NET开源、免费、跨平台的机器学习框架
693 2
|
机器学习/深度学习 TensorFlow 算法框架/工具
《池化技术:深度学习热点背后的神秘力量,探寻最大池化与平均池化如何引领图像革命》
【8月更文挑战第21天】池化技术是深度学习中关键的特征提取手段,通过下采样减少数据维度和计算量,同时保持核心特征。主要分为最大池化和平均池化:前者选取局部区域的最大值,保留显著特征并具平移不变性;后者计算区域平均值,平滑噪声并稳定输出。两者依据任务需求选择,如图像分类偏好最大池化以突出关键特征,而去噪任务则倾向平均池化以平滑图像。
339 0
|
机器学习/深度学习 存储 运维
ICML 2024:清华提出时间序列大模型:面向通用时序分析的生成式Transformer
【8月更文挑战第7天】在2024年ICML大会上,清华大学团队推出“时间序列大模型(LTSM)”——Timer,一种处理大规模时间序列数据的生成式Transformer。该模型通过预训练学习通用特征,支持多种任务如预测与异常检测。Timer采用统一的数据格式S3处理异构序列,并在数据稀缺场景下展现出色性能。尽管如此,模型泛化能力与计算效率仍有待优化。论文详情参见:https://arxiv.org/abs/2402.02368。
2805 4