心电图(ECG)是诊断心血管疾病的重要工具,通过分析其波形特征可以识别多种心脏异常。
系统设计思路
- 波形识别:自动检测P波、QRS波群、T波等关键波形
- 特征提取:测量各波形的时间、幅度等关键参数
- 异常检测:识别常见心律失常和心肌缺血等异常模式
- 可视化分析:直观展示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间期延长
临床应用价值
- 诊断价值: 识别心律失常类型 检测心肌缺血和梗死 评估心脏结构异常(心房/心室肥大) 监测电解质紊乱
- 预后评估: 预测心血管事件风险 评估治疗效果 监测疾病进展
- 筛查工具: 高血压筛查 隐匿性心脏病检测 运动员心脏评估