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. 筛查工具: 高血压筛查 隐匿性心脏病检测 运动员心脏评估
相关推荐
AI视觉网奇8 小时前
Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr
开发语言·c++·算法
智者知已应修善业8 小时前
【输入两个数字,判断两数相乘是否等于各自逆序数相乘】2023-10-24
c语言·c++·经验分享·笔记·算法·1024程序员节
Shingmc38 小时前
【Linux】进程控制
linux·服务器·算法
阿正的梦工坊9 小时前
DreamGym:通过经验合成实现代理学习的可扩展化
人工智能·算法·大模型·llm
小武~9 小时前
Leetcode 每日一题C 语言版 -- 45 jump game ii
c语言·算法·leetcode
行云流水6269 小时前
前端树形结构实现勾选,半勾选,取消勾选。
前端·算法
laocooon52385788610 小时前
一个C项目实现框架
c语言·算法
c#上位机11 小时前
halcon图像增强——图像取反
图像处理·算法·c#·halcon
zheyutao11 小时前
割点和桥
算法·图论