深入浅出:ECG信号质量评估的6把尺子(s_sqi/k_sqi/p_sqi...)到底在量什么?
深入浅出:ECG信号质量评估的6把尺子(s_sqi/k_sqi/p_sqi...)到底在量什么?
当你在凌晨三点盯着监护仪上跳动的ECG波形时,是否想过这些曲线背后隐藏着怎样的质量密码?在可穿戴设备普及的今天,我们比任何时候都更需要一双"火眼金睛"来辨别信号的真伪。本文将带你拆解6种信号质量指标(SQI)的数学语言,看看它们如何像经验丰富的医生一样,从不同维度为ECG信号开出"体检报告"。
1. 信号质量的"体检套餐":六维度评估体系
ECG信号质量评估就像给心电图做全面体检,需要多指标联合诊断。这6种SQI指标可分为三大类:
| 评估维度 | 核心指标 | 诊断目标 |
|---|---|---|
| 信号分布形态 | s_sqi(偏度) | 检测信号不对称性 |
| k_sqi(峰度) | 识别异常尖峰 | |
| 频谱能量分布 | p_sqi(QRS功率谱) | 评估QRS波能量集中度 |
| bas_sqi(基线功率) | 检测基线漂移 | |
| 节律稳定性 | q_sqi(R波检测一致性) | 验证R波识别可靠性 |
| c_sqi(RR间期变异) | 分析心率变异性 |
临床研究表明,联合使用多维度SQI可使信号质量判断准确率提升至92%以上(李桥等,2007)
2. 形态学侦探:s_sqi与k_sqi的数学解剖
2.1 s_sqi:信号分布的"歪脖子"检测器
偏度(s_sqi)量化了信号分布的不对称程度。想象把ECG信号的幅值分布画成山峰:
- 理想状态:健康ECG的幅值分布近似对称(s_sqi≈0)
- 左偏状态:当存在肌电干扰时,负向波增多(s_sqi<0)
- 右偏状态:基线漂移常导致正向偏移(s_sqi>0)
def ssqi(ecg_signal): """计算信号偏度的核心代码""" num = np.mean((ecg_signal - np.mean(ecg_signal))**3) denom = np.std(ecg_signal, ddof=1)**3 return round(num/denom, 3)2.2 k_sqi:异常尖峰的"温度计"
峰度(k_sqi)测量的是分布曲线的"尖瘦"程度:
- 正常范围:健康ECG的峰度通常在3左右(经过-5校正后≈-2)
- 尖峰警报:当k_sqi显著增大时,可能提示:
- 工频干扰(50/60Hz窄带噪声)
- 电极接触不良导致的瞬态尖峰
- 运动伪迹引起的突发性波动
def ksqi(ecg_signal): """峰度计算中的Fisher校正""" kurtosis = np.mean((ecg_signal - np.mean(ecg_signal))**4) / np.std(ecg_signal, ddof=1)**4 return round(kurtosis - 3.0, 3) # 注意原始公式中的-5应为-3实际应用中,建议将s_sqi和k_sqi结合使用。当两者同时异常时,信号质量可信度会显著降低。
3. 频谱分析双雄:p_sqi与bas_sqi的频域探秘
3.1 p_sqi:QRS波的"能量雷达"
p_sqi通过计算5-15Hz(QRS主频带)与5-40Hz(全频带)的功率比,评估QRS波的显著性:
def psqi(ecg_signal, fs): n = len(ecg_signal) yf = np.fft.fft(ecg_signal) xf = np.linspace(0.0, 1.0/(2.0*(1/fs)), n//2) # QRS频带(5-15Hz)功率 pds_num = [np.abs(yf[i]) for i in range(len(xf)) if 5<=xf[i]<=15] # 全频带(5-40Hz)功率 pds_denom = [np.abs(yf[i]) for i in range(len(xf)) if 5<=xf[i]<=40] return round(sum(pds_num)/sum(pds_denom), 3)典型场景分析:
- 优质信号:p_sqi > 0.7(QRS能量高度集中)
- 运动伪影:p_sqi ≈ 0.3-0.5(能量分散到高频)
- 电极脱落:p_sqi < 0.1(无显著QRS能量)
3.2 bas_sqi:基线稳定的"守门员"
bas_sqi检测0-1Hz频段的功率占比,专门捕捉基线漂移:
def bassqi(ecg_signal, fs): n = len(ecg_signal) yf = np.fft.fft(ecg_signal) xf = np.linspace(0.0, 1.0/(2.0*(1/fs)), n//2) # 基线频带(0-1Hz)功率 pds_num = [np.abs(yf[i]) for i in range(len(xf)) if 0<=xf[i]<=1] # 全频带(0-40Hz)功率 pds_denom = [np.abs(yf[i]) for i in range(len(xf)) if 0<=xf[i]<=40] return round(1 - sum(pds_num)/sum(pds_denom), 3) # 值越小基线越差临床经验表明,当bas_sqi低于0.85时,建议:
- 检查电极接触阻抗
- 确认患者是否在移动
- 考虑启用数字滤波
4. 节律稳定性双因子:q_sqi与c_sqi的时域智慧
4.1 q_sqi:R波检测的"裁判员"
q_sqi采用两种R波检测算法(如Hamilton与SWT),通过交叉验证提升可靠性:
def qsqi(ecg_signal, fs): detectors = Detectors(fs) # 两种R波检测算法 qrs_swt = detectors.swt_detector(ecg_signal) qrs_hamilton = bsp_ecg.hamilton_segmenter(np.array(ecg_signal), fs)[0] # 计算匹配度 matching = 0 i = j = 0 while i<len(qrs_hamilton) and j<len(qrs_swt): if abs(qrs_swt[j]-qrs_hamilton[i]) < 50*(fs/1000): # 50ms容忍窗口 matching += 1 i += 1 j += 1 elif qrs_hamilton[i] < qrs_swt[j]: i += 1 else: j += 1 return round(2*matching/(len(qrs_hamilton)+len(qrs_swt)), 3)4.2 c_sqi:心率变异性的"显微镜"
c_sqi通过RR间期的变异系数(CV)反映节律稳定性:
def csqi(ecg_signal, fs): try: rri = bsp_ecg.hamilton_segmenter(np.array(ecg_signal), fs)[0] cv = np.std(rri, ddof=1)/np.mean(rri) return round(cv, 3) except: return 0.0 # 检测失败时返回最低分典型阈值参考:
| 临床状态 | c_sqi范围 | 可能原因 |
|---|---|---|
| 正常窦性心律 | 0.01-0.05 | 健康生理变异 |
| 房颤发作 | >0.15 | RR间期极度不规律 |
| 信号严重失真 | ≈0 | 检测算法失效 |
5. 实战中的组合拳:多指标联合决策
在Aura-healthcare的ecg_qc实现中,最终决策采用机器学习模型整合6种SQI。但我们可以通过简单规则实现基础判断:
def is_high_quality(s_sqi, k_sqi, p_sqi, bas_sqi, q_sqi, c_sqi): conditions = [ abs(s_sqi) < 0.5, # 偏度正常 -2.5 < k_sqi < 2.5, # 峰度合理 p_sqi > 0.6, # QRS能量集中 bas_sqi > 0.9, # 基线稳定 q_sqi > 0.8, # R波检测一致 0.01 < c_sqi < 0.1 # 适当心率变异 ] return sum(conditions) >= 5可穿戴设备中的典型优化策略:
- 动态权重调整:运动状态下提高p_sqi权重
- 级联检测:先检查bas_sqi排除基线问题
- 上下文感知:睡眠时放宽c_sqi阈值
