信息速览
这个数据集的名字直白得不留余地:Video Pulse Signals,视频脉搏信号。它把同一个人在同一个姿势下的两样东西放在一起,一样是从脸部视频里提出来的脉搏波形,另一样是同一时刻指尖上接触式传感器测出来的脉搏波形。两路信号并排放着,中间只差一个头文件里写着的秒数偏移。用一句话说清它的用处:给「不用接触皮肤、只靠摄像头就能读出脉搏」这条路提供最朴素的对照尺子。
它出自西班牙加泰罗尼亚理工大学两位研究者之手,2017 年 7 月挂上 PhysioNet,采用开放数据署名许可,任何人注册都不必就能整包下载,未压缩体量约 5.5 MB。规模很小,十五名健康志愿者、四十条记录,静息与运动各占一半。这个体量在当下动辄上千小时的视频生理数据集里显得单薄,但它出现的时间很早,早于绝大多数远程光电容积脉搏数据集,很多后来的方法仍在拿它做最初的对标。
需要提前说清一件最容易被误会的事:数据集里没有视频。它给的只是视频被咀嚼完之后剩下的那支波形,原始帧不在包内。这条边界贯穿全篇,也是判断「能不能用」的第一道门槛。一屏速览见下表。
| 维度 | 内容 |
|---|---|
| 正式名称 | Video Pulse Signals in Stationary and Motion Conditions |
| 发布平台 | PhysioNet,Database: Open Access |
| 版本与日期 | v1.0.0,2017-07-12 首发,校验文件更新至 2019-02-20 |
| DOI | 10.13026/C28D5M |
| 创建者 | A. Melchor Rodríguez、J. Ramos-Castro(UPC) |
| 采集地点 | 西班牙巴塞罗那,室内坐姿 |
| 受试者 | 15 名健康志愿者,12 男 3 女,23 至 35 岁 |
| 记录数 | 40 组脉搏记录,PhysioNet 列出 80 条记录名 |
| 每组的组成 | videopulse 视频脉搏一支 + fingerpulse 指尖脉搏参考一支 |
| 模态 | 可见光面部视频经处理后得到的单通道波形,非近红外、非热成像 |
| 参考链 | 接触式指尖脉搏传感器,1 kHz 采样 |
| 相机 | c1 为 Logitech 机型,15 fps;c2 为 GoPro 机型,59.94005994 Hz |
| 状态标签 | s 为静息,m 为运动,各受试者两种状态各一段 |
| 文件格式 | WFDB(.hea 头文件 + .dat 二进制数据),另附 README、RECORDS、SHA256SUMS |
| 未压缩体积 | 约 5.5 MB |
| 许可 | ODC-By 1.0,署名即可商用 |
| 缺失 | 无原始视频、无心电、无血压、无呼吸、无逐拍标注 |
§1 它要解决的具体麻烦
1.1 摄像头读脉搏这条路,缺的从来不是模型而是对照
从人脸视频里读出心跳,原理听上去简单:心脏每次搏动把血推出去,面部皮肤下的微血管随之胀落,皮肤对光的吸收量跟着周期性变化,相机把这个变化记录下来就是脉搏。难点全在量级上。这个光强变化常常只有千分之几,与传感器噪声、压缩失真、微小头动带来的位移处于同一数量级。任何一支号称能从视频读出脉搏的算法,都必须回答一个问题:你读出来的那条波形,究竟是真的脉搏,还是你把人脸晃动的节奏当成了心跳。
回答这个问题只有一条路,就是找一支可信的参考放在旁边。这个数据集做的就是这件事,而且做得极其朴素:不提供花哨的多模态融合,不提供上百种场景,只提供一对波形和它们之间的时间差。它的价值不在于规模,而在于它把「可比」这件事标准化了。每一组记录里,参考信号与视频信号采自同一时刻、同一人、同一姿势,唯一的变量是提取方式。
这也意味着它的定位更接近标尺而非矿藏。想训练一个大模型的人会嫌它太小,想做方法学对照的人会觉得刚刚好,因为对照实验最怕的就是除了要比较的那个因素之外,其他条件都在变。四十组记录把条件控制得很死,静息一组、运动一组、同一个人、同一把椅子,这在真实采集里反而是稀缺品。
放到时间轴上看得更清楚。2017 年之前,公开可用的面部视频脉搏数据屈指可数,多数论文的对照实验是在自家实验室里临时录的,别人无法复现。这个数据集把一小段这样的实验永久留在了公开网络上,代价是规模小,收益是任何人都能下载、都能复算、都能质疑。
1.2 三条常见的错误期待
第一条期待是「这是个视频数据集」。名字里的 Video 指的是信号来源,不是交付物。打开压缩包看到的是成对的 .hea 与 .dat,没有任何 mp4 或 avi。想做人脸检测、想做视频压缩鲁棒性、想做光照变化的端到端学习,这个包一步都帮不上。这是三个误解里最容易踩中的,因为数据集标题、主题标签与论文题目都在强调视频二字。
第二条期待是「它能替代脉搏血氧仪或心电做临床验证」。参考链只有指尖脉搏,没有心电,因此无法给出真正的逐搏心搏间期基准;脉搏波形本身受外周血管状态影响,与心电的 R-R 间期并不等价。把它当作心律分析的黄金标准会引入系统性偏差,尤其是房颤这类节律不齐的场景,脉搏波形根本无法忠实反映每一次心室激动。
第三条期待是「四十条记录可以做统计推断」。十五个人、每人两到四组,这样的样本量连分层都做不到。任何在这上面算出来的组间差异、性别差异、相机差异,置信区间都会宽到没有决策价值。它的正确用法是展示一种方法可行的证据,不是论证某种现象普遍存在。
1.3 它能给到的与给不到的
| 你的需求 | 它给的 | 够不够 |
|---|---|---|
| 验证「视频提取的脉搏与真实脉搏是否一致」 | 同人同刻的两路波形加时间偏移 | 够,这正是它的设计目的 |
| 训练端到端的视频到脉搏神经网络 | 只有波形,没有帧,没有配准信息 | 不够,缺最关键的输入端 |
| 测试算法在头动干扰下的鲁棒性 | 一组明确标注为运动状态的记录 | 勉强够,运动强度未量化,只有是与否 |
| 比较两款相机对提取质量的影响 | 前五名受试者有双机记录 | 部分够,只覆盖五人,且帧率不同步改变 |
| 分析脉搏率变异性指标 | 参考信号 1 kHz,足够精细 | 够,但需自行检测脉搏峰 |
| 做人群泛化或公平性评估 | 十五名年轻健康受试者 | 不够,人群极度集中 |
| 做跨设备、跨光照的域适应研究 | 两款机型、室内单一场景 | 不够,变量太少 |
| 教学演示摄像头测心率原理 | 体量小、格式标准、许可宽松 | 非常够,几分钟下完,脚本十来行能读 |
| 做临床心律不齐检测 | 无逐搏心电、无诊断标签 | 不适合,参考链本身不具备该能力 |
| 复现论文中的完整处理链 | 论文描述了面部检测与跟踪方法 | 部分够,需自行实现,视频不在包内 |
1.4 你的处境与它能帮到的事
| 你的处境 | 它能帮你什么 | 下一步该做什么 |
|---|---|---|
| 刚开始做远程光电容积脉搏,想找一份小样本摸清数据形态 | 提供最干净的成对波形,格式标准,十分钟能读懂 | 先用它跑通读文件、对齐、算相关性的最小闭环 |
| 已经有一套算法,想找一个外部小样本做定性验证 | 四十组非同源记录,可用于看趋势是否跨库成立 | 明确声明这只是示意性验证,样本量不足以下结论 |
| 要做可穿戴设备的工程质量评估 | 静息与运动两种状态的对照 | 另外找规模更大、含逐拍标注的库做主评估,这里只做辅助 |
| 需要训练数据但预算与算力都有限 | 体量极小,适合反复迭代调试流程 | 把它当冒烟测试集,训练仍要另找数据 |
| 在写教材或课程实验 | 许可宽松,可整包发给学生 | 直接分发 ZIP,配合 WFDB 工具链讲信号对齐 |
| 做多模态生理信号融合 | 只有脉搏两路,通道极少 | 另找含心电、呼吸、加速度的库做主体 |
| 想研究肤色与光照对提取的影响 | 未记录肤色,光照条件未描述 | 不适合,这个问题它答不了 |
1.5 一句话判断
它是一把尺子,不是一座矿。想量清楚「摄像头读出的脉搏准不准」,它够用;想靠它练出一个模型,它不够。
1.6 不适合谁:四条边界
第一条,不适合把视频当作输入的人。没有原始帧,就没有办法做人脸框回归、做感兴趣区域选择、做帧级质量筛选。所有以像素为起点的研究路线,在这个数据集上都无法开展,无论算法多先进。这条边界比其余三条更硬,因为它不是程度问题,而是有没有的问题。
第二条,不适合需要人群泛化结论的人。十五名二十出头的健康志愿者,男女比例失衡到十二比三,肤色、体型、病理状态全都没有覆盖。在这种样本上得到的任何「算法在真实人群中表现如何」的推论都站不住,这不是数据质量问题,而是抽样设计本身没有朝这个方向走。
第三条,不适合做节律诊断的人。参考是脉搏而非心电,脉搏波是心室激动经过血管传播之后的结果,中间隔着一层外周循环。房颤、早搏这类节律事件在脉搏波上会被平滑甚至丢失,拿它当心律标注的替代品会产生假阴性。想要节律基准,必须另找含心电的库。
第四条,不适合做大规模统计或基准排行的人。四十组记录分散在十五人身上,每人贡献两到四组,组间并不独立。把人当样本单位只有十五个,把组当样本单位又有严重的个体内相关。任何排名、显著性检验在这种结构下都会高估效力。
§2 数据构成与规格
2.1 目录只有一层,命名承担全部索引
整个包解压后是平铺的一层,没有子目录。文件总数有限,顶层有四个非记录文件:README.docx 是作者写的数据说明,RECORDS 是记录名清单,SHA256SUMS.txt 是校验值,另有一个平台自动生成的页面文件。其余全部是成对的 .hea 与 .dat。
这种扁平结构在当代数据集里几乎见不到了,但在这里是合理的。总量太小,任何分层都是多余的负担。使用者要做的第一件事往往不是遍历目录,而是读 RECORDS 拿到清单,再按文件名解析出四维坐标。文件名即元数据,这是这个数据集最显著的工程特征。
表:顶层非记录文件
| 文件名 | 作用 | 说明 |
|---|---|---|
| README.docx | 作者撰写的数据说明 | 含受试者构成、采集条件、命名规则、字段列表与致谢 |
| RECORDS | 记录名清单 | 每行一个记录名,不含扩展名 |
| SHA256SUMS.txt | 完整性校验 | 逐文件哈希,用于下载后核对 |
| 平台页面文件 | PhysioNet 自动生成 | 与数据内容无关 |
表:记录文件的两种角色
| 后缀 | 内容 | 典型体积 |
|---|---|---|
| .hea | 纯文本头文件,第一行为记录名、通道数、采样率、采样点数 | 一百二十字节到一百四十字节 |
| .dat | 二进制数据,16 位有符号整数按小端排列 | vid 约一点六 KB 到十三点四 KB,ref 约一百 KB 到二百 KB |
表:文件名四段编码
| 段位 | 取值 | 含义 |
|---|---|---|
| subj | 固定前缀 | 标记这是一条受试者记录 |
| x | 1 至 15 | 受试者编号 |
| y | s 或 m | s 为静息,m 为运动 |
| z | c1 或 c2 | c1 为 Logitech 机型,c2 为 GoPro 机型 |
| s | vid 或 ref | vid 为视频脉搏,ref 为指尖参考 |
这里有一处细微的命名不一致值得指出。作者在 README 中把记录名格式写作 subj_x_y_z,即三段;而数据主页与文件名实际使用四段,多出一段信号类型。两种写法并不冲突,因为一条逻辑记录本来就分成两路文件,README 描述的是逻辑记录,文件名承载的是物理文件。核对时以文件名为准即可,这一点已在 §7.3 展开。
2.2 字段与记录的完整字典
WFDB 头文件的格式极简:第一行是记录层级信息,第二行开始每个信号一行,最后可以有若干以井号开头的注释行。这个数据集的每条记录都是单通道,因此每个头文件只有两行核心内容加一行注释。
表:头文件第一行字段
| 位置 | 名称 | 本例取值 | 含义 |
|---|---|---|---|
| 1 | 记录名 | subj_10_s_c1_vid | 与文件名去扩展名后一致 |
| 2 | 通道数 | 1 | 一律为单通道 |
| 3 | 采样率 | 15、59.94005994 或 1000 | 视频与参考两套体系 |
| 4 | 采样点数 | 整数,从数百到七万余 | 决定信号长度 |
表:头文件第二行字段
| 位置 | 名称 | 本例取值 | 含义 |
|---|---|---|---|
| 1 | 数据文件名 | subj_10_s_c1_vid.dat | 对应的二进制文件 |
| 2 | 存储格式 | 16 | 16 位有符号整数 |
| 3 | 增益与基线 | 32767.0(0) | 满量程标定,原始值除以该数得到归一化幅度 |
| 4 | 分辨率 | 16 | 与存储位数一致 |
| 5 | 零值 | 0 | 基线偏移 |
| 6 | 首样本值 | 例如 -20679 | 数据文件的第一个整数 |
| 7 | 校验和 | 例如 16156 | WFDB 的校验字段 |
| 8 | 块长 | 0 | 未使用 |
| 9 | 信号名 | videopulse 或 fingerpulse | 全库仅有这两种 |
表:注释行字段
| 形式 | 出现范围 | 含义 |
|---|---|---|
| 井号 reference offset time 冒号 数值 | 多数记录 | 参考信号与视频信号之间的时间差,单位秒 |
| 无注释行 | 少数记录 | 未写入偏移,需自行估算 |
表:信号名与物理含义
| 信号名 | 出现于 | 物理含义 | 是否可直接当生理量使用 |
|---|---|---|---|
| videopulse | 所有 vid 记录 | 从面部视频提取的脉搏波形 | 归一化幅度,无物理单位 |
| fingerpulse | 所有 ref 记录 | 指尖传感器的接触式脉搏波形 | 归一化幅度,无物理单位 |
表:条件与相机编码的组合
| 条件 | 相机 | 是否出现 | 说明 |
|---|---|---|---|
| s 静息 | c1 | 是,十五人全有 | 主实验条件 |
| m 运动 | c1 | 是,十五人全有 | 头动干扰条件 |
| s 静息 | c2 | 是,仅前五人 | 双机对照 |
| m 运动 | c2 | 是,仅前五人 | 双机对照 |
表:单条记录的完整属性清单
| 属性 | 是否在文件中显式给出 | 备注 |
|---|---|---|
| 受试者编号 | 是,在文件名里 | 1 至 15 |
| 性别 | 否 | 只在数据集层面文字说明 |
| 年龄 | 否 | 只给出区间,无逐人值 |
| 采集条件 | 是,文件名 s 或 m | 二元标签 |
| 相机型号 | 是,文件名 c1 或 c2 | 对应 Logitech 与 GoPro |
| 帧率 | 是,头文件采样率 | 两款机型不同 |
| 时长 | 可折算,由采样点数除以采样率 | 未写入注释行 |
| 时间偏移 | 多数记录有 | 秒为单位,带三位小数 |
| 心搏位置 | 否 | 无逐拍标注 |
| 质量评分 | 否 | 无质量标签 |
2.3 一条记录的完整解剖
以 subj_10_s_c1_vid 为例,可以把一个实际文件的全部信息在几行之内读完。第一行声明这是单通道、15 Hz、共一千余个采样点的记录;第二行说明数据格式是 16 位整数、增益标定为满量程、信号名是 videopulse;末尾注释给出时间偏移。三行文本加上一段二进制,就是一条记录的全部。
subj_10_s_c1_vid 1 15 1032
subj_10_s_c1_vid.dat 16 32767.0(0)/NU 16 0 18026 14983 0 videopulse
#-- reference offset time: 3.723
与之配对的参考记录形状完全相同,只是采样率与采样点数不同:
subj_10_s_c1_ref 1 1000 63495
subj_10_s_c1_ref.dat 16 32767.0(0)/NU 16 0 -1433 61802 0 fingerpulse
#-- reference offset time: 3.723
两行注释里的偏移值一致,这是配对关系的直接证据。若某条记录缺失注释行,配对就失去程序可读的锚点,只能靠同一受试者、同一条件、同一相机的组合去猜,这种推断在需要精确对齐的场合并不可靠。
数据文件的读法也很直接:每个采样点占两个字节,按小端整数解析,再除以增益得到归一化幅度。由于没有物理单位,两路信号的绝对幅值不可比,能比的只有形状与相位。这也是为什么这个数据集上所有的方法比较最终都落在时序相关、相位差、峰值时刻偏差这类形状指标上,而不是落在绝对值上。
import numpy as np
import wfdb
rec = wfdb.rdrecord("subj_10_s_c1_vid", pn_dir="videopulse/1.0.0")
print(rec.record_name, rec.fs, rec.sig_len)
print(rec.sig_name, rec.units)
x = rec.p_signal[:, 0]
print(float(x.min()), float(x.max()))
t = wfdb.rdrecord("subj_10_s_c1_ref", pn_dir="videopulse/1.0.0")
print(t.fs, t.sig_len, t.comments)
这段代码不下载任何文件到本地,wfdb 会直接按目录名去 PhysioNet 取。输出的 comments 里就能看到那行偏移注释,字符串形式,需要自行解析数字。
2.4 记录层面的结构分布
研究这一节要看的不是统计量,而是结构。四十组记录在三个维度上分布:受试者、条件、相机。三个维度并不正交,因为相机维度只对前五人展开,这决定了任何一种按相机分组的分析都只能在五人子集内进行。
表:受试者与记录数
| 受试者编号 | 静息记录 | 运动记录 | 相机 | 记录组数 |
|---|---|---|---|---|
| 1 至 5 | 各一段 | 各一段 | c1 与 c2 兼有 | 每人四组 |
| 6 至 15 | 各一段 | 各一段 | 仅 c1 | 每人两组 |
表:按条件分组的记录数
| 条件 | 记录组数 | 说明 |
|---|---|---|
| 静息 s | 二十 | 十五人 c1 加前五人 c2 |
| 运动 m | 二十 | 同上 |
表:按相机分组的记录组数
| 相机 | 记录组数 | 涉及受试者 |
|---|---|---|
| c1 Logitech | 三十 | 全部十五人 |
| c2 GoPro | 十 | 仅前五人 |
表:采样率与信号类型的对应
| 信号类型 | 采样率 | 单位 | 采样点数范围量级 |
|---|---|---|---|
| vid 于 c1 | 15 Hz | 帧每秒 | 数百至一千二百 |
| vid 于 c2 | 59.94005994 Hz | 帧每秒 | 四千余至近七千 |
| ref | 1000 Hz | 次每秒 | 五万至七万五千 |
表:头文件时长的实际分布区间
| 记录类型 | 时长下界量级 | 时长上界量级 | 官方口径 |
|---|---|---|---|
| ref | 五十秒 | 七十五秒 | 说明为每段取五十秒 |
| vid 于 c1 | 五十五秒 | 八十秒 | 同上 |
| vid 于 c2 | 七十七秒 | 一百一十四秒 | 同上 |
这张表值得停一下。官方文字说每段取五十秒以统一长度,但头文件按采样点数折算出来的时长跨度很大,短的五十一秒,长的一百一十四秒。这不是矛盾,而是两套口径:五十秒可能是作者在做变异性分析时截取的窗口,而文件里存的是更长的原始导出段。正确做法是把它记为「存在两个口径」,差额构成官方未说明的部分,不要据此断言官方数字有误。
2.5 与同类资源的字段差异
把三个同样围绕脉搏的数据集放在一起看字段,能更清楚这个库的取舍。三者分别是 PhysioNet 上的另一个指尖脉搏库、一个手机摄像头脉搏库,以及一份手指按压式脉搏数据库。
表:字段级横向对照
| 维度 | VideoPulse | 手机摄像头脉搏库 | 手指按压式脉搏库 |
|---|---|---|---|
| 采集器件 | 面部相机,远离皮肤 | 手机摄像头贴皮肤 | 专用指夹或贴片 |
| 是否提供原始视频 | 否 | 否 | 否 |
| 参考信号 | 指尖脉搏 1 kHz | 参考心电 | 另行记录 |
| 逐拍标注 | 无 | 有 | 视子库而定 |
| 条件控制 | 静息与运动二元 | 多种日常动作 | 多种生理状态 |
| 规模 | 四十组 | 数千条 | 数百至上千条 |
| 许可 | ODC-By 1.0 | 多为 CC BY 类 | 公开 |
表:这个库在字段上的独有之处
| 字段 | 独有性 | 对使用的意义 |
|---|---|---|
| 相机型号编码写在文件名里 | 少见 | 可做跨机型对照,无需另建映射表 |
| 时间偏移写在头文件注释 | 罕见 | 对齐信息随数据走,不依赖外部文档 |
| 两路信号分成独立记录名 | 少见 | 便于单独加载,但也意味着配对要靠命名约定 |
| 信号名只有两种取值 | 常见 | 解析器可以写死,无需通用化 |
最后一条看似是缺点,实则是这个库的工程优势。信号名固定为 videopulse 与 fingerpulse,意味着读数据的代码可以极度简化,不需要处理任意通道名。对于要做冒烟测试或教学演示的场合,这种约束降低了入门门槛。
§3 它在方法谱系里的位置
3.1 从「证明可行」到「证明可靠」的中间态
任何一项生理测量技术大致会经历三个阶段。第一阶段是证明可行,即有人做出来并展示它给出的数字大致合理。第二阶段是证明可靠,即在足够多样的条件下、足够多的人身上,误差保持在可接受范围。第三阶段是进入标准,即成为临床或监管认可的测量方式。
远程光电容积脉搏目前整体处于第一阶段向第二阶段过渡的位置,而这个数据集是第一阶段末期的一份标本。它要回答的问题是「用摄像头读脉搏这件事,能不能做出与真实脉搏波形吻合的结果」,答案是能,作者用统计一致性给出了支持。它没有要回答「在什么条件下会失效」,因为条件只有静息与运动两种。
这个定位决定了它的使用方法。想验证一个新特征提取器是否比旧的更好,可以拿它做初步对照;想论证自己的方法在临床上可用,必须找第二阶段的数据集。用错阶段的库去回答后阶段的问题,是这类小样本库最常见的误用。
3.2 面部检测与跟踪这一支
作者在 2015 年的会议上给出的方法核心是面部检测加跟踪。思路是:先检测出人脸,再在脸上选一块感兴趣区域,通常落在额头或脸颊,因为这两处皮下血管丰富、皮肤相对平整、不易被表情牵动;然后逐帧跟踪这块区域,抵消头动;最后对区域内的像素做空间平均,得到一条随时间变化的光强序列,再从中滤出脉搏频段的成分。
跟踪这一步是这个数据集存在的理由。作者明确指出,视频脉搏信号受两个因素严重影响,一是人的移动,二是所选感兴趣区域的位置。这两个因素都会引入与心跳无关的低频或宽带扰动。传统做法是不跟踪,整帧取均值,一旦人稍微动一下,信号就被污染。加上跟踪之后,扰动被显著压制,波形与参考的对齐程度明显改善。
这条技术路线后来演化出许多分支,有的用肤色模型分割,有的用光流估计位移,有的用深度网络直接回归脉搏。但这个数据集只对应最早的那一支,且只保留了它的输出,中间过程全部不可见。使用时必须清楚这一点:它验证的是「跟踪之后能不能对上」,而不是「哪一种跟踪最好」。
3.3 脉搏率变异性这个落点
作者把落点选在脉搏率变异性,而非简单的心率数值。这个选择有讲究。心率是一个标量,只要数一分钟内有多少个峰就能得到,对波形的细节不敏感;变异性则要求每一个峰的位置都准确,任何一个峰的错位都会改变相邻间期,进而改变变异性指标。用变异性做对照,等于把比对标准从「大致对上」提高到「逐个对上」。
从自主神经评估的角度看,这个落点是合理的。心率变异性是评估交感与副交感平衡的常用指标,但采集心电需要电极,长期监测不便。如果能用摄像头得到等价的脉搏率变异性,居家监测的门槛会大幅下降。问题在于脉搏波经过血管传播后,逐搏间期会被平滑,高频成分衰减,因此脉搏率变异性与心率变异性在频域上并不完全等价。这个数据集提供了检验这种等价性的原始材料,但没有替使用者下结论。
3.4 与心电基准路线的分工
另一条路线是直接用视频估计心电,或者用心电作为参考来验证视频脉搏。两条路线的差别在于参考信号的性质。心电记录的是心脏电活动,逐搏间期是心室激动的直接反映;脉搏记录的是血容量的机械波动,逐搏间期是电活动经血管传导后的结果。
选择哪条参考路线,取决于要回答的问题。要评估节律,必须用心电;要评估波形形态与提取质量,脉搏参考已经足够,而且更容易在自然状态下采集。这个数据集选了后者,代价是失去节律分析的资格,收益是采集条件更贴近真实应用场景,毕竟居家监测时没人愿意贴电极。
表:两条参考路线的取舍
| 维度 | 以心电为参考 | 以脉搏为参考 |
|---|---|---|
| 逐搏间期的含义 | 心室激动间隔 | 血管搏动间隔 |
| 对节律不齐的敏感度 | 高 | 低 |
| 采集侵入性 | 需电极 | 仅需指尖接触 |
| 自然状态可行性 | 较低 | 较高 |
| 本数据集的归属 | 否 | 是 |
3.5 小样本库为何仍有引用价值
按今天的标准,十五个人、四十组记录、五点五兆字节,无论如何都算不上数据集。但它仍被引用,原因有三。第一是时间早,很多后续工作在文献综述里需要一个早期参照点,它比绝大多数同类库都早。第二是干净,没有复杂的目录结构,没有冗长的元数据表,没有隐藏的预处理,读进来就是两条波形。第三是许可宽松,署名即可用,不限制商用,避免了注册审批的摩擦。
这三点加起来,使它成为入门者第一个该拿来练手的目标,也是审稿人容易接受的一个中立对照源。引用价值不等于科研价值,但在实际使用中,前者往往决定了后者能否顺利展开。
§4 核心特色:信号本身的质量
4.1 两路信号的对齐是全部工作的前提
任何用到这个数据集的分析,第一步都是把两路信号摆到同一时间轴上。头文件给出的偏移值就是这一步的全部依据。偏移的含义是参考信号相对视频信号的时间差,单位秒,三位小数。若不校正就直接算相关系数,结果会被这个偏移彻底破坏,因为脉搏周期通常在零点六到一秒之间,一个几秒的偏移足以让两路信号完全反相。
校正的方向容易搞反。稳妥的做法是先用一小段数据做互相关,找出使两路信号最相似的平移量,再与头文件给出的值对照。若两者接近,说明理解正确;若差一个符号,说明方向反了,把平移量取反即可。这个过程在任何一个受试者身上跑一次,就能确定全库的约定。
表:偏移处理的三种情形
| 情形 | 表现 | 处理方式 |
|---|---|---|
| 头文件有偏移且方向正确 | 校正后相关系数明显上升 | 直接采用 |
| 头文件有偏移但方向理解相反 | 校正后相关系数下降 | 平移量取反 |
| 头文件无偏移 | 无锚点 | 用互相关自行估计,并在方法中声明 |
4.2 案例:subj_1_s_c1_vid 记录组的四组形态
选第一条受试者记录 subj_1_s_c1_vid 作为贯穿全篇的样本,是因为只有他同时具备静息与运动、c1 与 c2 四种组合,四组记录构成了一个完整的小型析因设计。这个案例在后面几节还会被反复引用。
第一组是静息条件下的 c1 记录。参考信号采样点约六万二千余,折合约六十二秒;视频信号一千一百余点,按 15 Hz 折算约七十五秒。两者长度不同,偏移约六点七秒。这一组是四组里最干净的,因为静息状态下头动最少,跟踪几乎不费力。
第二组是运动条件下的 c2 记录。视频信号五千余点,按略高于五十九点九四赫兹折算约八十四秒;参考信号近六万七千点,约六十七秒。偏移约十二点三秒,比静息组大得多。这一组最能体现运动条件下的困难,也最能说明为什么需要把两种状态分开存放。
第三组与第四组是同一受试者用另一台相机拍的对应记录,帧率不同,采样点数相差近五倍。把 c1 与 c2 的同条件记录放在一起,可以直接看到帧率对波形密度的影响:低帧率下每搏的采样点很少,峰值位置的分辨率受限,这是低帧率设备固有的代价。
import numpy as np
import wfdb
def load_pair(name):
vid = wfdb.rdrecord(f"{name}_vid", pn_dir="videopulse/1.0.0")
ref = wfdb.rdrecord(f"{name}_ref", pn_dir="videopulse/1.0.0")
return vid, ref
for cond in ["s", "m"]:
for cam in ["c1", "c2"]:
try:
v, r = load_pair(f"subj_1_{cond}_{cam}")
except Exception as e:
print(cond, cam, "缺记录", type(e).__name__)
continue
print(cond, cam, v.fs, v.sig_len, r.sig_len, r.comments)
这段代码跑完会打印四行,第五、第六种组合若尝试会被异常捕获,因为该受试者没有其他组合。这正是 §4.2 的案例在代码层面的呈现:组数不是随意的,而是由设计决定。
4.3 归一化幅度带来的可比性限制
所有信号的增益都标定为满量程,意味着无论原始电压是多少,落到文件里都被拉伸到 16 位整数能表示的范围内。这样一来,同一个人不同时间的记录之间、不同人之间的记录之间,绝对幅度完全不可比。两路信号的幅度也不可比,因为视频脉搏是像素亮度变化的加权和,指尖脉搏是透射光强的变化,两者的物理来源根本不同。
这个限制听起来严重,实际影响有限,因为在脉搏分析里绝大多数指标都是形状无关幅度的:峰值时刻、间期、波形相似度、频域相对功率,都不依赖绝对幅度。真正受影响的是需要幅度比值的指标,比如脉搏波的灌注指数、上升支斜率与下降支斜率之比。这些指标在这个数据集上算出来只在单条记录内部有意义。
表:幅度相关指标在库内可用性
| 指标 | 是否需绝对幅度 | 库内可用性 |
|---|---|---|
| 峰值时刻 | 否 | 可用 |
| 逐搏间期 | 否 | 可用,需先检测峰 |
| 波形相关性 | 否 | 可用 |
| 频域相对功率 | 否 | 可用 |
| 灌注指数类比值 | 是 | 仅单条记录内可比 |
| 上升支斜率 | 是 | 仅单条记录内可比 |
| 跨受试者幅度比较 | 是 | 不可用 |
4.4 运动条件到底动了什么
官方把条件分为静息与运动两种,但运动具体指什么,页面没有细说。从记录规模与偏移量看,运动组的偏移明显更大,说明视频与参考的起始时刻差得多,这与采集流程在运动状态下更容易出现不同步的实际情况吻合。但头部摆动的幅度、频率、方向都没有定量描述。
这意味着运动组只能当作一个定性的干扰标签使用。想研究「多大头动会让提取失效」,这个数据集答不了,因为它只有一个运动水平。想验证「算法在有干扰时是否还工作」,它够用,因为至少存在一个非静息的条件可供对比。
表:两种条件的可比与不可比
| 比较项 | 可否比较 | 说明 |
|---|---|---|
| 静息与运动之间 | 可作定性比较 | 唯一控制的变量是干扰有无 |
| 运动强度分级 | 不可 | 无量化 |
| 不同受试者的运动组之间 | 弱可比 | 干扰程度未知 |
| 同受试者两相机之间 | 可 | 案例受试者具备该条件 |
4.5 参考链的精度上限
参考信号以 1 kHz 采样,这个采样率对于脉搏波形绰绰有余,脉搏的主要能量集中在零点五到五赫兹,千赫兹采样意味着每搏有数百个采样点,峰值定位精度可达毫秒级。因此参考端的精度不是瓶颈。
瓶颈在视频端。案例受试者的 c1 记录只有 15 Hz,每搏大约有十几个采样点,峰值定位的量化误差在数十毫秒量级。在计算逐搏间期时,这种误差会直接进入间期序列,而且相邻两搏的误差方向可能相反,导致间期估计的抖动被放大。这是低帧率设备的物理限制,任何算法都无法完全消除。
表:两路信号的精度对照
| 环节 | 采样率 | 峰值定位精度量级 | 是否瓶颈 |
|---|---|---|---|
| 参考指尖脉搏 | 一千赫兹 | 毫秒级 | 否 |
| 视频于 c1 | 十五赫兹 | 数十毫秒 | 是 |
| 视频于 c2 | 约五十九点九四赫兹 | 十几毫秒 | 较轻 |
§4.2 的案例里,四组记录恰好分处两档帧率,可以直接把这条解释当成对照:若同一方法在 c2 上显著更好,先排除量化误差再谈设备优势。
这张表解释了一个常见现象:同一支算法在 c2 记录上往往表现更好。原因未必是算法更适配 GoPro,而可能仅仅是因为高帧率减少了量化误差。比较两款相机的记录时,必须把这一层考虑进去,否则会把采样率的红利误记为设备的优势。
§5 怎么拿到、怎么读、怎么算
5.1 三种下载方式与体量判断
整包下载有现成路径。第一种是浏览器直接点 ZIP,适合一次性使用。第二种是递归抓取整个目录,适合要长期保留本地副本的场合。第三种是从云端对象存储同步,适合在服务器上批量处理。
wget -r -N -c -np https://physionet.org/files/videopulse/1.0.0/
由于总量只有几兆,任何方式都在数秒内完成。这也意味着不必纠结下载策略,随便选一种即可。
aws s3 sync --no-sign-request s3://physionet-open/videopulse/1.0.0/ ./videopulse
云同步路径不需要任何凭证,开放存储桶可直接读取。若所在环境无法访问外网对象存储,退回第一种方式即可。
表:三种获取方式的取舍
| 方式 | 适用场景 | 是否需要额外工具 |
|---|---|---|
| ZIP 直下 | 一次性分析 | 否 |
| 递归抓取 | 长期本地副本 | 需 wget |
| 云同步 | 服务器批处理 | 需命令行客户端 |
| 库内直读 | 不落盘的快速实验 | 需 WFDB 客户端 |
5.2 不落盘直接读
对于这个体量,最省事的做法是不下载。WFDB 的 Python 客户端支持按目录名在线读取,内部会把文件取到本地缓存。第一次调用有网络延迟,之后走缓存就很快。
import wfdb
rec = wfdb.rdrecord("subj_1_s_c1_ref", pn_dir="videopulse/1.0.0")
print(rec.record_name, rec.fs, rec.sig_len, rec.sig_name)
print(rec.p_signal.shape, rec.p_signal.dtype)
print(rec.comments)
返回对象的 p_signal 是已经按增益换算过的浮点数组,形状为采样点数乘通道数。由于是单通道,取第零列即可。comments 是一个字符串列表,偏移注释就在其中。
5.3 从 RECORDS 枚举全库
要遍历全部记录,正确入口是 RECORDS 清单,而不是扫目录,因为清单是作者维护的权威列表。清单每行一个记录名,不含扩展名,读进来后按信号类型分类即可。
import wfdb
names = wfdb.get_record_list("videopulse", pn_dir="videopulse/1.0.0")
print(len(names))
vids = [n for n in names if n.endswith("_vid")]
refs = [n for n in names if n.endswith("_ref")]
print(len(vids), len(refs))
print(sorted(vids)[:3])
记录名总数与 vid、ref 两类各占一半,这是判断包是否完整的第一道自检。若某个名字既不以 vid 也不以 ref 结尾,说明命名与预期不符,需要停下来核对。
5.4 解析偏移并做对齐
偏移写在注释里,格式固定但需要解析。稳妥做法是用正则提取数字,取不到就返回空值,交给下游用互相关兜底。
import re
import numpy as np
def read_offset(rec):
pat = re.compile(r"offset time:\s*([0-9.]+)")
for c in rec.comments:
m = pat.search(c)
if m:
return float(m.group(1))
return None
def align(ref, vid, offset):
t_ref = np.arange(ref.sig_len) / ref.fs
t_vid = np.arange(vid.sig_len) / vid.fs + offset
lo = max(t_ref.min(), t_vid.min())
hi = min(t_ref.max(), t_vid.max())
return lo, hi
函数只做时间轴的重建与重叠区间计算,不做重采样。要真正把两路信号摆到一起,还需要把视频信号按参考的时间轴插值。这一步的顺序不能颠倒,先定重叠区间再插值,可以避免在无数据的地方凭空生成样本。
import numpy as np
def resample_to_video_grid(ref, vid, offset):
t_vid = np.arange(vid.sig_len) / vid.fs + offset
keep = (t_vid >= 0) & (t_vid < ref.sig_len / ref.fs)
t_keep = t_vid[keep]
y_keep = vid.p_signal[keep, 0]
t_ref = np.arange(ref.sig_len) / ref.fs
y_ref = np.interp(t_keep, t_ref, ref.p_signal[:, 0])
return t_keep, y_keep, y_ref
这段把参考信号插值到视频时刻上,返回三条等长序列,可直接算相关系数或画图。
5.5 计算一个最基本的吻合度指标
有了等长序列,最小可用指标是皮尔逊相关系数。它不看幅度,只看形状,正好契合前文说的归一化幅度限制。
import numpy as np
def corr(y1, y2):
a = y1 - y1.mean()
b = y2 - y2.mean()
denom = np.sqrt((a * a).sum() * (b * b).sum())
return float((a * b).sum() / denom)
这个数在静息记录上通常为正且不小,在运动记录上会明显下降。把它当定性指标看,不要当性能指标报,因为个体内部的高度相关不构成人群层面的证据。
5.6 本地批量处理的最小工程
如果要在全部记录上跑同一套流程,建议先把整包下到本地,再按文件读,避免反复走网络。下载后目录是扁平的,直接按记录名拼路径即可。
import os
import re
import numpy as np
import wfdb
ROOT = "./videopulse"
def offset_of(path):
with open(path + ".hea", encoding="utf-8") as f:
txt = f.read()
m = re.search(r"offset time:\s*([0-9.]+)", txt)
return float(m.group(1)) if m else None
rows = []
for name in sorted(os.listdir(ROOT)):
if not name.endswith("_vid.hea"):
continue
base = name[:-4]
vid = wfdb.rdrecord(os.path.join(ROOT, base))
stem = base[:-4]
ref = wfdb.rdrecord(os.path.join(ROOT, stem + "_ref"))
rows.append((base, vid.fs, vid.sig_len, ref.sig_len, offset_of(os.path.join(ROOT, base))))
print(len(rows))
print(rows[:2])
脚本输出的是结构信息而非统计量,这正是使用这个库时该关心的层面:每组记录多长、帧率多少、偏移有没有、配对是否齐全。
§6 与库内其他脉搏类资源的关系
6.1 关系图谱
本库收录的脉搏类资源大致可以分成三层。最靠近皮肤的是指夹与贴片类,参考信号本身即被当作真值;中间是手机摄像头贴皮肤类,输入是反射光,但接触仍在;最远是面部视频类,输入是远距离反射光,干扰最多。这个数据集属于最外层,它的价值在于把最难的场景与同一时刻的接触式参考绑在一起。
表:三层资源的定位
| 层级 | 接触方式 | 典型干扰 | 典型参考 | 本库归属 |
|---|---|---|---|---|
| 指夹贴片 | 直接接触皮肤 | 运动导致接触不良 | 自身即真值或有心电 | 否 |
| 手机摄像头 | 贴皮肤表面 | 压力、指纹、镜头污染 | 心电 | 否 |
| 面部视频 | 无接触,远距离 | 头动、光照、表情 | 指尖脉搏 | 是 |
表:与心电类资源的分工
| 需求 | 该用哪一类 | 原因 |
|---|---|---|
| 节律诊断 | 心电类 | 脉搏无法反映每次心室激动 |
| 波形提取质量 | 视频类,本库 | 参考同刻同人 |
| 变异性长期监测 | 心电或脉搏皆可,视精度要求 | 各有代价 |
| 设备工程评估 | 依场景,视频类偏应用端 | 贴近真实使用 |
6.2 检索路径
在站内找与这个库相关的资源,可以从三条线索出发。第一条是模态线索,按面部视频、远程光电容积、摄像头脉搏这几个词检索,应能命中同一层级的其他库。第二条是参考链线索,按指尖脉搏、接触式脉搏检索,会命中中间层的资源。第三条是任务线索,按脉搏率变异性、心率变异性、信号对齐检索,会命中方法学更接近的条目。
表:三条检索线索
| 线索 | 关键词 | 预期命中层级 |
|---|---|---|
| 模态 | 面部视频、远程光电容积、摄像头脉搏 | 外层 |
| 参考链 | 指尖脉搏、接触式脉搏 | 中层 |
| 任务 | 脉搏率变异性、信号对齐、波形相似度 | 跨层 |
若检索结果里出现大量含原始视频的库,要注意区分:那些库的体量通常比这个大几个数量级,许可也更复杂,不能与本库混为一谈。本库的核心辨识特征是「没有原始视频」加「两路信号分文件存」。
§7 质量评估与局限性
7.0 阅读本节前的一个前置校正
评这个库之前,先要校正一个常见的量纲误判:它的体量小不等于它的文档薄。事实上它的文档密度相当高,README 里把受试者构成、采集条件、命名规则、字段清单、资助来源、致谢对象都写了,主页还列了逐文件的校验值。真正薄的是两处,一是原始信号的中间形态,二是标注体系。
另一个误判是把「小」直接等同于「偏差大」。偏差的方向由抽样设计决定,而不是由样本量决定。这个库的偏差方向很明确:年轻、健康、以男性为主、室内坐姿、单一光照。样本量小只会让偏差的估计不确定,不会让偏差凭空出现或消失。理解这一点,才能把它放在正确的位置上使用。
还有一处误判需要提前拆开:有人看到「每段五十秒」就以为文件里都是五十秒。前面已经说过,头文件折算出的时长普遍长于五十秒。这是两个口径并存,不是记录有误。处理数据时以头文件为准,写方法时标注口径来源。
7.1 五维评分
按 DAIMS 框架的五个维度给这个库打分,每一档都给出依据,而不是只给结论。
表:DAIMS 五维评分
| 维度 | 分值 | 依据 |
|---|---|---|
| 可得性 | 五 | 无需注册、无审批、许可宽松、体量极小、有校验值 |
| 完整性 | 二 | 缺原始视频、缺逐拍标注、缺人口学字段、缺质量标签 |
| 可解释性 | 四 | 命名规则清晰、头文件自包含、信号名固定、文档到位 |
| 一致性 | 三 | 偏移写法统一,但少数记录缺注释;相机覆盖不对称 |
| 可复现性 | 二 | 处理链依赖论文描述,原始帧缺失导致无法端到端复现 |
可得性给满分并不夸张。开放存储桶、无凭证、几兆体量,这三条叠加起来在生理信号库里属于最好拿的一档,比许多需要签署数据使用协议的库省事得多。
完整性给低分是必然的。以「支撑一次完整的方法研究」为标准,它缺的东西太多:输入端缺像素,输出端缺标注,中间缺处理参数。它只提供了链条的两端,中间那一段要使用者自己补。
可解释性给高分是因为自描述程度高。一条记录名就能还原四维坐标,一个头文件就能还原采样率与长度,一个注释就能还原对齐关系。不需要外部字典,不需要查表,这对长期维护特别友好。
一致性扣分主要在两处。少数记录没有偏移注释,需要使用者自己发现并处理。相机覆盖不对称,导致「跨相机」这个维度的样本只有五人,任何按相机分组的比较都要反复声明这一限制。
可复现性给低分不是作者的过失,而是发布形态决定的。论文描述了一套面部检测与跟踪流程,但没有把视频放出来,后来的研究者只能按文字重写,重写的结果必然与作者不同。这意味着「复现」在这个库上只能是流程级复现,到不了结果级复现。
7.2 与同层级资源的横向比较
同层级里能拿来比较的库不多,因为「面部视频加同步接触式参考」这个组合本身的产出就少。多数面部视频库要么没有参考,要么参考是心电而非脉搏。这个库的组合选择使它在一个很小的生态位里几乎没有直接对手。
表:同层级比较
| 属性 | 本库 | 典型同类 |
|---|---|---|
| 参考类型 | 指尖脉搏 | 多为心电 |
| 原始视频 | 不提供 | 部分提供 |
| 规模 | 数十组 | 数十到数千不等 |
| 状态控制 | 二元 | 多样 |
| 许可 | 署名即可 | 因库而异 |
表:本库的相对优势与劣势
| 方面 | 优势 | 劣势 |
|---|---|---|
| 获取 | 极简 | 无 |
| 对齐信息 | 随数据走 | 少数缺失 |
| 规模 | 无 | 过小 |
| 模态深度 | 无 | 无原始帧 |
| 标注 | 无 | 无逐拍标注 |
7.3 已知的、可枚举的偏差
把可枚举的偏差逐条列出,比笼统地说「有局限」更有用,因为每一条都对应一个可操作的处理决定。
表:可枚举的偏差清单
| 编号 | 偏差 | 方向 | 处理建议 |
|---|---|---|---|
| 一 | 受试者全为健康年轻人 | 高估算法在患病人群的表现 | 结论限定在健康年轻人群 |
| 二 | 男性占绝对多数 | 性别相关差异不可估 | 不做性别分层 |
| 三 | 室内单一光照 | 高估光照鲁棒性 | 明确声明未测光照变化 |
| 四 | 坐姿固定 | 高估姿态鲁棒性 | 不外推到行走或卧床 |
| 五 | 相机覆盖不对称 | 跨机比较的样本仅为五人 | 跨机结论标注样本数 |
| 六 | 帧率与机型绑定 | 无法分离帧率效应与机型效应 | 只报观察到的差异,不归因 |
| 七 | 运动无量化 | 干扰强度不可比 | 只做有无对比 |
| 八 | 少数记录缺偏移 | 对齐需自行估计 | 用互相关并声明 |
回到 §4.2 的案例,旁证就很直接:同一名受试者在两种帧率下的采样点数相差近五倍,而机型同时从 Logitech 换成 GoPro,两条线索绑在一起,无法拆开。
第六条尤其值得强调。c1 是 15 Hz,c2 是接近 60 Hz,机型与帧率完全共线。看到 c2 的表现更好时,无法判断是 GoPro 的镜头更好,还是帧率更高带来的量化误差更小。这在实验设计上是一个无法分离的混淆,只能在解释时保持克制。
第七条也常被忽略。官方只说运动与静息,没有说运动幅度多大、持续多久、是左右摇头还是上下点头。这导致不同受试者的运动组之间并不可比,把它们汇总计算一个平均性能是没有意义的。
7.4 外部验证矩阵
一个库能不能用,很大程度取决于它能否在外部被独立验证。对这个小库而言,外部验证的路径有三条,每条的可达性不同。
表:外部验证路径
| 路径 | 具体做法 | 可达性 | 局限 |
|---|---|---|---|
| 内部一致 | 在两款相机之间比较同一方法 | 高 | 仅五人 |
| 跨库对照 | 在更大规模的视频脉搏库上重跑 | 中 | 库间条件差异大 |
| 文献比对 | 与引用本库的论文报告的值比较 | 中 | 指标口径未必一致 |
| 端到端复现 | 重写处理链并与论文比较 | 低 | 无原始帧 |
表:各路径的证据强度
| 路径 | 证据强度 | 适用结论 |
|---|---|---|
| 内部一致 | 弱 | 只能说明方法在该库内可用 |
| 跨库对照 | 中 | 可说明方法具有一定的可迁移性 |
| 文献比对 | 中 | 可说明结论方向是否一致 |
| 端到端复现 | 取决于重写质量 | 才能谈复现性 |
这张矩阵给出的实用结论是:把本库当外部验证集的价值,低于把它当内部调试点。它太小,做外部验证时统计效力不足;但它干净,做内部调试时反馈快。
7.5 它为何能持续:一组无需维护的静态数据
这个库从二零一七年发布至今没有更新过内容,版本号仍是一点零,唯一的变化是校验文件在二零一九年被重新生成过一次。它能长期存在的原因很简单:它不需要维护。没有持续采集,没有隐私审核,没有增量交付,没有版本兼容负担。数据一旦公开,成本就只剩存储,而几兆的存储在公共平台上可以忽略不计。
这一点与许多需要持续更新的临床数据库形成对照。那些库的价值随规模增长,但也随维护成本上升而脆弱。这个小库的价值不增长,但也不衰减,它作为某个时间点的标本被固定下来,反而获得了长期的可引用性。
表:静态库与动态库的对比
| 维度 | 静态小库 | 动态大库 |
|---|---|---|
| 更新频率 | 一次性 | 持续 |
| 维护成本 | 近零 | 高 |
| 规模增长 | 无 | 有 |
| 长期可引用性 | 稳定 | 依赖运营 |
| 复现友好度 | 高 | 随版本漂移 |
§8 生态位与历史
8.1 从一次会议报告到一个公开库
这条线的起点是一五年的一次工程医学会议。作者报告了一套用人脸检测与跟踪从视频中提取脉搏并计算脉搏率变异性的方法,用统计一致性说明了它与接触式参考的吻合程度。会议论文篇幅有限,不可能附数据。两年后,同一批作者把当时采集的记录整理后挂到了公开平台上。
这个时间差值得注意。从方法发表到数据公开隔了两年,说明整理工作本身有成本,需要把实验室里的采集文件翻译成标准格式,写说明文档,理清命名规则,补上校验值。这些都是不被论文计入的工作量,却决定了数据能否被别人用起来。
表:时间线上的关键点
| 时间 | 事件 | 意义 |
|---|---|---|
| 一五年 | 会议论文报告方法 | 方法层面确立可行 |
| 一七年七月 | 数据集首次发布 | 数据层面可复现 |
| 一九年二月 | 校验文件更新 | 完整性可核对 |
| 其后 | 版本未变 | 内容冻结 |
8.2 与同期同类工作的关系
同期还有若干团队在做类似的事,但公开发布的极少。多数团队把数据留在实验室,只在论文里报几个数。这使得这个库在很长时间里成为少数可以下载的样本,引用它的工作往往不是因为它最好,而是因为它是当时唯一能下载的。
这种「唯一性红利」在数据生态里很常见。一个库的早期引用量往往由可得性决定,而非质量决定。随着后续更大的库陆续公开,这类早期库的引用会从「主实验」转为「背景引用」,即只在综述或方法介绍里提一句。观察这个库近年的引用形态,可以看到这种转变的痕迹。
表:早期库的引用生命周期
| 阶段 | 引用性质 | 典型表述 |
|---|---|---|
| 首发初期 | 主实验数据 | 我们在该库上验证了方法 |
| 中期 | 补充对照 | 同时在该库上做了对比 |
| 后期 | 背景引用 | 早期工作如该库所示 |
8.3 它在今天的实际位置
今天再要做面部视频脉搏研究,第一选择不会是它。可选的数据集在规模、场景、标注上都远超它。但在两类场合它仍是首选:一是教学,因为体量小、格式标准、许可宽松,适合整包发给学生;二是流程调试,因为在两路信号都干净的小样本上跑通对齐,比在大库上调试要快得多。
§4.2 的案例在十年之后仍是教学中最常被打开的那一组,因为它用四条记录把一个析因设计讲完了,学生不用面对几十个目录就能理解配对、偏移与帧率三件事。
这个位置可以概括为「入口」而非「终点」。多数人第一次接触这类数据是从它开始,做完之后就转向更大的库。这并不贬低它,相反,能长期充当入口本身就是一种稳定的生态位。
表:两类典型场合的匹配度
| 场合 | 匹配度 | 原因 |
|---|---|---|
| 课程实验 | 高 | 体量小、许可宽松、概念完整 |
| 流程冒烟测试 | 高 | 反馈快、格式标准 |
| 主实验训练 | 低 | 规模不足 |
| 外部验证 | 低 | 人群单一 |
| 方法溯源 | 高 | 早期参照点清晰 |
8.4 从它演化出的问题清单
这个小库虽然没有被大规模使用,却提出了几个至今仍被讨论的问题。第一是感兴趣区域的选择,额头、脸颊、鼻尖各有优劣,作者选了跟踪,但没有系统比较区域。第二是帧率的下限,十五赫兹是否足够支撑变异性分析,这个库提供了低帧率样本,却没有给出结论。第三是运动干扰的量化,如何定义一个可复现的运动强度指标,至今没有共识。
这些问题都不是这个库能回答的,但它们的存在方式影响了后来的数据集设计。可以看到,后续发布的面部视频库大多会在元数据里明确记录光照、距离、运动幅度,这正是对这个库缺口的补位。
表:本库提出的问题与后续补位
| 问题 | 本库的状态 | 后续库的补位方式 |
|---|---|---|
| 区域选择 | 只做跟踪,未系统比较 | 记录区域坐标 |
| 帧率下限 | 提供两档,未下结论 | 提供多档帧率 |
| 运动量化 | 二元标签 | 记录加速度或位移 |
| 光照条件 | 未记录 | 记录照度 |
| 人群构成 | 单一 | 分层记录 |
§9 使用指引
9.1 三种角色的路径
第一种是学习者。目标是把概念跑通,不追求结果的可发表性。路径最短:下包、读一条记录、画两路波形、算一个相关系数。半天之内可以完成,难点只在环境配置。
第二种是算法开发者。目标是验证一个新特征或新流程是否比基线好。路径要长一些:先建立全库的读取与对齐管线,再选定评估指标,再在有偏移与无偏移两种情形下都跑一遍,最后把结果限定在描述性层面,不做显著性宣称。
第三种是数据集设计者。目标是借鉴这个库的做法去设计新的采集。路径完全不同:不看信号本身,只看文档结构与命名约定,研究它如何用最少的元数据把配对关系表达清楚,以及它在哪些地方留了缺口需要补。
表:三种角色的最短路径
| 角色 | 第一步 | 关键产出 | 常见卡点 |
|---|---|---|---|
| 学习者 | 下载并读一条记录 | 两路波形图 | 环境与库名拼写 |
| 开发者 | 建立对齐管线 | 全库结构表 | 偏移方向 |
| 设计者 | 读 README 与命名 | 命名与字段规范 | 忽略配对约定 |
9.2 一条最短的可用流程
把前面几节的内容压缩成一条可执行的最短路径,从下载到得出一个数,大约十来行代码。流程刻意省去了重采样之外的所有步骤,目的是让人在最短时间内看到「对齐是必要的」这件事。
python3.11 -m venv .venv && source .venv/bin/activate
pip install wfdb numpy
wget -r -N -c -np https://physionet.org/files/videopulse/1.0.0/
import numpy as np
import wfdb
root = "./physionet.org/files/videopulse/1.0.0"
vid = wfdb.rdrecord(f"{root}/subj_1_s_c1_vid")
ref = wfdb.rdrecord(f"{root}/subj_1_s_c1_ref")
def parse_off(rec):
for c in rec.comments:
if "offset time" in c:
return float(c.split(":")[-1])
return 0.0
off = parse_off(vid)
t_vid = np.arange(vid.sig_len) / vid.fs + off
t_ref = np.arange(ref.sig_len) / ref.fs
y_ref = np.interp(t_vid, t_ref, ref.p_signal[:, 0])
a = vid.p_signal[:, 0] - vid.p_signal[:, 0].mean()
b = y_ref - y_ref.mean()
print("偏移", off, "相关系数", float((a * b).sum() / np.sqrt((a * a).sum() * (b * b).sum())))
这段代码只依赖两个库,不涉及任何本地缓存配置。跑通之后,把 subj_1_s_c1 换成其他记录名,就可以遍历全库。
9.3 引用方式
数据集主页明确要求,使用时应引用其对应的会议论文。同时,平台也要求附上平台本身的标准引用。两套引用缺一不可,前者说明数据来源,后者说明分发渠道。
表:两套引用
| 用途 | 引用对象 | 说明 |
|---|---|---|
| 数据来源 | 作者的一五年会议论文 | 平台明确要求 |
| 分发渠道 | 平台标准引用 | 平台通用要求 |
| 版本标注 | 数据集版本号与发布年 | 便于定位具体快照 |
| 许可标注 | ODC-By 1.0 | 署名义务 |
表:引用时容易漏掉的三项
| 项目 | 为何重要 | 写法建议 |
|---|---|---|
| 版本号 | 内容可能更新 | 写明 v1.0.0 与发布年 |
| 访问日期 | 快照可追溯 | 写明核对日期 |
| 偏移处理声明 | 影响结果 | 在方法中说明如何对齐 |
§10 AI 使用声明
本页按 DAIMS 框架对 AI 可用性做一次声明式梳理。这里的「AI 可用」指数据能否直接喂给模型,而非数据是否由 AI 生成。该库全部内容由人工采集,不含任何合成或增强样本。
表:AI 使用声明
| 项目 | 声明 |
|---|---|
| 数据来源 | 人工采集,非合成 |
| 是否含 AI 生成内容 | 否 |
| 是否可直接用于监督学习 | 否,缺输入与标注 |
| 是否可用于自监督预训练 | 有限,规模过小 |
| 是否可用于方法可行性验证 | 是,这是主要用途 |
| 是否涉及个人隐私 | 无原始视频、无面部图像、无姓名 |
| 再分发条件 | ODC-By 1.0,保留署名 |
| 建议的模型使用方式 | 冒烟测试、对照基线、教学演示 |
| 不建议的模型使用方式 | 大规模训练、人群泛化结论、临床声明 |
表:隐私与合规要点
| 要点 | 状态 | 说明 |
|---|---|---|
| 面部图像 | 不提供 | 仅保留提取后的波形 |
| 姓名与身份 | 不提供 | 仅编号 |
| 年龄精度 | 区间 | 无逐人精确值 |
| 伦理审批信息 | 页面未列 | 使用时不宜自行推断 |
| 跨境传输限制 | 无 | 公开许可,无地域限制 |
常见误读(避坑清单)
| 常见说法 | 实际 | 证据 |
|---|---|---|
| 这是视频数据集 | 只有波形,没有帧 | 文件清单只有 .hea 与 .dat |
| 参考信号是心电 | 是指尖脉搏 | 信号名为 fingerpulse |
| 每段都是五十秒 | 头文件折算普遍更长 | 采样点数除以采样率 |
| 十五个人分两组 | 前五人有四组,其余两组 | 文件名相机段的分布 |
| 两台相机可公平比较 | 机型与帧率共线 | c1 十五赫兹,c2 近六十赫兹 |
| 有逐拍标注 | 无任何标注文件 | 目录无标注目录 |
| 有呼吸或血氧 | 无额外通道 | 单通道,信号名仅两种 |
| 可以用它训练模型 | 缺输入端,不宜训练 | 无原始视频 |
| 时间偏移可忽略 | 偏移可达十余秒 | 注释行数值 |
| 许可需要申请 | 署名即可 | ODC-By 1.0 |
FAQ
Q1:它里面有没有原始视频文件?
没有。发布内容只有从视频中提取出来的脉搏波形,原始帧不随数据集提供。若要复现从视频到波形的整个过程,必须自己按论文描述搭一套面部检测与跟踪流程。
Q2:参考信号是心电还是血压?
都不是。参考系统是一枚指尖脉搏传感器,输出接触式光电容积脉搏波形,以一千赫兹采样。数据集中没有心电、没有袖带血压,也没有呼吸通道。
Q3:只有十五个人,还能拿来做研究吗?
能,但定位必须放对。它适合做方法原型的可行性验证、两路信号对齐流程的调试,以及教学演示。不适合做需要人群泛化结论的训练集或外部验证集。
Q4:为什么有的记录里视频信号比参考信号长?
两路信号是分别导出的,采样点数各自独立。头文件给出的时长是按采样点数除以采样率折算的结果,两个文件不做同步截断,因此长短不一致属于正常现象,需要使用者按时间偏移自己裁齐。
Q5:偏移值的方向怎么确定?
先用一小段数据做互相关,找出使两路最相似的平移量,再与头文件的值比对。若接近则方向正确,若差一个符号则把平移量取反。在一个受试者身上跑通一次即可确定全库约定。
Q6:能不能拿来算心率变异性?
参考信号质量足够支撑脉搏率变异性计算,但它反映的是血管搏动间隔,与心电的心搏间期不等价,高频成分会被平滑。用于节律诊断不合适,用于自主神经的粗略评估尚可。
Q7:为什么运动记录的偏移普遍更大?
偏移是两路采集的起始时刻差,与采集流程是否顺畅有关。运动条件下受试者需要更多准备时间,两套设备的启动时刻更容易错开。页面没有解释成因,这一点属于观察,不宜当作结论。
Q8:两款相机的差异是机型造成的吗?
未必。机型与帧率完全绑定,十五赫兹对接近六十赫兹,无法分离设备光学性能与采样率的影响。只能报告观察到的差异,不能归因。
Q9:可以商用吗?
可以。许可为开放数据署名一版,只要求保留署名,不限制商业使用。再分发时应保留原许可与出处说明。
Q10:有没有官方工具链?
没有专门的工具,但数据用通用的生理信号格式存储,任何支持该格式的客户端都能直接读取。Python 生态里的 WFDB 客户端是最常用的一种。
Q11:为什么记录名和 README 写的不一致?
README 把名字写成三段,实际文件名是四段,多出信号类型一段。前者描述逻辑记录,后者描述物理文件,两者并不冲突,核对时以文件名为准。
Q12:适合做深度学习吗?
不直接适合。缺输入端也就是原始视频,缺标注也就是逐拍位置,规模也不足以支撑训练。可以当作深度学习流程的冒烟测试样本,训练与评估都要另找数据。
术语表
| 术语 | 英文 | 在本库中的含义 |
|---|---|---|
| 视频脉搏信号 | videopulse | 从面部视频提取的脉搏波形,单通道 |
| 指尖脉搏参考 | fingerpulse | 接触式传感器测得的脉搏波形,单通道 |
| 远程光电容积脉搏 | remote photoplethysmography | 无接触地从视频提取脉搏的技术总称 |
| 脉搏率变异性 | pulse rate variability | 由脉搏峰间期序列计算的变异性指标 |
| 心率变异性 | heart rate variability | 由心电间期序列计算的变异性指标 |
| 时间偏移 | time offset | 参考与视频两路信号起始时刻之差 |
| 记录名 | record name | 由受试者、条件、相机、信号类型四段拼成 |
| 头文件 | header | 记录名、采样率、采样点数与信号名的文本描述 |
| 数据文件 | data file | 十六位有符号整数的小端二进制 |
| 增益 | gain | 把整数换算为归一化幅度的除数 |
| 静息条件 | stationary | 受试者基本不动的采集状态,编码 s |
| 运动条件 | motion | 受试者有头动的采集状态,编码 m |
| 相机一 | c1 | Logitech 机型,十五赫兹 |
| 相机二 | c2 | GoPro 机型,接近六十赫兹 |
| 感兴趣区域 | region of interest | 面部用于提取信号的区域 |
| 面部跟踪 | face tracking | 逐帧定位面部以抵消头动 |
| 时间对齐 | alignment | 按偏移把两路信号摆到同一时间轴 |
| 互相关 | cross correlation | 估计两路信号平移量的方法 |
| 归一化幅度 | normalized amplitude | 无物理单位、仅形状有意义的数值 |
| 逐拍标注 | beat annotation | 标记每次搏动时刻的元数据,本库无 |
| 校验值 | checksum | 用于核对文件完整性的哈希 |
| 开放数据署名许可 | ODC-By 1.0 | 只要求署名的开放数据许可 |
| 数字对象标识 | DOI | 数据集的持久标识 |
| 快照 | version snapshot | 某一时点的固定发布状态 |
| 混淆 | confounder | 与目标变量共同变化的第三因素 |
附录 A:核心数字核对表
| 项 | 值 | 来源 | 来源层级 |
|---|---|---|---|
| 受试者人数 | 十五 | 数据集主页与 README | 官方页面 |
| 男女构成 | 十二男三女 | 数据集主页与 README | 官方页面 |
| 年龄区间 | 二十三至三十五岁 | 数据集主页与 README | 官方页面 |
| 记录组数 | 四十 | 数据集主页 | 官方页面 |
| 记录名条数 | 八十 | 记录清单文件 | 官方页面 |
| 双机受试者数 | 五 | 数据集主页 | 官方页面 |
| 参考采样率 | 一千赫兹 | 头文件与 README | 官方页面 |
| 相机一帧率 | 十五赫兹 | 头文件 | 数据文件 |
| 相机二帧率 | 五十九点九四零赫兹 | 头文件 | 数据文件 |
| 未压缩体积 | 约五点五兆字节 | 数据集主页 | 官方页面 |
| 版本 | 一点零 | 数据集主页 | 官方页面 |
| 首发日期 | 二零一七年七月十二日 | 数据集主页 | 官方页面 |
| 许可 | 开放数据署名一版 | 数据集主页 | 官方页面 |
| 分析窗口 | 五十秒 | 数据集主页与 README | 官方页面 |
| 头文件折算时长 | 五十一秒至一百一十四秒 | 头文件 | 数据文件 |
| 时间偏移量级 | 二点七秒至十二点三秒 | 头文件注释 | 数据文件 |
附录 B:数字的来源分层
| 层级 | 定义 | 本页涉及的条目 |
|---|---|---|
| 官方页面 | 数据集主页、说明文档、记录清单 | 人数、构成、年龄、记录数、帧率标称、采样率、体积、许可、日期 |
| 数据文件 | 逐条头文件解析所得 | 实际采样点数、折算时长、具体偏移值、首样本与校验和 |
| 论文摘要 | 会议论文摘要 | 方法动机、变异性替代作用、跟踪的必要性 |
| 未核实 | 页面未说明 | 运动强度、光照条件、伦理审批、肤色构成、型号具体版本 |
表:两处口径差异
| 项 | 口径一 | 口径二 | 处理 |
|---|---|---|---|
| 每段时长 | 说明为五十秒 | 头文件折算更长 | 以头文件为准,注明口径 |
| 记录名结构 | 说明为三段 | 文件名为四段 | 以文件名为准,说明对应关系 |
附录 C:完整参考文献
| 编号 | 文献 | 与本页的关系 |
|---|---|---|
| 一 | Melchor Rodríguez A, Ramos Castro J. Pulse rate variability analysis by video using face detection and tracking algorithms. 2015 年工程医学年会,第五六九六至五六九九页 | 数据集对应的方法论文,平台要求引用 |
| 二 | 平台标准引用,二〇二六年 | 分发渠道的通用引用 |
| 三 | 数据集说明文档 | 命名规则、字段清单与致谢 |
| 四 | 记录清单文件 | 记录名的权威列表 |
| 五 | 校验值文件 | 完整性核对 |
附录 D:任务代码
| 任务 | 关键函数 | 输出 |
|---|---|---|
| 列出全库记录 | 取记录清单 | 记录名列表 |
| 读单条记录 | 读记录 | 信号数组与头信息 |
| 解析偏移 | 正则匹配注释 | 浮点秒数 |
| 重采样对齐 | 线性插值 | 等长序列 |
| 算吻合度 | 皮尔逊相关 | 相关系数 |
| 批量结构表 | 遍历头文件 | 结构汇总 |
附录 E:如果只记五件事
| 序号 | 要点 |
|---|---|
| 一 | 没有原始视频,只有提取后的波形,这是最硬的边界 |
| 二 | 参考是指尖脉搏而非心电,因此不能做节律诊断 |
| 三 | 十五人四十组,适合验证与教学,不适合训练与推断 |
| 四 | 时间偏移写在头文件里,不对齐就没有可比性 |
| 五 | 许可宽松、体积极小、格式标准,是这类数据的入门首选 |
编辑说明
本页依据数据集主页、说明文档、记录清单与各位头文件的公开内容整理,核对日期为二零二六年十月二十八日。凡涉及人数的数字取自官方文字说明,凡涉及时长与偏移的数字取自头文件解析,两者口径不同处已在附录 B 并列标注,未做取舍。页面未说明的内容一律标为未核实,未做推断补全。运动条件的具体含义、光照与距离、伦理审批细节、肤色与体型构成,均未纳入,因为官方未提供。许可与引用要求按平台原文转述,具体条款以官方文件为准。
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- eda-rest-sedation — 共享标签:生理信号 / 可穿戴传感 / 评测基准
- icentia11k — 共享标签:生理信号 / 可穿戴传感 / 心血管疾病 / 评测基准
- hf-lung-v1 — 共享标签:生理信号 / 可穿戴传感 / 评测基准
- auricle-wearable-cv — 共享标签:生理信号 / 可穿戴传感 / 心血管疾病 / 评测基准
- mimic-perform — 共享标签:生理信号 / 可穿戴传感 / 心血管疾病 / 评测基准
- dreamt — 共享标签:生理信号 / 可穿戴传感 / 评测基准
- code-test — 共享标签:生理信号 / 心血管疾病 / 评测基准
- bigideaslab-step-hr-smartwatch — 共享标签:生理信号 / 心血管疾病 / 评测基准
- neurocritical-pediatric — 共享标签:生理信号 / 心血管疾病 / 评测基准
- multimodal-surgery-anesthesia — 共享标签:生理信号 / 心血管疾病 / 评测基准
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

