ECG波形检查与分析系统

心电图(ECG)是诊断心血管疾病的重要工具,通过分析其波形特征可以识别多种心脏异常。

系统设计思路

  1. 波形识别:自动检测P波、QRS波群、T波等关键波形
  2. 特征提取:测量各波形的时间、幅度等关键参数
  3. 异常检测:识别常见心律失常和心肌缺血等异常模式
  4. 可视化分析:直观展示ECG波形和检测结果

MATLAB实现代码

matlab 复制代码
%% ECG波形检查与分析系统
% 功能: 自动分析ECG波形,检测异常模式

clear; clc; close all;

%% 1. 加载和预处理ECG数据
% 生成模拟ECG信号(实际应用中可替换为真实数据)
fs = 500;                  % 采样频率 (Hz)
t = 0:1/fs:10;             % 时间向量 (10秒)
ecg_clean = generateECG(t); % 生成基础ECG信号

% 添加噪声和干扰
noise = 0.05 * randn(size(ecg_clean));       % 高斯噪声
baseline_wander = 0.2 * sin(2*pi*0.1*t);     % 基线漂移
powerline_noise = 0.1 * sin(2*pi*50*t);      % 工频干扰
ecg_noisy = ecg_clean + noise + baseline_wander + powerline_noise;

% 设计带通滤波器 (0.5-40 Hz)
fc = [0.5 40];           % 截止频率
order = 4;               % 滤波器阶数
[b, a] = butter(order, fc/(fs/2), 'bandpass');
ecg_filtered = filtfilt(b, a, ecg_noisy);

%% 2. 波形检测算法
% R波检测 (Pan-Tompkins算法)
[qrs_peaks, r_locs] = detectRPeaks(ecg_filtered, fs);

% P波和T波检测
[p_waves, p_locs] = detectPWaves(ecg_filtered, r_locs, fs);
[t_waves, t_locs] = detectTWaves(ecg_filtered, r_locs, fs);

% 分割单个心跳周期
heartbeats = segmentHeartbeats(ecg_filtered, r_locs, fs);

%% 3. 特征提取
features = extractFeatures(ecg_filtered, r_locs, p_locs, t_locs, fs);

%% 4. 异常检测
abnormalities = detectAbnormalities(features, heartbeats, fs);

%% 5. 可视化结果
visualizeResults(t, ecg_filtered, r_locs, p_locs, t_locs, features, abnormalities, fs);

%% 6. 生成报告
generateReport(features, abnormalities);

%% ========== 核心函数实现 ==========

% 生成模拟ECG信号
function ecg = generateECG(t)
    % 基本参数
    heart_rate = 72; % 心率 (bpm)
    period = 60/heart_rate; % 心跳周期 (秒)
    
    % 创建基本波形
    ecg = zeros(size(t));
    for i = 1:length(t)
        phase = mod(t(i), period) / period; % 心跳相位 (0-1)
        
        % P波 (心房收缩)
        if phase >= 0.0 && phase < 0.15
            ecg(i) = 0.25 * sin(pi * (phase-0.0)/0.15);
        % QRS波群 (心室收缩)
        elseif phase >= 0.15 && phase < 0.25
            % Q波
            if phase < 0.17
                ecg(i) = -0.3 * sin(pi * (phase-0.15)/0.02);
            % R波
            elseif phase < 0.20
                ecg(i) = 1.5 * sin(pi * (phase-0.17)/0.03);
            % S波
            else
                ecg(i) = -0.5 * sin(pi * (phase-0.20)/0.05);
            end
        % T波 (心室舒张)
        elseif phase >= 0.35 && phase < 0.5
            ecg(i) = 0.35 * sin(pi * (phase-0.35)/0.15);
        end
    end
    
    % 添加随机变异
    ecg = ecg .* (0.9 + 0.2*rand(size(ecg)));
end

% R波检测 (Pan-Tompkins算法)
function [peaks, locs] = detectRPeaks(ecg, fs)
    % 1. 带通滤波 (5-15 Hz)
    f1 = 5; f2 = 15;
    [b, a] = butter(1, [f1 f2]/(fs/2), 'bandpass');
    ecg_filt = filtfilt(b, a, ecg);
    
    % 2. 微分
    diff_ecg = diff(ecg_filt);
    
    % 3. 平方
    sqr_ecg = diff_ecg.^2;
    
    % 4. 移动平均积分窗口 (150ms)
    window_size = round(0.15 * fs);
    integrated = movmean(sqr_ecg, window_size);
    
    % 5. 自适应阈值检测
    threshold = 0.2 * max(integrated);
    [peaks, locs] = findpeaks(integrated, 'MinPeakHeight', threshold, 'MinPeakDistance', round(0.3*fs));
    
    % 6. 二次验证
    valid_locs = [];
    for i = 1:length(locs)
        idx = locs(i);
        segment = ecg(max(1,idx-round(0.05*fs)):min(end,idx+round(0.05*fs)));
        if max(segment) > 0.5 * max(ecg)
            valid_locs = [valid_locs; idx];
        end
    end
    locs = valid_locs;
