PAT 通常用作动脉硬度的间接测量值或心血管健康的指标。它与各种生理和病理状况有关,例如高血压、动脉硬化和内皮功能障碍。

通过脉搏到达时间进行测量,简单来说就是 先从脉冲传输时间 PPG 数据集中提取数据,提取此数据集中每个对象的脉冲到达时间,再提取参考年龄,进行一些比较。
用的pulse transit time PPG数据集
22*3个数据记录了走跑坐
Bp_sys_start/end systolic blood pressure 收缩压
Bp_dia_start/end diastolic blood pressure 舒张压
Hr_1_start/end 测量开始时使用欧姆龙 HEM-7322 血压计测量的心率 (bpm)
Hr_2_start/end 测量开始时使用 iHealth Air 无线脉搏血氧仪测量的心率 (bpm)
spo2_start/end SpO2血氧饱和度

对于ecg和ppg信号,用neurokit2和wfdb库导入数据,
有一个需要注意的预处理操作是:
让ppg = -1*ppg,使ppg信号看起来更像血压信号。
再用neurokit2进行信号过滤,消除噪音
然后检测峰值:
ppg:

ecg:

对于峰值时间的检测,ppg和ecg略有区别:
ecg可以直接提取R 波的时间,它表示心室去极化的时间(促使心室收缩的电活动)。
ppg则一般不使用收缩峰时间,因为脉搏开始和收缩峰之间可能存在可变延迟,所以一般会用脉冲开始时间

def get_ppg_onsets(ppg, pks, fs):ons = np.empty(0)for i in range(len(pks) - 1):start = pks[i]stop = pks[i + 1]ibi = ppg[start:stop]aux_ons = np.argmin(ibi)ind_ons = aux_ons.astype(int)ons = np.append(ons, ind_ons + start)ons = ons.astype(int)return onsdef get_data(record_list,database_name,required_signals,required_duration,required_activity):matching_recs = {'dir': [], 'name': [], 'length': [], 'start_sbp': [], 'end_sbp': [], 'delta_sbp': [], 'age': []}for record in record_list:print('Record: {}'.format(record), end="", flush=True)record_data = wfdb.rdheader(record, pn_dir=database_name, rd_segments=True)# Check whether the required signals are present in the recordsigs_present = record_data.sig_nameif not all(x in sigs_present for x in required_signals):print('   (missing signals)')continueif not required_activity in record:print('   (not required activity)')continueseg_length = record_data.sig_len / (record_data.fs)if seg_length < required_duration:print(f' (too short at {seg_length / 60:.1f} mins)')continue# This record does meet the requirements, so extract information and data from it# Informationmatching_recs['dir'].append(database_name)matching_recs['name'].append(record_data.record_name)matching_recs['length'].append(seg_length)# Blood pressure measurementsstart_el = record_data.comments[0].index('<bp_sys_start>: ') + len('<bp_sys_start>: ')end_el = record_data.comments[0].index('<bp_sys_end>') - 1matching_recs['start_sbp'].append(int(record_data.comments[0][start_el:end_el]))start_el = record_data.comments[0].index('<bp_sys_end>: ') + len('<bp_sys_end>: ')end_el = record_data.comments[0].index('<bp_dia_start>') - 1matching_recs['end_sbp'].append(int(record_data.comments[0][start_el:end_el]))matching_recs['delta_sbp'].append(matching_recs['end_sbp'][-1] - matching_recs['start_sbp'][-1])# agesstart_el = record_data.comments[0].index('<age>: ') + len('<age>: ')end_el = record_data.comments[0].index('<bp_sys_start>') - 1matching_recs['age'].append(float(record_data.comments[0][start_el:end_el]))print('   (met requirements)')print(f"A total of {len(matching_recs['dir'])} out of {len(record_list)} records met the requirements.")return matching_recsdef get_pat(matching_recs,start_seconds,n_seconds_to_load,required_signals):subj_nos = [i for i in range(len(matching_recs['name']))]median_pats = []for subj_no in subj_nos:# specify this subject's record name and directory:record_name = matching_recs['name'][subj_no]record_dir = matching_recs['dir'][subj_no]# extract this subject's signalsrecord_data = wfdb.rdheader(record_name, pn_dir=record_dir, rd_segments=True)fs = record_data.fs# Specify timings of segment to be extractedsample_start = fs * start_secondssample_end = fs * (start_seconds + n_seconds_to_load)# Load segment datasegment_data = wfdb.rdrecord(record_name=record_name,channel_names=required_signals,sampfrom=sample_start,sampto=sample_end,pn_dir=record_dir)ppg_col = segment_data.sig_name.index("pleth_1")ppg_final = segment_data.p_signal[:, ppg_col]ecg_col = segment_data.sig_name.index("ecg")ecg_final = segment_data.p_signal[:, ecg_col]fs = segment_data.fsppg = -1 * ppg_final# filter signalsppg = nk2.ppg_clean(ppg, sampling_rate=fs)ecg = nk2.ecg_clean(ecg_final, sampling_rate=fs)# detect beats in signalsppg_clean = nk2.ppg_clean(ppg, sampling_rate=fs)ppg_peaks = nk2.ppg_findpeaks(ppg_clean, method="elgendi", show=False)['PPG_Peaks']ecg_clean = nk2.ecg_clean(ecg, sampling_rate=fs)ecg_signals, ecg_info = nk2.ecg_peaks(ecg_clean, method="neurokit", show=False)ecg_peaks = ecg_info["ECG_R_Peaks"]# obtain timingsecg_timings = ecg_peaksppg_timings = get_ppg_onsets(ppg, ppg_peaks, fs)# extract pulse arrival timesrel_ppg_timings = []for ecg_timing in ecg_timings:ppg_timings = np.asarray(ppg_timings)different = ppg_timings - ecg_timingdifferent = np.where(different > 0, different, 100000)idx = different.argmin()rel_ppg_timings.append(ppg_timings[idx])pats = (rel_ppg_timings - ecg_timings) / fs# find median pulse arrival time for this subjectcurr_median_pat = median(pats)median_pats.append(curr_median_pat)return median_patsdef get_age(matching_recs):ages = []subj_nos = [i for i in range(len(matching_recs['name']))]for subj_no in subj_nos:# specify this subject's record name and directory:record_name = matching_recs['name'][subj_no]record_dir = matching_recs['dir'][subj_no]# extract this subject's agecurr_age = matching_recs['age'][subj_no]ages.append(curr_age)return ages

