ecg-qc实现ECG信号质量评估

ecg-qc工具包实验ECG信号质量评估

参考

https://blog.csdn.net/weixin_61539900/article/details/124777025?spm=1001.2014.3001.5502

一 下载

尝试用pip install ecg_qc,但是导入包一直不成功

所以从github直接下载,下载地址如下

https://github.com/Aura-healthcare/ecg_qc

二 使用方法

对于源码的说明文档来自如下链接

可以参考原说明文档,也可以按照本篇分享内容进行

https://aura-healthcare.github.io/ecg_qc/index.html
1、下载后解压用pycharm打开,文件目录如下

在这里插入图片描述

2、在ecg_qc_main下新建python文件在这里插入图片描述
3、可以计算的SQI类型

SQI(Signal Quality Indicator)是指信号质量指标,可以反映信号的质量好坏。ecg_qc中使用的有q_sqi、c_sqi、s_sqi、k_sqi、p_sqi、bas_sqi。

根据对信号的处理方式,六种SQI可以进行如下分类。

分类SQI类型
基于频率分布s_sqi(偏度)
k_sqi(峰度)
基于功率谱p_sqi(QRS的功率谱分布)
bas_sqi(基线的相对功率)
基于RR间期q_sqi(基于两种R波检测算法)
c_sqi(基于噪声或伪影对RR间期分布的影响)
对六种SQI的说明
(1)s_sqi

s_sqi:基于ECG信号频率偏度的SQI。

偏度(Skewness)是衡量一个信号分布在其平均值周围的不对称性。它可以是负的、零或正的。当频率主要分布在左侧时,偏度值为负;频率主要分布在右侧时,偏度值为正。关于中心线对称时,偏度值为0。
在这里插入图片描述
定义如下:其中 μ x , σ \mu_x,\sigma μx,σ分别表示信号的均值和方差。
s _ s q i = E { ( x − μ x ) 3 } σ 3 s\_sqi=\frac{E\{(x-\mu_x)^3\}}{\sigma^3} s_sqi=σ3E{(xμx)3}
代码实现

def ssqi(ecg_signal: list) -> float:
    num = np.mean((ecg_signal - np.mean(ecg_signal))**3)
    s_sqi = num / (np.std(ecg_signal, ddof=1)**3)
    s_sqi_score = float(round(s_sqi, 3))
    return s_sqi_score
(2)k_sqi

k_sqi:基于ECG信号峰度的SQI。表征的是在平均值处峰值高低的指标,反映地是峰部的尖度。

峰度(Kurtosis)= 信号的四阶矩( ν 4 \nu_4 ν4)。
在这里插入图片描述
定义如下:其中 μ x , σ \mu_x,\sigma μx,σ分别表示信号的均值和方差。

k _ s q i = E { ( x − μ x ) 4 } σ 4 − 5 k\_sqi=\frac{E\{(x-\mu_x)^4\}}{\sigma^4}-5 k_sqi=σ4E{(xμx)4}5
代码实现

def ksqi(ecg_signal: list) -> float:
    num = np.mean((ecg_signal - np.mean(ecg_signal))**4)
    k_sqi = num / (np.std(ecg_signal, ddof=1)**4)
    k_sqi_fischer = k_sqi - 5.0
    k_sqi_score = float(round(k_sqi_fischer, 3))
    return k_sqi_score
(3)p_sqi

p_sqi:计算的是ECG信号中QRS波的频率谱分布。

即QSR波和全部ECG信号的功率比值。QRS波的功率集中在5-15Hz,ECG信号集中在5-40Hz。如果存在干扰,则高频的信号数量增加,则p_sqi的值会减小。(这里的频率范围可以根据ECG信号本身的情况设置为其他值)

代码实现