end

% P波检测
function [p_waves, p_locs] = detectPWaves(ecg, r_locs, fs)
    p_locs = [];
    p_waves = [];
    
    for i = 1:length(r_locs)
        % 在R波前200ms区域搜索
        search_start = max(1, r_locs(i) - round(0.2*fs));
        search_end = r_locs(i) - round(0.05*fs);
        if search_end <= search_start
            continue;
        end
        
        segment = ecg(search_start:search_end);
        [~, max_idx] = max(segment);
        candidate_loc = search_start + max_idx - 1;
        
        % 验证是否为P波 (幅度适中,宽度合理)
        amp = segment(max_idx);
        width = estimateWidth(ecg, candidate_loc, fs);
        
        if amp > 0.1 * max(ecg) && width < 0.12 * fs
            p_locs = [p_locs; candidate_loc];
            p_waves = [p_waves; segment(max_idx-5:max_idx+5)];
        end
    end
end

% T波检测
function [t_waves, t_locs] = detectTWaves(ecg, r_locs, fs)
    t_locs = [];
    t_waves = [];
    
    for i = 1:length(r_locs)
        % 在R波后200-400ms区域搜索
        search_start = r_locs(i) + round(0.2*fs);
        search_end = min(length(ecg), r_locs(i) + round(0.4*fs));
        if search_end <= search_start
            continue;
        end
        
        segment = ecg(search_start:search_end);
        [~, max_idx] = max(segment);
        candidate_loc = search_start + max_idx - 1;
        
        % 验证是否为T波 (幅度适中,宽度合理)
        amp = segment(max_idx);
        width = estimateWidth(ecg, candidate_loc, fs);
        
        if amp > 0.2 * max(ecg) && width > 0.1*fs && width < 0.2*fs
            t_locs = [t_locs; candidate_loc];
            t_waves = [t_waves; segment(max_idx-10:max_idx+10)];
        end
    end
end

% 估计波形宽度
function width = estimateWidth(ecg, loc, fs)
    half_amp = ecg(loc)/2;
    left = loc;
    right = loc;
    
    % 向左搜索半幅点
    while left > 1 && ecg(left) > half_amp
        left = left - 1;
    end
    
    % 向右搜索半幅点
    while right < length(ecg) && ecg(right) > half_amp
        right = right + 1;
    end
    
    width = right - left;
end

% 分割单个心跳周期
function heartbeats = segmentHeartbeats(ecg, r_locs, fs)
    heartbeats = {};
    pre_r = round(0.3*fs);  % 取R波前0.3秒
    post_r = round(0.5*fs); % 取R波后0.5秒
    
    for i = 1:length(r_locs)
        start_idx = max(1, r_locs(i) - pre_r);
        end_idx = min(length(ecg), r_locs(i) + post_r);
        heartbeat = ecg(start_idx:end_idx);
        heartbeats{i} = heartbeat;
    end
end

% 特征提取
function features = extractFeatures(ecg, r_locs, p_locs, t_locs, fs)
    features = struct();
    
    % 1. RR间期 (心率变异性)
    rr_intervals = diff(r_locs) / fs; % 秒
    features.mean_hr = 60 / mean(rr_intervals); % 平均心率 (bpm)
    features.sdnn = std(rr_intervals); % SDNN (ms)
    features.rmssd = sqrt(mean(diff(rr_intervals).^2)); % RMSSD (ms)
    
    % 2. P波特征
    if ~isempty(p_locs)
        p_amplitudes = arrayfun(@(loc) ecg(loc), p_locs);
        features.p_duration = mean(arrayfun(@(loc) estimateWidth(ecg, loc, fs), p_locs)) / fs; % 秒
        features.p_amplitude = mean(p_amplitudes); % mV
    else
        features.p_duration = NaN;
        features.p_amplitude = NaN;
    end
    
    % 3. QRS波群特征
    qrs_widths = arrayfun(@(loc) estimateWidth(ecg, loc, fs), r_locs);
    qrs_amplitudes = arrayfun(@(loc) ecg(loc), r_locs);
    features.qrs_duration = mean(qrs_widths) / fs; % 秒
    features.qrs_amplitude = mean(qrs_amplitudes); % mV
    
    % 4. T波特征
    if ~isempty(t_locs)
        t_amplitudes = arrayfun(@(loc) ecg(loc), t_locs);
        features.t_duration = mean(arrayfun(@(loc) estimateWidth(ecg, loc, fs), t_locs)) / fs; % 秒
        features.t_amplitude = mean(t_amplitudes); % mV
    else
        features.t_duration = NaN;
        features.t_amplitude = NaN;
    end
    
    % 5. ST段分析
    st_segments = [];
    for i = 1:length(r_locs)
        j = r_locs(i);
        st_start = j + round(0.08*fs); % J点后80ms
        st_end = j + round(0.12*fs);   % J点后120ms
        if st_end < length(ecg)
            st_segment = ecg(st_start:st_end);
            st_segments = [st_segments; mean(st_segment)];
        end
    end
    features.st_level = mean(st_segments); % ST段平均电平 (mV)
