You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python的NeuroKit2库从ECG信号提取呼吸频率(BPM)求助

从ECG信号提取呼吸频率(BPM)的NeuroKit2实现问题

我尝试用NeuroKit2库从ECG信号中提取以呼吸次数/分钟(BPM)为单位的呼吸频率(RR),参考了ECG衍生呼吸(EDR)相关文档但对用法理解模糊,网上也没找到可参考的实际实现代码,自己写了一段代码但不确定是否正确,希望得到技术支持。

我编写的代码

import neurokit2 as nk
import numpy as np

ecg = nk.data('ecg_1000hz.csv')
sampling_rate = 1000

# 可视化信号
nk.signal_plot(ecg)

# 测试ecg_rsp()函数的所有可用方法  
method_name_lst = ["vangent2019", "sarkar2015", "charlton2016", "soni2019"]

# 清洗ECG信号以去除噪声,提高峰值检测精度
cleaned_ecg = nk.ecg_clean(ecg_signal=ecg, sampling_rate=sampling_rate, method="neurokit")

# 使用指定方法在ECG信号中查找R波峰值
rpeaks, info = nk.ecg_peaks(cleaned_ecg, sampling_rate=sampling_rate)

# 根据峰值序列计算信号速率(每分钟)
ecg_rate = nk.signal_rate(rpeaks, sampling_rate=sampling_rate, desired_length=len(rpeaks))

for method_name in method_name_lst:
    print("Method: {}\n".format(method_name))
  
    # 提取ECG衍生呼吸(EDR)
    resp_signal = nk.ecg_rsp(ecg_rate, sampling_rate=sampling_rate, method=method_name)

    # 清洗呼吸信号
    rsp_cleaned = nk.rsp_clean(resp_signal, sampling_rate=sampling_rate)

    # 计算呼吸频率
    rsp_rate_onsets = nk.rsp_rate(rsp_cleaned, sampling_rate=sampling_rate, method="trough")
    rsp_rate_xcorr = nk.rsp_rate(rsp_cleaned, sampling_rate=sampling_rate, method="xcorr")

    print("\tMean RR (Trough): {}\n".format(np.mean(rsp_rate_onsets)))
    print("\tMean RR (Xcorr): {}\n".format(np.mean(rsp_rate_xcorr)))

代码中的关键问题

  • ecg_rsp输入错误:nk.ecg_rsp()的正确输入是原始/清洗后的ECG信号,而非你传入的ecg_rate(心率序列)。多数EDR方法直接从ECG波形提取呼吸调制信号,不需要先计算心率。
  • 信号长度不匹配:nk.signal_rate()返回的ecg_rate长度远短于原始ECG信号,会导致后续衍生呼吸信号长度异常,影响频率计算准确性。
  • EDR信号清洗冗余:nk.rsp_clean()是为真实呼吸信号设计的,部分EDR方法输出的信号已处理过,额外清洗可能引入误差。

修正后的实现代码

import neurokit2 as nk
import numpy as np

# 加载数据
ecg = nk.data('ecg_1000hz.csv')
sampling_rate = 1000

# 1. 预处理ECG信号
cleaned_ecg = nk.ecg_clean(ecg, sampling_rate=sampling_rate)

# 2. 提取R波峰值(部分EDR方法需用到该信息)
rpeaks, _ = nk.ecg_peaks(cleaned_ecg, sampling_rate=sampling_rate)

# 测试所有EDR方法
method_list = ["vangent2019", "sarkar2015", "charlton2016", "soni2019"]

for method in method_list:
    print(f"=== 使用方法: {method} ===")
    
    # 3. 提取EDR信号:直接传入清洗后的ECG,部分方法自动调用R峰数据
    edr_signal, info = nk.ecg_rsp(cleaned_ecg, sampling_rate=sampling_rate, method=method, rpeaks=rpeaks)
    
    # 4. 计算呼吸频率
    rsp_rate_trough = nk.rsp_rate(edr_signal, sampling_rate=sampling_rate, method="trough")
    rsp_rate_xcorr = nk.rsp_rate(edr_signal, sampling_rate=sampling_rate, method="xcorr")
    
    # 输出平均呼吸频率(用nanmean排除异常值)
    print(f"平均呼吸频率(波谷法): {np.nanmean(rsp_rate_trough):.2f} BPM")
    print(f"平均呼吸频率(互相关法): {np.nanmean(rsp_rate_xcorr):.2f} BPM\n")

# 可选:可视化EDR信号与原始ECG对比
nk.signal_plot([cleaned_ecg, edr_signal], labels=["清洗后ECG", "EDR信号"], sampling_rate=sampling_rate)

关键说明

  • EDR方法逻辑:不同EDR方法实现逻辑不同,部分方法(如vangent2019)需要R峰辅助,nk.ecg_rsp()会自动处理,无需手动传入心率序列。
  • 频率计算注意:nk.rsp_rate()返回瞬时呼吸频率序列,用np.nanmean()计算平均值可排除异常值干扰。
  • 结果验证:若有同步真实呼吸信号,可对比EDR提取结果,选择最适配数据的EDR方法。

内容的提问来源于stack exchange,提问作者Nikolaos Sintoris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 20:13:22