def psqi(ecg_signal: list, sampling_frequency: int) -> float:
    n = len(ecg_signal)
    t = 1 / sampling_frequency

    yf = np.fft.fft(ecg_signal)
    xf = np.linspace(0.0, 1.0/(2.0*t), n//2)

    pds_num = [np.abs(yf[idx]) for idx in range(len(xf)) if
               xf[idx] >= 5 and xf[idx] <= 15]
    pds_denom = [np.abs(yf[idx]) for idx in range(len(xf)) if
                 xf[idx] >= 5 and xf[idx] <= 40]
    p_sqi_score = float(np.round(sum(pds_num) / sum(pds_denom), 3))

    return p_sqi_score
(4)bas_sqi

bas_sqi:基于基线功率谱的SQI。

与p_sqi相似,计算的是基线与整体ECG信号的功率比值。这里的基线功率范围取在0-1Hz,ECG信号的功率范围取在0-40Hz。如果没有基线漂移,则bas_sqi接近于1,如果存在基线漂移,则bas_sqi值减小。

代码实现

def bassqi(ecg_signal: list, sampling_frequency: int) -> float:
    n = len(ecg_signal)
    t = 1 / sampling_frequency

    yf = np.fft.fft(ecg_signal)
    xf = np.linspace(0.0, 1.0/(2.0*t), n//2)

    pds_num = [np.abs(yf[idx]) for idx in range(len(xf)) if
               xf[idx] >= 0 and xf[idx] <= 1]
    pds_denom = [np.abs(yf[idx]) for idx in range(len(xf)) if
                 xf[idx] >= 0 and xf[idx] <= 40]

    bas_sqi_score = float(np.round(1 - (sum(pds_num) / sum(pds_denom)), 3))

    return bas_sqi_score
(5)c_sqi

c_sqi:根据ECG信号的可变性来衡量。首先使用biosppy模块对ECG信号进行R峰识别,然后对识别出来的R峰计算变异系数,即标准差除以均值。

代码实现

def csqi(ecg_signal: list, sampling_frequency: int) -> float:
    with np.errstate(invalid='raise'):

        try:

            rri_list = bsp_ecg.hamilton_segmenter(
                    signal=np.array(ecg_signal),
                    sampling_rate=sampling_frequency)[0]

            c_sqi_score = float(np.round(
                np.std(rri_list, ddof=1) / np.mean(rri_list),
                3))

        except Exception:
            c_sqi_score = 0

        return c_sqi_score

(6)q_sqi

q_sqi:使用两种不同的ECG的R峰检测算法,计算两种算法识别出来的R峰算法的匹配程度。

计算公式:其中 R 1 、 R 2 、 m a t c h e d R R_1、R_2、matched_R R1R2matchedR分别表示R峰算法1检测出的R峰个数,R峰算法2检测出的R峰个数、两个检测算法检测到的同样的R峰个数。
q _ s q i = 2 ∗ m a t c h e d R R 1 + R 2 q\_sqi = \frac{2*matched_R}{R_1+R_2} q_sqi=R1+R22matchedR

代码实现

def qsqi(ecg_signal: list, sampling_frequency: int) -> float:
    detectors = Detectors(sampling_frequency)
    qrs_frames_swt = detectors.swt_detector(ecg_signal)
    qrs_frames_hamilton = bsp_ecg.hamilton_segmenter(
            signal=np.array(ecg_signal),
            sampling_rate=sampling_frequency)[0]

    q_sqi_score = compute_qrs_frames_correlation(qrs_frames_hamilton,
                                                 qrs_frames_swt,
                                                 sampling_frequency)

    return q_sqi_score

def compute_qrs_frames_correlation(qrs_frames_1: list,
                                   qrs_frames_2: list,
                                   sampling_frequency: int,
                                   matching_qrs_frames_tolerance=50) -> float:

    single_frame_duration = 1/sampling_frequency

    frame_tolerance = matching_qrs_frames_tolerance * (
        0.001 / single_frame_duration)

    # Catch complete failed QRS detection
    if (len(qrs_frames_1) == 0 or len(qrs_frames_2) == 0):
        return 0

    i = 0
    j = 0
    matching_frames = 0

    while i < len(qrs_frames_1) and j < len(qrs_frames_2):
        min_qrs_frame = min(qrs_frames_1[i], qrs_frames_2[j])
        # Get missing detected beats intervals

        # Matching frames

        if abs(qrs_frames_2[j] - qrs_frames_1[i]) < frame_tolerance:
            matching_frames += 1
            i += 1
            j += 1
        else:
            # increment first QRS in frame list
            if min_qrs_frame == qrs_frames_1[i]:
                i += 1
            else:
                j += 1

    correlation_coefs = 2 * matching_frames / (len(qrs_frames_1) +
                                               len(qrs_frames_2))

    correlation_coefs = round(correlation_coefs, 3)

4、类、函数说明

我们需要调用的函数全部来自ecg_qc_mian/ecg_qc
以下是对一些函数的介绍

类名/函数名说明输入输出
ecg_qc.ecg_qc.class EcgQc计算一段ECG信号的六个SQI,并根据这些SQI通过训练好的模型得出信号质量结果model_file=‘训练好的模型名称或路径’, sampling_frequency: int = ECG信号频率, normalized: bool = ECG信号是否需要标准化信号质量:0或1
EcgQc.compute_sqi_scores(ecg_signal)根据一段ECG信号计算SQIECG信号根据输入的ECG得出的6个SQI值
EcgQc.get_signal_quality根据输入的ECG信号,通过训练好的模型预测得出信号质量ECG信号信号质量(0或1)
EcgQc.predict_quality根据SQI分数,通过训练好的模型预测信号质量ECG的六个SQI信号质量(0或1)

参考

1、李桥,俞梦孙. 重症监护病人心电导联信号质量评估[J]. 山东大学学报( 医学版) , 2007,45.
2、https://aura-healthcare.github.io/ecg_qc/index.html

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值