end

% 异常检测
function abnormalities = detectAbnormalities(features, heartbeats, fs)
    abnormalities = struct();
    
    % 1. 心律失常检测
    if features.sdnn > 0.15 % SDNN > 150ms 提示自主神经功能紊乱
        abnormalities.arrhythmia = '心率变异性增加 (SDNN > 150ms)';
    elseif features.rmssd < 0.02 % RMSSD < 20ms 提示副交感神经活性降低
        abnormalities.arrhythmia = '心率变异性降低 (RMSSD < 20ms)';
    else
        abnormalities.arrhythmia = '正常窦性心律';
    end
    
    % 2. 心肌缺血检测 (ST段压低或抬高)
    if features.st_level < -0.1 % ST段压低 > 0.1mV
        abnormalities.ischemia = 'ST段压低提示心肌缺血';
    elseif features.st_level > 0.2 % ST段抬高 > 0.2mV
        abnormalities.ischemia = 'ST段抬高提示急性心肌梗死';
    else
        abnormalities.ischemia = '无缺血迹象';
    end
    
    % 3. 心房异常检测 (P波异常)
    if features.p_duration > 0.12 % P波时限 > 120ms
        abnormalities.atrial_abnormality = 'P波增宽提示左心房扩大';
    elseif features.p_amplitude > 0.25 % P波振幅 > 0.25mV
        abnormalities.atrial_abnormality = 'P波高尖提示右心房扩大';
    else
        abnormalities.atrial_abnormality = 'P波正常';
    end
    
    % 4. 心室肥大检测 (QRS波群异常)
    if features.qrs_amplitude > 2.0 % QRS振幅 > 2.0mV
        abnormalities.ventricular_hypertrophy = 'QRS高电压提示左心室肥大';
    elseif features.qrs_duration > 0.12 % QRS时限 > 120ms
        abnormalities.ventricular_hypertrophy = 'QRS增宽提示束支传导阻滞';
    else
        abnormalities.ventricular_hypertrophy = 'QRS波群正常';
    end
    
    % 5. T波异常检测
    if features.t_amplitude < 0.1 || features.t_amplitude > 0.5
        abnormalities.t_wave_abnormality = 'T波振幅异常';
    elseif features.t_duration > 0.2 % T波时限 > 200ms
        abnormalities.t_wave_abnormality = 'T波增宽提示心肌损伤';
    else
        abnormalities.t_wave_abnormality = 'T波正常';
    end
end

