首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >基于MATLAB的心电信号去噪

基于MATLAB的心电信号去噪

原创
作者头像
用户4006703
发布2025-07-03 16:30:39
发布2025-07-03 16:30:39
2960
举报

基于MATLAB的心电信号去噪

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

噪声类型分析

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

MATLAB去噪方法

1. 基本滤波方法

代码语言:javascript
复制
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. 小波变换去噪

代码语言:javascript
复制
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. 自适应滤波

代码语言:javascript
复制
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)

代码语言:javascript
复制
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. 综合去噪流程

代码语言:javascript
复制
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

完整示例代码

代码语言:javascript
复制
%% 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)
  1. 均方根误差(RMSE):评估去噪信号与原始信号的差异
RMSE = \sqrt{\frac{1}{N}\sum_{i=1}^{N}(x_i - \hat{x}_i)^2}
  1. 相关系数:评估波形相似度
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}}

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基于MATLAB的心电信号去噪
    • 噪声类型分析
    • MATLAB去噪方法
      • 1. 基本滤波方法
      • 2. 小波变换去噪
      • 3. 自适应滤波
      • 4. 经验模态分解(EMD)
      • 5. 综合去噪流程
    • 完整示例代码
    • 方法对比分析
    • 性能评估指标
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档