分别比较走,跑,坐

PPG信号和ECG信号检测血管年龄相关推荐

  1. 一文详解光电容积图 (PPG) 和心电图 (ECG) 基本工作原理

      最近在做PPG和ECG相关的Sensor的驱动和应用的开发,在找资料的时候发现一篇解析得很详细且清晰的文章,故分享. 本文转载自:立锜科技电子报:ECG/PPG量测解决方案 0.摘要   本应用文 ...

  2. 【可穿戴算法开发】-基于PPG信号的血氧与血压检测模型

    文章目录 1.血氧检测方法 (1) 测量原理 0 检测原理 (2)标定试验 (3)基于线性回归的特征值R提取算法 (4)基于移动平均的特征值提取算法 2.血压监测方法 (1)原理 (2)计算公式 3. ...

  3. 检测PPG信号的峰值

    基于大佬的代码. PPG信号靠心率 (HR) 进行估计,主要取决于收缩压峰值检测的准确性.与 ECG 不同,PPG 信号形式简单和特定点 少.低振幅 PPG 信号更容易受到噪声污染和其他不良影响的影响 ...

  4. 一种基于神经网络的由PPG信号估计连续血压算法【翻译】

    一种基于神经网络的由PPG信号估计连续血压算法 摘要 由光体积描记(PPG)信号得到的血压和脉搏持续时间之间存在关系,但并不总是线性的.为了从PPG信号中估计血压,本文采用了人工神经网络(ann).训 ...

  5. 使用PPG信号计算脉率和血氧

    Github代码地址:https://github.com/hzzhangqf0558/SPO2_HR - PPG信号简介 脉搏波是心脏的搏动(振动)沿动脉血管和血流向外周传播而形成的.心脏是一个持续 ...

  6. matlab小波变换处理ECG信号,[Matlab]ECG信号处理常见问题

    1. 计算某变量(常表现为向量或矩阵)所占存储空间大小--多见于数据压缩 Let say a variable named as var1: inf=whos('var1'); % all infor ...

  7. 计算心率--基于ppg信号

    光学心率测量原理 http://blog.csdn.net/kh766200466/article/details/53898291

  8. ecg 幅度_心电图 (ECG) 与光电容积图 (PPG) 基本工作原理,如何测量?

    ECG/PPG量测解决方案 摘要 本应用文件介绍了心电图 (ECG) 与光电容积图 (PPG) 的基本工作原理,讨论了ECG与PPG生理信号的量测,以及提高可靠性.实现高精度电气特性的难点.一般高精准 ...

  9. 光电容积脉搏波描记法PPG

    PPG 实时心率值可以反映一个人当时的心脏活动能力,进而从侧面衡量人体的健康状态.医院中测心率多采用心电图的方式,这在日常活动以及运动中是不便测量的,PRG( photoplethysmographi ...

最新文章

  1. SpringMVC传递multiple类型select后台Controller的接收方法
  2. string.Format 方法拼入{}
  3. 零基础python入门书籍-零基础学Python,不容错过的入门书籍
  4. 老板问:多长时间搞定?开发说3天,測试说2天,然后……
  5. 安利一下这个群投票的小程序,比较好用
  6. scp拷贝文件夹到另一个服务器目录中
  7. (63)FPGA二维数组(reg)
  8. to load JavaHL Library解决方法
  9. JavaScript GET 和 POST 请求的区别详解
  10. 获取用户上传的图片的本地路径实现方法,解决fakepath路径问题
  11. 微博大 V 用户画像与热点话题分析
  12. 二维码的制作之根据Excel数据批量制作二维码
  13. 无线专题 路由器和交换机、光猫的区别
  14. 基于STM32F103的液晶显示电子钟
  15. 微信小程序之在线任务发布与接单平台(2)
  16. C++编程规范 头文件格式 和 函数注释格式
  17. 如何专注?一个番茄钟就够了!
  18. Centos6 安装yum 完美安装(转载)
  19. GaussDB(DWS)介绍
  20. JS(Javascript)调用Android原生方法三步走

热门文章

  1. C语言基础之判断字符类型、字符串的数值转换、串长比较、数组指针、函数参数
  2. 【转】ssa/ass字幕格式全解析
  3. 时间管理的十大关键(zz)
  4. Xshell远程服务器tensorboard/visdom的本地可视化方法【亲测一步有效】
  5. QCefView源码优化
  6. mysql t.com_window系统上Apache PHP MySQL Tcomcat Resin整合 - Apache - 数安时代(GDCA)SSL证书官网...
  7. EasyExcel 学习笔记 - 读Excel
  8. 实验2:配置DHCPv6
  9. js阻止移动端下拉滑动效果
  10. linux安装glassfish