% 可视化结果
function visualizeResults(t, ecg, r_locs, p_locs, t_locs, features, abnormalities, fs)
    figure('Position', [100, 100, 1200, 800]);
    
    % 1. 原始ECG信号
    subplot(3,1,1);
    plot(t, ecg, 'b');
    hold on;
    plot(t(r_locs), ecg(r_locs), 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r'); % R波
    plot(t(p_locs), ecg(p_locs), 'go', 'MarkerSize', 6, 'MarkerFaceColor', 'g'); % P波
    plot(t(t_locs), ecg(t_locs), 'mo', 'MarkerSize', 6, 'MarkerFaceColor', 'm'); % T波
    title('ECG波形分析');
    xlabel('时间 (秒)');
    ylabel('幅度 (mV)');
    legend('ECG信号', 'R波', 'P波', 'T波', 'Location', 'best');
    grid on;
    
    % 2. 放大单个心跳
    if ~isempty(r_locs)
        beat_idx = min(5, length(r_locs)); % 取第5个心跳或最后一个
        start_idx = max(1, r_locs(beat_idx) - round(0.3*fs));
        end_idx = min(length(ecg), r_locs(beat_idx) + round(0.5*fs));
        t_zoom = t(start_idx:end_idx) - t(start_idx);
        ecg_zoom = ecg(start_idx:end_idx);
        
        subplot(3,1,2);
        plot(t_zoom, ecg_zoom, 'b');
        hold on;
        if any(p_locs > start_idx & p_locs < end_idx)
            p_zoom = p_locs(p_locs > start_idx & p_locs < end_idx) - start_idx;
            plot(t_zoom(p_zoom), ecg_zoom(p_zoom), 'go', 'MarkerSize', 8, 'MarkerFaceColor', 'g');
        end
        if any(t_locs > start_idx & t_locs < end_idx)
            t_zoom = t_locs(t_locs > start_idx & t_locs < end_idx) - start_idx;
            plot(t_zoom(t_zoom), ecg_zoom(t_zoom), 'mo', 'MarkerSize', 8, 'MarkerFaceColor', 'm');
        end
        r_zoom = r_locs(beat_idx) - start_idx;
        plot(t_zoom(r_zoom), ecg_zoom(r_zoom), 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r');
        title('单个心跳放大');
        xlabel('时间 (秒)');
        ylabel('幅度 (mV)');
        grid on;
    end
    
    % 3. 特征参数和异常检测结果
    subplot(3,1,3);
    axis off;
    
    text(0.05, 0.95, 'ECG分析报告', 'FontSize', 14, 'FontWeight', 'bold');
    
    % 心率信息
    text(0.05, 0.85, sprintf('平均心率: %.1f bpm', features.mean_hr), 'FontSize', 12);
    text(0.05, 0.80, sprintf('心率变异性(SDNN): %.2f ms', features.sdnn*1000), 'FontSize', 12);
    text(0.05, 0.75, sprintf('RMSSD: %.2f ms', features.rmssd*1000), 'FontSize', 12);
    
    % 波形特征
    text(0.05, 0.65, sprintf('P波: 时限=%.3f s, 振幅=%.2f mV', features.p_duration, features.p_amplitude), 'FontSize', 12);
    text(0.05, 0.60, sprintf('QRS波群: 时限=%.3f s, 振幅=%.2f mV', features.qrs_duration, features.qrs_amplitude), 'FontSize', 12);
    text(0.05, 0.55, sprintf('T波: 时限=%.3f s, 振幅=%.2f mV', features.t_duration, features.t_amplitude), 'FontSize', 12);
    text(0.05, 0.50, sprintf('ST段水平: %.2f mV', features.st_level), 'FontSize', 12);
    
    % 异常检测结果
    text(0.05, 0.40, '异常检测结果:', 'FontSize', 12, 'FontWeight', 'bold');
    text(0.05, 0.35, ['心律: ' abnormalities.arrhythmia], 'FontSize', 11, 'Color', 'red');
    text(0.05, 0.30, ['缺血: ' abnormalities.ischemia], 'FontSize', 11, 'Color', 'red');
    text(0.05, 0.25, ['心房: ' abnormalities.atrial_abnormality], 'FontSize', 11, 'Color', 'red');
    text(0.05, 0.20, ['心室: ' abnormalities.ventricular_hypertrophy], 'FontSize', 11, 'Color', 'red');
    text(0.05, 0.15, ['T波: ' abnormalities.t_wave_abnormality], 'FontSize', 11, 'Color', 'red');
    
    % 添加图例说明
    annotation('textbox', [0.7, 0.15, 0.25, 0.2], 'String', ...
        {'图例:', '红点: R波', '绿点: P波', '紫点: T波'}, ...
        'FitBoxToText', 'on', 'BackgroundColor', 'white', 'FontSize', 10);
end

% 生成报告
function generateReport(features, abnormalities)
    fprintf('\n============== ECG分析报告 ==============\n');
    fprintf('平均心率: %.1f bpm\n', features.mean_hr);
    fprintf('心率变异性(SDNN): %.2f ms\n', features.sdnn*1000);
    fprintf('RMSSD: %.2f ms\n', features.rmssd*1000);
    fprintf('\n波形特征:\n');
    fprintf('  P波: 时限=%.3f s, 振幅=%.2f mV\n', features.p_duration, features.p_amplitude);
    fprintf('  QRS波群: 时限=%.3f s, 振幅=%.2f mV\n', features.qrs_duration, features.qrs_amplitude);
    fprintf('  T波: 时限=%.3f s, 振幅=%.2f mV\n', features.t_duration, features.t_amplitude);
    fprintf('  ST段水平: %.2f mV\n', features.st_level);
    fprintf('\n异常检测结果:\n');
    fprintf('  心律: %s\n', abnormalities.arrhythmia);
    fprintf('  缺血: %s\n', abnormalities.ischemia);
    fprintf('  心房: %s\n', abnormalities.atrial_abnormality);
    fprintf('  心室: %s\n', abnormalities.ventricular_hypertrophy);
    fprintf('  T波: %s\n', abnormalities.t_wave_abnormality);
    fprintf('=========================================\n');
end

ECG波形检查要点

1. P波分析

  • 位置:位于QRS波群之前
  • 时限:正常<120ms(3个小格)
  • 振幅:肢体导联<0.25mV,胸导联<0.2mV
  • 异常表现: 增宽:左心房扩大(二尖瓣狭窄) 高尖:右心房扩大(肺心病) 倒置:异位心房节律

2. PR间期分析

  • 正常范围:120-200ms(3-5个小格)
  • 异常表现: 延长:房室传导阻滞 缩短:预激综合征

3. QRS波群分析

  • 时限:正常60-100ms(1.5-2.5个小格)
  • 形态: Q波:时限<40ms,振幅<R波的1/4 R波:胸导联逐渐增高(V1-V5) S波:V1-V3导联可见
  • 异常表现: 增宽:束支传导阻滞 高电压:心室肥大 异常Q波:心肌梗死

4. ST段分析

  • 正常范围:等电位线,轻微偏移<0.1mV
  • 异常表现: 压低:心肌缺血 抬高:心肌梗死、心包炎

5. T波分析

  • 方向:通常与QRS主波同向
  • 振幅:一般>1/10 R波振幅
  • 异常表现: 低平/倒置:心肌缺血、低钾血症 高尖:高钾血症、心肌梗死超急性期

6. QT间期分析

  • 正常范围:<440ms(男性),<460ms(女性)
  • 异常表现: 延长:长QT综合征、药物作用 缩短:短QT综合征、高钙血症

参考代码 ECG的各种波形的检查 www.youwenfan.com/contentcsm/83596.html

常见异常ECG模式

1. 心律失常

  • 房颤:P波消失,代之以f波,RR间期绝对不规则
  • 室性早搏:宽大畸形QRS波群,提前出现
  • 房室传导阻滞: 一度:PR间期延长 二度:部分P波未下传 三度:P波与QRS波无关

2. 心肌缺血/梗死

  • 缺血:T波倒置,ST段压低
  • 损伤:ST段抬高
  • 坏死:出现异常Q波

3. 心房/心室肥大

  • 右心房肥大:P波高尖(肺型P波)
  • 左心房肥大:P波增宽(二尖瓣型P波)
  • 左心室肥大:RV5>2.5mV,RV5+SV1>4.0mV(男)
  • 右心室肥大:V1导联R/S>1,电轴右偏

4. 电解质紊乱

  • 高钾血症:T波高尖,QRS增宽,P波低平
  • 低钾血症:ST段压低,U波明显,T波低平
  • 高钙血症:QT间期缩短
  • 低钙血症:QT间期延长

临床应用价值

  1. 诊断价值: 识别心律失常类型 检测心肌缺血和梗死 评估心脏结构异常(心房/心室肥大) 监测电解质紊乱
  2. 预后评估: 预测心血管事件风险 评估治疗效果 监测疾病进展
  3. 筛查工具: 高血压筛查 隐匿性心脏病检测 运动员心脏评估
相关推荐
你们补药再卷啦1 天前
人工智能算法概览
人工智能·算法
cnxy1881 天前
围棋对弈Python程序开发完整指南:步骤3 - 气(Liberties)的计算算法设计
python·算法·深度优先
AndrewHZ1 天前
【图像处理基石】什么是光栅化?
图像处理·人工智能·算法·计算机视觉·3d·图形渲染·光栅化
小白菜又菜1 天前
Leetcode 944. Delete Columns to Make Sorted
算法·leetcode
我找到地球的支点啦1 天前
Matlab系列(006) 一利用matlab保存txt文件和读取txt文件
开发语言·算法·matlab
Dev7z1 天前
基于Matlab实现GRACE卫星重力数据的全球水储量变化估算与分析
人工智能·算法·matlab
爱喝热水的呀哈喽1 天前
11题目汇总
算法
三斗米1 天前
Transformer入门:一文读懂《Attention Is All You Need》
算法·架构
Swift社区1 天前
LeetCode 458 - 可怜的小猪
算法·leetcode·职场和发展
AI科技星1 天前
宇宙的像素:真空中一点如何编码无限星光
数据结构·人工智能·算法·机器学习·重构