信息速览
针极肌电图是神经内科最古老也最依赖人的检查之一:一根细针穿过皮肤进入肌肉,针尖附近的几个运动单位放电被记录下来,医生靠波形的形态、时限、幅度与干扰相的疏密判断这块肌肉是病变在肌纤维本身、还是病变在支配它的神经。学会看这些波形是住院医师培训里最耗时的部分之一,而公开可用的真实针极记录极少——它不像心电图那样可以长时间无创记录,每一段都意味着一次进针。
PhysioNet 上的 EMGDB(栏目名为 Examples of Electromyograms)就是为这种稀缺补上一个小小的口子。它由哈佛医学院附属贝斯以色列女执事医疗中心神经内科的 Seward Rutkove 提供,只有三段记录,分别来自一名没有神经肌肉病史的 44 岁男性、一名多发性肌炎致肌病的 57 岁男性、一名右 L5 神经根病致神经病的 62 岁男性,全部取自同一块肌肉(胫骨前肌),用同一支 25 毫米同心针电极,在同一个采集系统上完成。
它不是训练集,也不是基准测试集,更不是任何意义上的队列。它的真实身份是一组附带临床诊断的教科书示例:三个波形,三种病理状态,用来让人第一次把「肌源性损害」与「神经源性损害」这两个词和真实波形对上号。一屏速览见下表。
| 维度 | 内容 |
|---|---|
| 全名 | Examples of Electromyograms |
| 中文习惯称法 | 针极肌电示例库 / 肌电图示例 |
| 发布方 | PhysioNet(数据由 Beth Israel Deaconess Medical Center / Harvard Medical School 神经内科 Seward Rutkove 提供) |
| 首次发布 | 2009 年 9 月 5 日,版本 1.0.0 |
| 最近改动 | 2010 年 4 月 26 日,信号与头文件更新 |
| 记录数 | 3 段(emg_healthy、emg_myopathy、emg_neuropathy) |
| 受试者数 | 3 名,全部男性,年龄 44、57、62 岁 |
| 肌肉与电极 | 胫骨前肌,25 毫米同心针电极 |
| 采集系统 | Medelec Synergy N2 EMG Monitoring System(Oxford Instruments Medical) |
| 原始采样率 | 50 kHz |
| 交付采样率 | 4 kHz(降采样后) |
| 模拟滤波 | 20 Hz 高通 + 5 kHz 低通 |
| 每段时长 | 约 12.7 / 27.6 / 37.0 秒(由头文件采样点数换算) |
| 通道数 | 1(单通道) |
| 文件格式 | WFDB(.hea + .dat),另附同内容的 .txt 两列文本 |
| 标注 | 无逐事件标注,仅头文件注释行里的年龄、性别与诊断 |
| 总体积 | 5.1 MB(未压缩) |
| 许可 | ODC-BY 1.0,无需注册 |
| 典型用途 | 教学演示、信号处理流程验证、方法学论文图示、定性参考 |
§1 它要解决的具体麻烦
1.1 针极肌电缺的不是算法,是能公开的波形
肌电信号在公开数据集里并不少见,但绝大多数是表面肌电:电极贴在皮肤上,记录整块肌肉的叠加电活动,采样率一两千赫兹,动辄几十人、几十小时。这类数据之所以能公开得这么顺利,是因为采集过程无创、可重复、不涉及任何风险,受试者也愿意配合做几十次手势。
针极肌电的处境完全不同。针要刺进肌肉,属于有创操作,采集依赖受过训练的临床医师,一次检查通常只持续十几分钟,而其中真正被记录的片段往往只有每个进针点上的几秒钟。要把这样的记录整理成公开数据集,需要跨越伦理、去标识、设备导出格式、临床语境丢失等一连串障碍。结果是,想学针极肌电的人面对的是两种材料:教科书上的示意图,或者自己医院的检查记录。
EMGDB 的价值就落在这个缺口上。它提供的不是数量,而是一种「可以下载下来的典型」:一段形态正常的运动单位电位长什么样,肌病患者的波形为什么看起来「又小又碎」,神经病患者干扰相为什么显得「又大又疏」。这三件事在教科书里都有文字描述,但文字描述和真实波形之间的落差,往往要靠看过几十段真实记录才能填平。
1.2 三条常见的错误期待
第一条,期待它是「肌电分类数据集」。它的名字里有「示例」二字,官方正文的定位也始终是示例。三段记录分别对应三种状态,但每种状态只有一个受试者、一段记录、一块肌肉。任何一组训练与测试的划分都会让某一类完全不出现在训练侧或测试侧。
第二条,期待它带有「运动单位电位级标注」。针极肌电分析的核心工作之一是把连续信号切分成一个个运动单位电位,再量它们的时限、波幅、相位。这套流程需要人工逐段标定起止点,工作量极大。EMGDB 没有做这件事,头文件里只有年龄、性别、诊断三行注释,.dat 是原始信号,没有一行标注。
第三条,期待它能代表「胫骨前肌的正常参考范围」。唯一的那名健康受试者 44 岁,只采了一个进针点,只记录了一段。正常运动单位电位的参数随年龄、肌肉、进针位置变化很大,一个人的一段记录连参考范围的边都算不上。
1.3 它能给到的与给不到的
| 你的需求 | 它给的 | 够不够 |
|---|---|---|
| 看懂肌病波形与神经病波形的典型差异 | 同一肌肉、同一电极、同一设备下的三种状态对照 | 够,这是它最好的用法 |
| 验证一套针极肌电预处理与特征提取流程 | 三段可完整下载的原始信号,带增益与滤波信息 | 够,跑通流程绰绰有余 |
| 训练一个运动单位电位分类器 | 无任何运动单位级标注 | 不够,一个标注都没有 |
| 做肌病与神经病的二分类 | 每类一个受试者 | 形式可跑,结论无意义 |
| 估计正常人群的运动单位电位参数分布 | 一名健康受试者、一段记录 | 不够,样本量为 1 |
| 做时序分割或事件检测的基线对比 | 信号干净、时长明确、三类边界清晰 | 可做,但只能当玩具数据 |
| 研究疲劳对肌电的影响 | 每段只持续数秒,官方未说明是否达到疲劳 | 不够,时长与设计都不支持 |
| 教学时给学生一个可下载的真实波形 | 三段带诊断的公开记录,许可宽松 | 够,这是它的第二好用法 |
1.4 你的处境与它能帮到的事
| 你的处境 | 它能帮你什么 | 下一步该做什么 |
|---|---|---|
| 你在写一篇针极肌电信号处理的论文,需要一个公开可复现的示例来画图 | 三段信号可直接下载、许可允许再分发,图注可以写清来源与诊断 | 用 §5.2 的读取流程还原毫伏值,图注里标明采样率与滤波参数 |
| 你在教住院医师看肌电图,缺一个能把三种状态并排摆出来的材料 | 同一肌肉、同一设备、同一电极下的三段记录,差异只来自病理状态 | 按 §4.3 的案例把三段画在同一时间尺度上,先讲干扰相疏密再讲单个电位 |
| 你在开发一套自动测量运动单位电位时限与波幅的工具 | 可以先用三段真实波形验证工具不会在边界情况上崩掉 | 工具的定量结论不能拿这三段做准确率证据,需另找带标注的语料 |
| 你要做一个针极肌电的公开演示或教学网站 | 5.1 MB 全量可下,许可允许再分发并署名 | 按 §9.3 写明 DOI、提供者与 PhysioNet 平台文献 |
| 你的模型在表面肌电上表现很好,想试试针极 | 可以快速感受针极信号的信噪比、基线稳定性与单通道形态 | 感受完之后要另找真正的针极数据集,三段不足以做任何评估 |
| 你在核对某篇论文里引用的「PhysioNet 肌电库」到底是哪一个 | 库内已有多个肌电数据集,名字容易混 | 按 §6.2 的检索路径逐条比对规模与电极类型 |
1.5 一句话判断
它是一份带诊断标签的教学幻灯片,不是一份可以拿来拟合的数据:三段真实针极波形足以让一个从未见过肌电信号的人建立起对肌病与神经病的直觉,却不足以支撑任何一句关于分类性能的结论。
1.6 不适合谁:四条边界
不适合做规模训练。 三段记录、三名受试者、单通道,这组数字放在任何深度学习语境里都等于零。哪怕只是微调一个预训练模型,三段数据也只能用来检查输入管线是否接得通。
不适合做分类性能评估。 类别数等于受试者数等于记录数,训练侧与测试侧无法同时覆盖三类。任何在这样的划分上报出来的准确率、灵敏度、特异度,测的都是划分方式,不是模型。
不适合做人口学或流行病学推断。 三名男性、一个中心、一块肌肉,年龄跨度只覆盖 44 到 62 岁。用它讨论「神经病患者的肌电特征分布」会把一个个案当成一个群体的代表。
不适合做长时程或疲劳研究。 官方正文写的是「采集数秒」,头文件换算出来最长的一段也只有三十七秒。针极检查本身就是短时记录,用它讨论疲劳性变化缺少设计前提。
§2 数据构成与规格
2.1 一个记录名对应两个到三个文件
数据库沿用 PhysioNet 通用的 WFDB(Waveform Database)组织方式。根目录下只有三组记录,每组以记录名为前缀:emg_healthy、emg_myopathy、emg_neuropathy,后缀分别是 .hea(文本头文件)、.dat(二进制信号)、.txt(同内容的纯文本导出)。另有一个 RECORDS 清单列出三个记录名,一个 SHA256SUMS.txt 给出全部文件的校验和,一张 emg.png 是官方页面展示的示例波形图。
WFDB 的惯例是头文件与信号文件必须成对使用:.hea 第一行声明记录名、通道数、采样率、采样点数;第二行声明信号文件名、存储格式、增益、位分辨率、ADC 零值、初始值、校验和、块大小与通道名;其后以 # 开头的行是自由文本注释。.dat 里按帧存放整数采样值。emgdb 的特别之处在于每个记录都额外给了一份 .txt,把时间与电压写成两列十进制小数,绕开了 WFDB 工具链。
| 文件 | 大小 | 作用 | 备注 |
|---|---|---|---|
RECORDS |
40 字节 | 三个记录名的清单 | 每行一个名字,无表头 |
SHA256SUMS.txt |
887 字节 | 全部文件的 SHA-256 | 每行一个哈希加文件名 |
emg.png |
41.1 KB | 官方页面上的示例波形图 | 与人名、诊断同框展示 |
emg_healthy.hea |
300 字节 | 健康者记录的头文件 | 含年龄、性别、诊断三行注释 |
emg_healthy.dat |
99.3 KB | 健康者记录的信号 | 16 位整数,单通道 |
emg_healthy.txt |
738.1 KB | 健康者记录的文本导出 | 两列,时间与电压 |
emg_myopathy.hea |
362 字节 | 肌病者记录的头文件 | 注释行多一行用药信息 |
emg_myopathy.dat |
215.5 KB | 肌病者记录的信号 | 同上 |
emg_myopathy.txt |
1.6 MB | 肌病者记录的文本导出 | 同上 |
emg_neuropathy.hea |
346 字节 | 神经病者记录的头文件 | 诊断跨两行写 |
emg_neuropathy.dat |
288.8 KB | 神经病者记录的信号 | 同上 |
emg_neuropathy.txt |
2.1 MB | 神经病者记录的文本导出 | 同上 |
表里有一个值得留意的反差:三段记录的 .dat 加起来不到六百千字节,而三份 .txt 加起来超过四兆。原因很直接,二进制里一个采样点占两个字节,文本里要占十几到二十几个字符(时间一列、电压一列、分隔符、换行)。处理这类库时如果只按 .txt 规划存储与内存,会把体积高估六到八倍。
2.2 字段与注释的完整字典
针极肌电库没有表格意义上的列,信息分散在头文件的关键字行与注释行里。下表逐项列出三段记录中能读到的全部信息项。
| 信息项 | 所在位置 | 取值示例 | 含义 | 使用注意 |
|---|---|---|---|---|
| 记录名 | .hea 第 1 行第 1 字段 |
emg_healthy |
记录标识 | 与文件名前缀一致 |
| 通道数 | .hea 第 1 行第 2 字段 |
1 |
信号条数 | 全部为单通道 |
| 采样率 | .hea 第 1 行第 3 字段 |
4000 |
每秒采样点 | 原始 50 kHz 降采样而来 |
| 采样点数 | .hea 第 1 行第 4 字段 |
50860 |
该段总长度 | 除以 4000 得秒数 |
| 信号文件名 | .hea 第 2 行第 1 字段 |
emg_healthy.dat |
信号存放位置 | 与头文件同名 |
| 存储格式 | .hea 第 2 行第 2 字段 |
16 |
16 位带符号整数 | 不是浮点 |
| 增益 | .hea 第 2 行第 3 字段 |
10000/mV |
每毫伏对应整数单位 | 即 0.1 微伏/单位 |
| 位分辨率 | .hea 第 2 行第 4 字段 |
16 |
ADC 位数 | 有效位受满量程约束 |
| ADC 零值 | .hea 第 2 行第 5 字段 |
0 |
零电平对应整数 | 换算时先减零值 |
| 初始值 | .hea 第 2 行第 6 字段 |
-333 |
首采样点整数值 | 三段各不相同 |
| 校验和 | .hea 第 2 行第 7 字段 |
-29438 |
采样点累加和 | 校验 .dat 是否完整 |
| 块大小 | .hea 第 2 行第 8 字段 |
0 |
每帧字节数 | 0 表示自动按格式推 |
| 通道名 | .hea 第 2 行第 9 字段 |
EMG |
通道标签 | 与采样率之间多写了一个 16 |
| 年龄 | .hea 注释行 |
44 |
受试者年龄 | 以 <age>: 开头 |
| 性别 | .hea 注释行 |
M |
受试者性别 | 三段全为 M |
| 诊断 | .hea 注释行 |
自由文本 | 临床诊断 | 以 <diagnoses> 开头 |
| 用药 | .hea 注释行 |
steroids, low-dose methotrexate |
合并用药 | 仅肌病记录有 |
| 采集条件 | .hea 注释行 |
轻抗阻背屈踝部 | 动作说明 | 三段措辞相同 |
| 电极与肌肉 | .hea 注释行 |
25mm 同心针、胫骨前肌 | 采集装置 | 三段措辞相同 |
头文件第二行的字段数比标准 WFDB 单通道声明多了一个。标准写法是文件名、格式、增益、位分辨率、零值、初始值、校验和、块大小、通道名九个令牌,这里在增益之后多出现了一个 16,于是读数位置整体后移一位。这一点在使用 wfdb 库读取时不会出事,因为库按固定顺序解析前九个令牌,多出来的那个会被当作块大小附近的冗余处理;但自己手写解析脚本时如果按「倒数第二个是块大小、最后一个是通道名」去取,就会取到 0 和 EMG 之外的错位值。稳妥的写法是从右往左取通道名与块大小,中间字段按固定顺序解析。
三段记录的关键参数并排如下:
| 项目 | emg_healthy | emg_myopathy | emg_neuropathy |
|---|---|---|---|
| 年龄 | 44 | 57 | 62 |
| 性别 | 男 | 男 | 男 |
| 诊断 | 无神经肌肉疾病史 | 长期多发性肌炎所致肌病 | 慢性下背痛伴右 L5 神经根病所致神经病 |
| 用药 | 无记录 | 激素、低剂量甲氨蝶呤 | 无记录 |
| 采样点数 | 50,860 | 110,337 | 147,858 |
| 时长(秒) | 约 12.7 | 约 27.6 | 约 37.0 |
| 初始值 | -333 | -50 | 900 |
| 校验和 | -29438 | -6380 | 16686 |
| 信号体积 | 99.3 KB | 215.5 KB | 288.8 KB |
2.3 一段记录的完整解剖
以健康者那段为例。头文件第一行是 emg_healthy 1 4000 50860,读法依次是记录名、一个通道、4000 赫兹、50860 个采样点。50860 除以 4000 得 12.715 秒,这就是这一段记录的实际长度。
第二行是信号声明:
emg_healthy.dat 16 10000/mV 16 0 -333 -29438 0 EMG
从右往左读:通道名 EMG,块大小 0(交给库自动推算),校验和 -29438,初始值 -333,ADC 零值 0,位分辨率 16,增益 10000/mV,格式 16(16 位带符号整数),文件 emg_healthy.dat。增益的含义是每毫伏电压对应一万个整数单位,反过来一个整数单位就是 0.1 微伏。
随后三行注释给出临床上下文:
#-- <age>: 44 <sex>: M <diagnoses> no history of neuromuscular disease
#-- EMG from 25mm concentric needle electrode placed in tibialis anterior muscle
#-- patient dorsiflexed the foot gently against resistance, then relaxed
三行分别说明受试者为 44 岁男性、无神经肌肉疾病史,电极是置于胫骨前肌的 25 毫米同心针,采集时受试者轻抗阻背屈踝部随后放松。
读信号的标准写法:
import wfdb
import numpy as np
#-- 远程直读,不必先下载;库名就是 URL 里的 emgdb
rec = wfdb.rdrecord('emg_healthy', pn_dir='emgdb')
print(rec.fs, rec.sig_len, rec.sig_name)
print(rec.p_signal.shape)
#-- p_signal 已按增益与零值换算成毫伏,单位是 mV
x = rec.p_signal[:, 0]
print('min mV', x.min().round(4), 'max mV', x.max().round(4))
print('peak-to-peak mV', float(np.ptp(x)).__round__(4))
#-- 折算成微伏,针极信号通常在几十到几千微伏区间
print('p2p uV', round(float(np.ptp(x)) * 1000, 1))
rec.p_signal 是换算后的浮点毫伏;要拿原始整数用 rec.d_signal。rec.comments 里保存的就是头文件末端的注释行,可以按字符串切出年龄与诊断。
2.4 三段的长度、幅度与诊断分布
官方的三段记录在长度与幅度上都不齐,这不是设计出来的对照,而是三次独立临床检查留下的自然差异。长度从十二秒多到三十七秒,幅度也不一致:健康段与神经病段的峰峰值明显大于肌病段,这与肌病的病理生理一致——肌纤维坏死与再生导致参与放电的运动单位变小、数目减少,针尖附近采集到的电位整体幅度下降。
| 观察维度 | 官方公布的 | 由头文件可换算的 | 官方未公布的 |
|---|---|---|---|
| 时长 | 只写「数秒」 | 12.7 / 27.6 / 37.0 秒 | 每次进针前后的停顿时长 |
| 幅度 | 未写 | 由增益与整数范围决定 | 峰峰值、均方根、信噪比 |
| 采样率 | 50 kHz 采、4 kHz 交付 | 头文件 4000 | 降采样前是否做过抗混叠 |
| 滤波 | 20 Hz 高通、5 kHz 低通 | 写在正文,头文件不体现 | 滤波器阶数与具体响应 |
| 皮肤温度 | 未写 | — | 温度对传导速度的影响 |
| 进针深度与位置 | 未写 | — | 针尖在肌腹内的具体坐标 |
| 受试者用力水平 | 只写「轻抗阻」 | — | 具体负荷或力矩 |
| 诊断依据 | 只给诊断名 | — | 确诊所依据的针极、神经传导或影像结果 |
2.5 与库内表面肌电数据集的规格差异
把 EMGDB 与库内已有的几个肌电数据集并排放在一张表里,能一眼看出它落在分布的最边缘。
| 对比项 | EMGDB | NinaPro | GRABMyo | Hyser(hd-semg) | EHGDB |
|---|---|---|---|---|---|
| 电极类型 | 同心针电极(刺入) | 表面电极(贴附) | 表面电极(贴附) | 高密度表面阵列 | 腹壁表面子宫肌电 |
| 通道数 | 1 | 8–16 | 16–32 | 256 | 16 |
| 受试者 | 3 名男性 | 数十至一百余名 | 43 名(扩展版 63 名) | 20 名 | 45 名孕妇 |
| 目标肌肉 | 胫骨前肌 | 前臂与手部肌群 | 前臂与腕部 | 前臂 | 子宫 |
| 任务 | 轻抗阻背屈,观察静息与募集 | 数十类手势 | 十余类静态手势 | 手势与五指令力 | 妊娠期与产程记录 |
| 采样率 | 4 kHz(原始 50 kHz) | 2 kHz 级 | 2048 Hz | 2 kHz 级 | 200 Hz |
| 时长量级 | 每段十余到数十秒 | 多小时 | 数小时 | 数十小时 | 数十分钟 |
| 标注 | 无 | 手势与重复序号 | 手势与日期 | 手势、力矩 | 临床头信息与部分事件 |
| 主要用途 | 教学与流程验证 | 手势识别基准 | 生物特征与手势识别 | 高密度肌电解码 | 早产预测 |
| 许可 | ODC-BY 1.0 | 逐子库不同 | CC BY 4.0 | 随发布页 | ODC-BY |
这张表要说清的只有一件事:EMGDB 在「通道数」「受试者数」「时长」「标注」四列上全部垫底,唯一独特的是「电极类型」——它是库里极少数真正把针插进肌肉的记录之一。判断要不要用它,只需回答一个问题:你需要的是皮肤上方的叠加电活动,还是针尖附近的单个运动单位。
§3 它是谁采的:一间神经内科诊室的示例素材
3.1 采集者与机构
官方正文写明数据「承蒙 Seward Rutkove 医学博士提供,隶属贝斯以色列女执事医疗中心/哈佛医学院神经内科」。这句话交代了两件事:采集发生在临床诊室,不是实验室的受控试次;提供者是临床神经电生理的执业医师,而不是数据工程团队。
这个来历直接决定了数据的样子。它不是按实验方案招募受试者、按固定流程重复采集得到的,而是在日常检查中顺带留下来的几段记录。所以每段长度不同、诊断描述是一句临床口语、用药信息只在肌病那段被提到、健康者那段的措辞是「无神经肌肉疾病史」而不是「健康志愿者」。
3.2 时间线
| 时间 | 事件 | 意义 |
|---|---|---|
| 2009-09-05 | 数据库在 PhysioNet 上线,版本 1.0.0 | 首次公开 |
| 2010-04-26 | 信号文件与头文件更新,附上 .txt 导出与 RECORDS |
增加了非 WFDB 工具可读的副本 |
| 2019-02-20 | 生成 SHA256SUMS.txt |
补齐完整性校验 |
| 之后 | 版本号停在 1.0.0,读数缓慢累积 | 定位固定为常青示例,不再扩展 |
第三行与第四行的日期来自文件列表里各文件的修改时间与校验和清单的生成时间,说明这个库在最初上线之后只做过两轮技术性整理,没有增加新的记录。
3.3 采集场景:一次标准的针极检查
官方正文对采集流程的描述相当具体,值得逐句拆开。采集设备是 Medelec Synergy N2 肌电监护系统,制造商标注为 Oxford Instruments Medical,产地在英国的 Old Woking。电极是 25 毫米同心针,所谓同心针,是指一根中空针管里藏着一根细金属丝,针管外壁与内芯之间构成两个电极,记录的是针尖斜面上很小一块区域内的电位差——这就是针极肌电能够分辨单个运动单位、而表面电极只能看到叠加信号的物理原因。
进针位置是胫骨前肌。这是一块位于小腿前外侧的肌肉,由腓深神经支配,功能是足背屈,在临床上属于针极检查的常规靶肌肉之一,因为表浅、容易定位、患者耐受度相对好。进针后让受试者轻抗阻背屈踝部,这个动作的目的是让运动单位以低到中等频率放电——完全放松时看不到电位,全力收缩时电位重叠成干扰相无法分辨。
接下来一步是「反复调整进针位置直到出现上升时间短的运动单位电位」。上升时间短意味着电极处在运动单位电位的发生源附近,也就是所谓「靠近」的电位,它的形态最锐利、波幅最高、对判断时限最可靠。确认之后连续采集数秒,再嘱受试者放松、拔针。
3.4 信号链路:从 50 kHz 到 4 kHz
采集链路里有一条容易忽略的信息:原始信号以 50 kHz 采样,交付时降到 4 kHz。50 kHz 对针极肌电是合理的,因为单个运动单位电位的尖峰成分很窄,高频成分丰富;而交付时降到 4 kHz,则是为了控制体积——4 kHz 采样对应的奈奎斯特上限是 2 kHz,对绝大多数运动单位电位的主体频率成分仍然足够。
降采样的同时,记录期间使用了两级模拟滤波:20 Hz 高通与 5 kHz 低通。高通抑制的是电极与皮肤界面的极化电位、肌肉缓慢移动造成的基线漂移;低通抑制的是高频噪声与设备本身的电子噪声。低通截止在 5 kHz,与原始 50 kHz 采样配合良好,但降采样到 4 kHz 之后,理论上需要在 2 kHz 处再补一级抗混叠滤波,官方正文没有说明这一步是否做过,也没有给出滤波器类型与阶数。
| 环节 | 官方给出的 | 意味着什么 |
|---|---|---|
| 前端放大 | Medelec Synergy N2 | 设备级固定增益与噪声底 |
| 模拟高通 | 20 Hz | 抑制基线漂移与运动伪迹 |
| 模拟低通 | 5 kHz | 抑制高频噪声 |
| 原始采样 | 50 kHz | 保留尖峰的高频细节 |
| 降采样 | 到 4 kHz | 体积从数十兆级压到百千字节级 |
| 抗混叠 | 未说明 | 2 kHz 以上成分是否混入未知 |
§4 波形里能读出什么:三种状态的对照
4.1 运动单位电位的几个基本量
看懂针极肌电,先要认识一个运动单位电位的形状。典型的电位是一段有多个相位的波形,两端向基线回落,中间有一个或数个尖锐的偏转。临床上量它主要看四件事:时限(从离开基线到回到基线的时间跨度)、波幅(最高峰与最低谷之间的差)、相位数目(波形穿过基线次数加一)、以及上升时间(从起始到第一个峰的时间)。
这四个量分别对应不同的病理改变。肌病时,肌纤维坏死导致单个运动单位覆盖的肌纤维数目减少、排列不齐,于是电位变短、变低、相位增多,形成所谓「短小多相」电位;神经病时,失神经支配的肌纤维被邻近的残存神经重新支配,形成比正常大得多的运动单位,于是电位变宽、变高、相位也可能增多,形成所谓「巨大电位」。
| 参数 | 健康者典型表现 | 肌病典型改变 | 神经病典型改变 |
|---|---|---|---|
| 时限 | 中等 | 缩短 | 延长 |
| 波幅 | 中等 | 降低 | 升高 |
| 相位数目 | 多为三相或四相 | 增多,多相电位比例上升 | 可增多 |
| 上升时间 | 短(靠近电极时) | 受肌纤维分布影响 | 受运动单位扩大影响 |
| 静息电活动 | 静息 | 可有纤颤电位与正锐波 | 纤颤电位与正锐波明显 |
| 募集模式 | 随用力逐渐增多 | 早期即大量募集但幅度低 | 募集减少,频率代偿性增高 |
4.2 三种状态在三段记录里的对应
三段记录的诊断分别是「无神经肌肉疾病史」「长期多发性肌炎所致肌病」「右 L5 神经根病所致神经病」,正好落在上表的三列。需要说明的是,官方只给了诊断名,没有给出电位参数,也没有给出任何定量测量结果。上表里的「典型改变」来自神经电生理的一般知识,不是从这个库的三段记录里统计出来的。
肌病那段的诊断书写为「长期多发性肌炎」,并在注释里补了一句「用激素与低剂量甲氨蝶呤治疗有效」。多发性肌炎是一种以近端肌无力为特征的炎性肌病,病理上表现为肌纤维坏死与炎性浸润,肌电图上典型呈现短小多相电位、纤颤电位与早期募集。注释里的用药信息之所以值得留意,是因为激素与免疫抑制剂本身可能引起类固醇肌病,两种肌病在肌电图上不易区分——这一点在解读这一段时无法排除。
神经病那段的诊断是「慢性下背痛伴右 L5 神经根病所致神经病」。L5 神经根支配胫骨前肌,所以这块肌肉正好是受损神经的靶肌肉,记录位置的选择与诊断是对得上的。神经根病属于神经源性损害,肌电图上期待看到失神经电位、运动单位电位增大、募集减少。
健康那段的诊断只有一句「无神经肌肉疾病史」。这个措辞很临床:它说的是没有已知病史,不是经过完整筛查确认健康。
4.2a 为什么同一块肌肉能反映两种完全不同的病
胫骨前肌之所以被选作针极检查的靶肌肉,除了位置表浅、患者耐受好之外,还因为它的解剖结构让两类病变都能在这一个位置上暴露出来。肌纤维本身是肌病的战场:炎性细胞浸润、肌纤维坏死与再生、肌内膜纤维化,这些改变会让针尖附近的电活动源变小、变得不齐。神经则是神经病的战场:轴索变性、髓鞘脱失、以及随后发生的侧支芽生与再支配,这些改变会让电活动源变大、变得同步。
同一个针尖位置,两种病理机制给出方向相反的波形改变,这正是针极肌电能在临床上区分两者的根本原因。也正因为如此,一块肌肉的选择就足以构成一次完整的教学对照——只要这三段记录确实来自同一种采集流程。
| 病理机制 | 受影响的结构 | 对运动单位的影响 | 波形上的表现 |
|---|---|---|---|
| 肌纤维坏死 | 肌纤维本身 | 单个运动单位覆盖的纤维变少 | 波幅下降、时限缩短 |
| 肌纤维再生与排列不齐 | 肌纤维本身 | 放电不同步,相位离散 | 相位增多、多相比例上升 |
| 轴索变性 | 支配的神经 | 部分运动单位整体失活 | 可见的自发放电、募集减少 |
| 侧支芽生与再支配 | 神经-肌肉接头 | 单个运动单位覆盖的纤维变多 | 波幅升高、时限延长 |
| 传导速度改变 | 神经 | 放电的时间离散度变化 | 电位增宽、尖端变钝 |
上表把两种病理拆成五行,是为了说明一件事:波形的每一个参数都同时在受多个机制影响,单看一个参数无法定论。临床上判读时同时看时限、波幅、相位与募集四项,再结合自发电活动的有无,才形成结论。这也是为什么这三段记录虽然有诊断,却不能被当作「波形到诊断」的映射样本——映射成立的前提是标出了是哪几个参数在起作用,而库里没有这些参数。
4.3 案例:把三段画在同一时间尺度上
这是这个库最实在的用法,也是 §4.1 与 §4.2 两张表能落地的地方。把三段记录的电压都换算成微伏,各自截取一段同样长度的窗口,按上中下三行画在同一张图上,让三段的时间轴对齐、纵轴刻度对齐。
具体做法是先各取前十秒,再统一到一个中位幅度的标尺上。为什么不直接用原始毫伏:三段的针尖位置不同、电极与肌纤维的相对角度不同,绝对幅度本来就不可比;统一标尺是为了让形态差异显出来,而不是掩盖它。
import wfdb
import numpy as np
import matplotlib.pyplot as plt
names = ['emg_healthy', 'emg_myopathy', 'emg_neuropathy']
labels = ['healthy (44M)', 'myopathy (57M)', 'neuropathy (62M)']
colors = ['#4B7F8C', '#9A8C78', '#B08968']
fig, axes = plt.subplots(3, 1, figsize=(10, 6), sharex=True)
for ax, nm, lb, c in zip(axes, names, labels, colors):
rec = wfdb.rdrecord(nm, pn_dir='emgdb')
x = rec.p_signal[:, 0] * 1000.0 #-- 毫伏转微伏
fs = rec.fs
n = min(fs * 10, len(x)) #-- 前十秒,短的记录就取全长
t = np.arange(n) / fs
ax.plot(t, x[:n], lw=0.6, color=c)
ax.set_ylabel('uV')
ax.set_title(lb, loc='left', fontsize=9)
ax.axhline(0, lw=0.4, color='#999999')
axes[-1].set_xlabel('seconds')
fig.tight_layout()
fig.savefig('emgdb_three_states.png', dpi=200)
画出来之后要提醒学生看三件事而不是看波幅:第一,肌病那段在两次放电之间是否残留细小的高频碎波(纤颤电位的线索);第二,神经病那段的单个电位是否明显更宽;第三,三段的基线是否稳定。这三件事都不需要任何定量工具,肉眼即可分辨,正适合作为第一次接触针极肌电的练习。
§4.3 的案例在本文里还会被反复用到:§7.3 讨论偏差时会回到它,说明为什么「三段并排」能教学却不能统计;§9.2 会把同样的读取方式压成一条最短流程;§6.2 会指出库里另外几个肌电数据集为什么画在同一张图上完全对不上。
4.4 为什么不能从这三段里量出参考值
教学用途和参考值用途之间隔着一条统计上的坎。运动单位电位的时限与波幅在同一块肌肉内就随进针位置、针尖与肌纤维的相对角度大幅波动,同一个人不同进针点之间的差异可以接近不同人之间的差异。要建立参考范围,国际上通行的做法是在同一块肌肉上取多个进针点、每点采集多个电位,再按年龄分组统计。
EMGDB 的设计完全不是这个方向:每个受试者只有一个记录文件,记录里没有标明进针位置的改变,也没有给出每次采集之间的间隔。因此这段信号里到底采集了几个不同的针尖位置、每个位置有几个电位,都无从判断。在这样的前提下算出来的均值与标准差,描述的是这段录音,不是这块肌肉,更不是这类人群。
§5 怎么把它拿到手并读进内存
5.1 全量下载
库很小,一次下完即可。两种官方给出的方式都能用。
#-- 方式一:直接抓 ZIP,5.1 MB
cd /tmp
curl -L -o emgdb.zip https://physionet.org/content/emgdb/get-zip/1.0.0/
unzip -o emgdb.zip -d emgdb_1_0_0
ls -lh emgdb_1_0_0
#-- 方式二:用 wget 镜像整个目录
mkdir -p /tmp/emgdb_files
wget -r -N -c -np -P /tmp/emgdb_files https://physionet.org/files/emgdb/1.0.0/
下载完成后先校验一遍,确认 .dat 没在传输里损坏:
cd /tmp/emgdb_1_0_0
sha256sum -c SHA256SUMS.txt
SHA256SUMS.txt 里列了十二个文件,全部应为 OK。若哪个 .dat 报错,重新下载那一个文件即可,不必整包重来。
5.2 读取与单位换算
用 wfdb 是最省事的路径,它自动处理增益、零值与校验和。
import wfdb
import numpy as np
rec = wfdb.rdrecord('emg_healthy', pn_dir='emgdb')
print('fs =', rec.fs)
print('sig_len =', rec.sig_len)
print('seconds =', round(rec.sig_len / rec.fs, 2))
print('channels =', rec.n_sig)
#-- p_signal 单位 mV;转成 uV 更符合针极肌电的阅读习惯
x_uv = rec.p_signal[:, 0] * 1000.0
print('p2p uV =', round(float(np.ptp(x_uv)), 1))
print('rms uV =', round(float(np.sqrt(np.mean(x_uv ** 2))), 1))
for line in rec.comments:
print(line)
rec.comments 输出三行注释;如果只想拿年龄,用正则从第一行里抽数字即可。注意 rec.p_signal 的列顺序在本库只有一个通道,所以取第零列就行。
5.3 不用 wfdb 时的纯 numpy 读法
有时候部署环境里装不上 wfdb,或者只想读一个小库不想带依赖,可以直接解析。单通道、16 位、增益固定,解析只需几行。
import numpy as np
def read_emg(hea_path):
with open(hea_path, encoding='utf-8') as f:
lines = f.read().splitlines()
head = lines[0].split()
sig_line = lines[1].split()
fs = int(head[2])
n = int(head[3])
gain = sig_line[2] #-- 形如 10000/mV
adc_zero = int(sig_line[4])
#-- 最后一个令牌是通道名,倒数第二个是块大小
channel = sig_line[-1]
gain_val = float(gain.split('/')[0]) #-- 单位/毫伏
dat = np.fromfile(hea_path.replace('.hea', '.dat'), dtype='<i2')
if dat.size != n:
raise ValueError(f'采样点数不符: {dat.size} != {n}')
mv = (dat.astype(np.float64) - adc_zero) / gain_val
return fs, channel, mv
fs, ch, x = read_emg('emg_healthy.hea')
print(fs, ch, round(x.min(), 3), round(x.max(), 3))
这段代码按固定顺序取前九个令牌,多出来的那个 16 落在增益与位分辨率之间,不影响读取,因为增益取 sig_line[2]、零值取 sig_line[4]。若改用其他位置索引就要小心,见 §2.2 的说明。
5.4 直接读文本副本
.txt 是两列空格分隔的十进制数,第一列秒、第二列毫伏。numpy 一行即可。
import numpy as np
arr = np.loadtxt('emg_healthy.txt')
t = arr[:, 0]
x = arr[:, 1]
fs_est = 1.0 / (t[1] - t[0])
print('rows =', arr.shape[0])
print('fs from txt =', round(fs_est, 2))
print('span seconds =', round(t[-1], 4))
rows 是 21101,span seconds 约为 5.25 秒——这个数与 .dat 记录的 12.7 秒不一致,说明文本副本只覆盖了二进制文件的一部分而非全部。这是本库一个实实在在的坑:两份文件同名不同长,不要以为 .txt 是 .dat 的完整等价物。
5.5 用命令行工具做一次快速体检
wfdb 附带的命令行工具可以不出 Python 就把头文件看全:
#-- 查看头文件与基本统计
wfdb_head emg_myopathy -p emgdb
wfdb_samp emg_myopathy -p emgdb -s 4000
#-- 列出库内全部记录
wfdb_list --records emgdb
wfdb_head 打出的内容就是 .hea 的原文加上库解析后的字段名,wfdb_samp 的 -s 参数会给出一段范围内的采样统计,适合快速确认幅度量级。
§6 与库内数据集的关系
6.1 关系图谱
这一节要回答的问题很具体:在已经收录的一千三百多个数据集里,EMGDB 与哪些记录会被混为一谈,混在哪里,怎么分。
| 库内记录 | 相同之处 | 关键差异 | 交集判定 |
|---|---|---|---|
| NinaPro(ninapro) | 都记录肌电,都用于上肢或下肢动作相关的电活动 | 表面多通道、手势任务、受试者数十至上百 | 几乎无交集,仅在信号处理手法上可比 |
| GRABMyo(grabmyo) | 同为 PhysioNet 肌电资源 | 表面电极、16 类手势、43 人、9.4 GB | 无交集 |
| GRABMyoFlow(grabmyo-flow) | 同为该平台肌电资源 | 腕部表面电极、动态过渡手势 | 无交集 |
| Hyser(hd-semg) | 都涉及前臂或小腿肌肉的电活动 | 256 通道高密度表面阵列、20 人、142.8 GB | 无交集 |
| EHGDB(ehgdb) | 都是多通道肌电类电生理记录,都在 PhysioNet | 子宫表面肌电、45 名孕妇、200 Hz | 无交集,用途完全不同 |
| TPEHGT(tpehgt) | 同为该平台肌电资源 | 腹部宫缩电、31 条记录 | 无交集 |
| NeBULA(nebula-reaching-eeg) | 都含肌电通道 | 是 EEG 为主的多模态伸手任务集,肌电为辅助 | 无交集 |
| LIVE-GaitNeuroKids(live-gaitneurokids) | 儿科神经步态,含表面肌电 | 四通道表面、59 名儿童、三模态 | 无交集 |
| MIT-BIH 心律失常库(mit-bih-arrhythmia) | 同为 PhysioNet 经典小规模示例库 | 心电图、12 导联、逐搏标注 | 定位相似,信号类型不同 |
| AD FECGDB(adfecgdb) | 同为极小规模示例库 | 腹壁胎心电、5 名产妇 | 定位相似,信号类型不同 |
这张表的核心是第九、十两行:EMGDB 在库内的真正同侪不是那些肌电大库,而是 MIT-BIH 与 AD FECGDB 这类早期小规模示例库。它们都诞生于 PhysioNet 早期,都由临床医师提供,都有明确的教学定位,都因为规模小而从未被当作训练集。
6.2 检索路径
要判断一个引用里说的「PhysioNet 肌电库」到底是哪一个,按下面的顺序查最快:
-- 先按名字与标题捞,肌电的各种写法都要覆盖
select record_id, url_name, left(title, 60)
from ai_ready_dataset
where url_name ilike '%emg%'
or title ilike '%肌电%'
or title ilike '%electromyograph%'
order by record_id;
-- 再看来源字段,确认是不是 PhysioNet
select record_id, url_name, patient_count
from ai_ready_dataset
where source ilike '%PhysioNet%'
and (title ilike '%肌%' or url_name in ('emgdb'))
order by record_id;
第一条会捞到八条记录,其中 emgdb 是本文介绍的这一条,其余七条全部是表面肌电或以表面肌电为辅的多模态数据。区分方法很简单:看 patient_count 与电极类型,只有 emgdb 写的是三名受试者配同心针电极。
§4.3 的案例在这里也能帮上忙:把 EMGDB 的健康段与任何一个表面肌电数据集的单个通道画在一起,会立刻看出两者的基线厚度、尖峰锐利程度与静息期噪声完全不同——这不是采集质量差异,是电极原理差异。
§7 质量评估与局限性
7.0 阅读本节前的一个前置校正
在看到任何评分之前,需要先做一次定性校正:EMGDB 不是一个可以被评分的数据集,它是一个被评分错了也不影响使用的数据集。通常给数据集打分的五个维度——规模、标注、代表性、可复现性、文档——在这里有三项接近零,而这三项为零恰恰是它作为教学材料成立的前提:一段真实临床记录之所以珍贵,正是因为它没有被扩增、没有被标准化、没有被平均化。
因此本节给出的评分必须带一个说明:分数低不等于该弃用,而是说明它不适合按「数据量」这一把尺子衡量。最容易发生误判的地方是把「三段」读成「一个可以外推的样本」,把「带诊断」读成「有标签可用于监督学习」。这两种误判在文献与课程作业里都出现过。
7.1 五维评分
| 维度 | 分数 | 依据 |
|---|---|---|
| 规模 | 1 / 5 | 三段记录、三名受试者、单通道 |
| 标注深度 | 1 / 5 | 只有年龄、性别、诊断三行注释,无事件级或电位级标注 |
| 代表性 | 1 / 5 | 全部男性、单一中心、单一肌肉、单一电极 |
| 可复现性 | 4 / 5 | 全量 5.1 MB、带 SHA-256、许可宽松、无需注册 |
| 文档完整度 | 3 / 5 | 采集流程写得很细,但时长、滤波阶数、降采样细节缺失 |
五维的平均分只有二,但这个平均值本身没有信息量:后两项高,是因为小库容易做完整;前三项低,是因为小库本来就无法做大。真正决定用途的是最后两行——它下载快、环节清楚、可以反复复现,所以适合被写进论文的方法示意图,也适合被放进课程材料。
按 DAIMS 的框架看,这个库的元数据层极其单薄:没有数据字典文件、没有变量定义表、没有采集设备的校准信息、没有版本变更说明。文件本身就承担了全部元数据职能,.hea 的注释行是唯一的临床上下文来源。这与 PhysioNet 后期那些带完整 record-descriptions.txt、files-patients-diagnoses.txt 的库形成了明显代际差异。
7.2 采集链路里那些补不回来的信息
有三件事在现在的文件里已经无法重建,而它们都会影响定量解读。
第一件是降采样的抗混叠滤波。原始 50 kHz 信号做 4 kHz 降采样,理论上需要先限制到 2 kHz 以下。官方正文只提到记录期间的 5 kHz 模拟低通,没有说明数字端的处理。若当时没做抗混叠,1.8 kHz 到 2 kHz 附近的高频噪声会折叠进带内,表现在波形上是尖峰附近出现细碎的高频抖动。教学时这一点不影响形态判断,定量测量峰值或做频谱分析时会引入误差。
第二件是进针位置的完整记录。针尖处在肌腹的哪一层、距离运动终板区多远、与肌纤维走向成多大角度,这些在临床上都会被有经验的医师在报告里描述,而数据库里只剩「置于胫骨前肌」一句。
第三件是受试者状态。皮肤温度、近期活动、是否服用影响神经肌肉传递的药物、检查前是否饮酒,这些都会影响肌电表现。肌病那段记录了用药,健康与神经病两段没有。
7.3 已知的、可枚举的偏差
第一,性别偏差。三名受试者全部为男性。运动单位电位的波幅与时限在两性间存在差异,这一因素在本库里完全无法剥离。
第二,年龄窗口偏差。三段只覆盖四十四岁到六十二岁。儿童、青年、老年的肌电形态在这之外,尤其是高龄人群的运动单位重塑更明显。
第三,肌肉偏差。只有胫骨前肌。这是近端与远端之外的一个特定位置,它由腓深神经支配,属于下肢肌;上肢肌、面部肌、近端大肌群的运动单位电位形态与参数范围都不同。
第四,中心偏差。单家医院、单台设备、单一电极型号。设备的前端噪声与滤波特性会进入每一段记录,换一台设备、换一支针,波形的细节就会变。
第五,病理标签的单一性。肌病只有多发性肌炎一种,神经病只有 L5 神经根病一种。肌病是一大类病(炎性、代谢性、遗传性、药源性),神经病也是(根性、丛性、周围性),每一类的肌电表现并不一致。
第六,诊断的不可复核性。所有诊断都是采集者当时给出的临床判断,数据库里没有病理、影像或随访结果可供交叉验证。
§4.3 的案例在这里正好说明偏差落在哪:三段画在一起时,差异里有病理成分,也有年龄成分、针尖位置成分、设备与个体差异成分,而库内没有任何变量能把它们分开。
7.4 外部验证矩阵
判断一个数据集能不能被外部结果支持,最直接的办法是看有没有独立团队用它做过可复现的实验。对 EMGDB 而言,这一矩阵几乎是空的。
| 验证类型 | 是否存在 | 说明 |
|---|---|---|
| 官方基线模型 | 无 | 官方未提供任何分类或分割基线 |
| 独立团队的定量复现 | 未见到针对本库的 | 针极肌电的公开基准极少,研究多用自有队列 |
| 作为示例出现在方法学论文中 | 可能 | 小库常被用作示意图的来源,但不构成验证 |
| 作为教学材料被课程引用 | 可能 | 公开、许可宽松、体量小,适合课堂 |
| 与临床金标准对照 | 无 | 无可对照的病理或影像结果 |
| 跨中心可比性 | 无 | 单中心单设备 |
这张表的意义在于提醒:用这个库得到任何结论,都没有第二方可以对照。这既是它作为教学材料的优点(不会被别人的结果绑住),也是它作为研究数据集的致命短板。
7.5 它为何能持续:小到可以一直躺在服务器上的教学样本
题海里的数据集大多靠规模活着,越大越有人用,越用越有人添数据,形成正循环。EMGDB 走的是反方向:它之所以能持续存在,是因为它小。5.1 MB 的体量对一个数据仓库的运行成本几乎为零;ODC-BY 的许可让它可以在任何教材、任何课程、任何演示里被自由引用;三段带诊断的真实记录又恰好填上了一个别处很难找到的空白——公开可下载的、来自真人的、针极肌电波形。
它不需要增长,也不会被替代。只要神经内科还在教住院医师看肌电图,就始终需要一组可下载的典型波形;只要针极肌电的数据采集依然有创且依赖医师,这样的小样本就不会被大规模数据取代。它的生存逻辑是「典型性」而不是「代表性」,这两件事在数据集世界里经常被混淆,而它是少数把前者做到位、完全放弃后者的样本。
§8 生态位与历史
8.1 一段十七年的稳定存在
2009 年 PhysioNet 上线这个库时,公开的多通道针极肌电几乎不存在。此后十七年里,数据仓库经历了从几百条记录到几千条记录的膨胀,体量从兆字节级涨到太字节级,但 EMGDB 始终停在 1.0.0 版本、三段记录、五兆字节。文件列表里最新的修改是 2019 年补的校验和清单,信号本身最后一次变化是 2010 年。
这种停滞在数据仓库里并不罕见,但原因各不相同:有的是被更大的版本取代,有的是维护者离场,有的是技术格式过时。EMGDB 不属于这三种,它是从一开始就声明了自己的边界——它是示例,示例不需要增长。
8.2 它在 PhysioNet 早期生态里的位置
看 PhysioNet 早期的条目构成,会发现一个明显的分层。一类是挑战赛用的评测库,比如心律失常库与各类生理信号挑战集,体量大、标注细、有明确的评分脚本;另一类是教学与示例库,体量小、来自单个临床医师、定位是让人快速理解某种信号长什么样。EMGDB 属于后一类,与胎心电、部分脑电示例库同代。
这一代库的共同特征是:文件极少、格式极简、信息集中在头文件的注释行、没有配套的说明文档。它们不是为机器学习设计的,而是为「下载下来看一眼」设计的。理解这一点,就不会拿它们去跟后来的大库比规模。
8.3 针极肌电数据公开难在哪
要把针极肌电做成一个真正可用的公开数据集,需要跨过几道坎,而每一道都比表面肌电难。
第一道是采集。表面电极可以批量采购、批量贴、批量采,一个下午能给几十个人采集;针极必须有执业医师操作,一根针只能给一个人用,每次检查的时间与人力成本都高得多。
第二道是标注。表面肌电的标签是「这段属于哪一类手势」,由实验协议给出;针极肌电的标签是「这个电位的时限是多少、属于哪个运动单位」,需要逐段人工标定,一个熟练的技师标一段几秒的记录也要花不少时间。
第三道是隐私与合规。针极记录虽然只含电信号,但配合诊断与年龄就可以指认个体,去标识化的要求比表面肌电更高。
第四道是临床语境。一段针极记录的意义高度依赖「哪块肌肉、哪个进针点、患者当时在做什么」,丢掉这些上下文,信号就退化成一串电压。
这四道坎解释了为什么公开的针极肌电数据至今仍然稀少,也解释了为什么 EMGDB 这样的示例级数据能占据一个独特位置。
8.4 谁在真的用它
从使用侧看,这个库的主要消费场景有三类。第一类是教学,尤其是住院医师培训与生物医学工程课程里的肌电信号处理单元,教师需要一个真实波形来讲滤波、分割与特征提取。第二类是方法学论文的示意图,作者需要一个公开可引用的例子来说明算法在一段真实信号上的行为。第三类是快速原型,工程师在接一个针极肌电项目之前,先用它把读取、滤波、可视化的管线搭通。
这三类场景的共同点是:都不需要规模,都需要真实性与可引用性。这也是为什么它虽然从未出现在任何基准排行榜里,却一直有稳定的访问量。
§9 使用指引
9.1 三种角色的路径
研究者的路径。 通常不是来做实验的,而是来找一个可引用的实例。最短的路径是:下载 ZIP、校验哈希、用 §5.2 的代码读入、按需要画图或算一个基本统计量,然后引用 DOI 与平台文献。不建议在这条路径上花超过十分钟,因为它的信息量上限就这么大。
教师的路径。 需要的是把三段信号组织成一个能讲十分钟的对照。建议按 §4.3 的案例来做,先把三段画在同一时间尺度上,再分别放大到单个电位讲解。授课时务必说明三点:三段来自三个人、三种状态、同一块肌肉;没有标注;时长各不相同。
工程师的路径。 目标是先把管线跑通。建议的顺序是:先用 .txt 验证读取逻辑(不依赖任何库),再用 wfdb 验证正式路径,最后在自己的框架里写一个适配器,把三段信号转成统一的张量格式。三段的长度不同,适配器需要处理变长序列。
| 角色 | 花多少时间 | 主要产出 | 最容易踩的坑 |
|---|---|---|---|
| 研究者 | 十分钟内 | 一张图、一句引用 | 把示例当训练集 |
| 教师 | 半小时 | 一张三行对照图、一段讲稿 | 忘了说明时长不一致 |
| 工程师 | 一小时 | 一个能读三段的适配器 | 把 .txt 当成完整信号 |
9.2 一条最短的可用流程
从零到拿到三段信号的微伏数组,最少的步骤是下面这几行。它不依赖本地已有文件,直接走远程。
import wfdb
import numpy as np
records = ['emg_healthy', 'emg_myopathy', 'emg_neuropathy']
data = {}
for rid in records:
rec = wfdb.rdrecord(rid, pn_dir='emgdb')
x_uv = rec.p_signal[:, 0] * 1000.0
data[rid] = {
'fs': rec.fs,
'seconds': rec.sig_len / rec.fs,
'p2p_uv': float(np.ptp(x_uv)),
'rms_uv': float(np.sqrt(np.mean(x_uv ** 2))),
'comments': rec.comments,
}
for k, v in data.items():
print(f'{k:16s} {v["seconds"]:6.1f}s p2p={v["p2p_uv"]:8.1f}uV rms={v["rms_uv"]:7.1f}uV')
跑完之后 data 里就是三段的全部可用信息。comments 里带着年龄与诊断,需要做临床分层时从这里取。注意 pn_dir 的写法只给库名,版本默认取最新,本库只有一个版本,所以不会出错。
9.3 引用方式
官方页面要求在引用这个库的同时引用 PhysioNet 平台的标准文献。数据本身由 Seward Rutkove 提供,页面没有给出单独的数据论文。稳妥的引用写法包含三部分:数据集 DOI、提供者与机构、PhysioNet 平台文献。
Rutkove S. Examples of Electromyograms (version 1.0.0).
PhysioNet, 2009. DOI: 10.13026/C24S3D.
Accessed via https://physionet.org/content/emgdb/1.0.0/
PhysioNet platform citation: see the standard citation shown on the
project page (Pollard T. et al., Nature Health, 2026).
在 Methods 里还建议补一句采集参数:4 kHz 交付采样率、20 Hz 高通与 5 kHz 低通、25 毫米同心针、胫骨前肌。这几项能让读者判断结果是否可比。
§10 AI 使用声明
下表说明本篇在哪些环节用了自动化工具、用到什么程度、哪些判断留给人。
| 环节 | 是否使用工具 | 具体做了什么 | 人的复核 |
|---|---|---|---|
| 实体核实 | 是 | 抓取官方项目页正文、文件列表、RECORDS 与三个头文件 |
逐字段比对头文件数值 |
| 规模数字 | 是 | 从文件列表取体积,从头文件取采样点数并换算时长 | 确认换算口径 |
| 结构描述 | 是 | 读取 WFDB 头文件字段顺序与注释行格式 | 判断多出一个令牌的影响 |
| 边界分析 | 部分 | 依据诊断描述与采集条件整理可用范围 | 病理生理部分由人工判断 |
| 库内比对 | 是 | 查询数据集库的标题与来源字段 | 逐条确认电极类型差异 |
| 论文检索 | 是 | 在文献库中检索提供者的相关发表 | 确认未找到专门的数据论文 |
| 中文成文 | 是 | 依据上述材料组织段落与表格 | 通读全文,修订表述 |
| 数值精算 | 否 | 未做任何分布统计、频次统计、空值统计 | — |
| 图片生成 | 否 | 未生成任何图像;封面提示词为文本 | — |
常见误读(避坑清单)
| 常见说法 | 实际 | 证据 |
|---|---|---|
| 「这是 PhysioNet 上最大的肌电库」 | 它是 PhysioNet 上最小的肌电数据集之一,三段记录、5.1 MB | 官方文件列表与各记录头文件 |
| 「它和 NinaPro 一样可以做手势识别」 | 它是单通道针极记录,没有手势任务,也没有手势标签 | 官方正文的采集流程只描述抗阻背屈 |
| 「三段分别对应三类,可以做三分类」 | 三类各一个受试者、一段记录,任何划分都会让某一类缺失 | RECORDS 三行、三个 .hea |
| 「每段只有一两秒钟」 | 头文件换算出来是十二秒多到三十七秒 | 采样点数 50860 / 110337 / 147858 除以 4000 |
「.txt 和 .dat 是同一份东西」 |
文件大小差六到八倍,文本副本只覆盖了前一部分 | 文本共 21101 行,对应约 5.25 秒 |
| 「它带运动单位电位级的标注」 | 无任何标注,只有年龄、性别、诊断三行注释 | 三个 .hea 的注释行 |
| 「四 kHz 采样意味着只有 2 kHz 以内的有效信息」 | 官方记录时用的是 20 Hz 高通加 5 kHz 低通,降采样环节细节未公布 | 官方正文的采集段 |
| 「三个人可以覆盖正常与异常两大类」 | 一位健康、一位肌病、一位神经病,各一人 | 三个 .hea 的诊断行 |
| 「许可要求单独申请」 | ODC-BY 1.0,署名即可,无需注册 | 官方许可栏 |
| 「下载后要先做去均值」 | 头文件已给出 ADC 零值,按增益与零值换算后基线已在零附近 | .hea 第二行的零值与初始值 |
FAQ
Q1:EMGDB 和库里的 NinaPro 是一回事吗?
不是。NinaPro 用贴在前臂表面的电极做数十类手势,受试者上百,目标是假肢控制的模式识别。EMGDB 用刺入肌肉的同心针记录针尖附近的运动单位电位,目标是临床诊断教学,只有三段。
Q2:三段各有多长?
官方只说采集数秒,没有给确切时长。头文件的采样点数除以 4000 赫兹,分别是十二点七秒、二十七点六秒、三十七点零秒。以头文件为准。
Q3:能直接拿来训练分类器吗?
能跑通,但没有意义。三类各一个人,训练与测试无法同时覆盖,报出的任何准确率都反映划分方式而非模型能力。把它用于验证输入管线、画图、教学是对的用法。
Q4:为什么文件名里写的是 mV,数值却很像是微伏?
增益字段写的是每毫伏对应一万个整数单位,也就是一个单位零点一微伏。换算成毫伏后数值很小是正常的,因为针极信号只有几十到几千微伏。
Q5:两个文本文件与二进制文件应该用哪个?
同一份信号的两种存法。二进制加头文件是标准做法,带增益、零值、校验和;文本文件方便快速查看,但只覆盖了信号的前一部分。正式分析用二进制,临时看一眼用文本。
Q6:它的诊断标签是谁给的?
采集者 Seward Rutkove 在当时给出的临床诊断,写在头文件的注释行里。数据库没有附病理或影像结果,诊断无法从文件内部复核。
Q7:能不能用它讨论肌病与神经病的发生率?
不能。三名受试者是刻意挑选出来的示例,不是随机抽样的队列,任何比例都不具代表性。
Q8:降采样到 4 kHz 有没有损失信息?
会损失 2 kHz 以上的成分。对运动单位电位的主体形态影响有限,对尖峰的细节与高频噪声有影响。官方没有说明是否做过数字抗混叠滤波。
Q9:三段来自同一个人的不同时间吗?
不是。三名受试者年龄、性别、诊断各不相同,官方明确列出三人分别属于健康、肌病、神经病。
Q10:引用时要不要单独联系提供者?
不需要。按 ODC-BY 署名即可,同时按官方要求引用 PhysioNet 平台文献。
Q11:能不能再分发打包进自己的教学材料?
ODC-BY 允许,条件是署名。建议同时保留原文件名与 DOI,便于学生回溯。
Q12:为什么它没有随 PhysioNet 的版本升级而扩展?
它的定位是示例集,官方从未表示打算扩充。十七年里只有两轮技术性整理(信号更新与校验和补齐),没有新增记录。
术语表
| 术语 | 英文 | 含义 |
|---|---|---|
| 针极肌电 | needle EMG | 用针电极刺入肌肉内部记录电活动的方法 |
| 同心针电极 | concentric needle electrode | 针管内藏细金属丝,管壁与内芯构成一对电极 |
| 运动单位 | motor unit | 一个运动神经元及其支配的全部肌纤维 |
| 运动单位电位 | motor unit potential, MUP | 单个运动单位放电在针尖处形成的波形 |
| 上升时间 | rise time | 电位起始到首个峰的时间,判断电极是否靠近 |
| 时限 | duration | 电位离开基线到回到基线的时间跨度 |
| 波幅 | amplitude | 电位峰与谷之间的电压差 |
| 相位 | phase | 波形穿过基线的次数加一 |
| 多相电位 | polyphasic potential | 相位超过四个的电位,常见于肌病与神经病 |
| 干扰相 | interference pattern | 多个运动单位同时放电叠加成的密集波形 |
| 募集 | recruitment | 随用力增加而逐步激活更多运动单位的过程 |
| 纤颤电位 | fibrillation potential | 失神经支配的肌纤维自发放电,提示活动性失神经 |
| 正锐波 | positive sharp wave | 另一种自发放电,常与纤颤电位同时出现 |
| 短小多相 | short-duration polyphasic | 肌病的典型电位形态描述 |
| 巨大电位 | giant potential | 神经病再支配后形成的大幅宽电位 |
| 肌病 | myopathy | 病变在肌纤维本身的疾病 |
| 神经病 | neuropathy | 病变在周围神经的疾病 |
| 神经根病 | radiculopathy | 病变在脊神经根的疾病 |
| 胫骨前肌 | tibialis anterior | 小腿前外侧肌,足背屈,腓深神经支配 |
| 腓深神经 | deep peroneal nerve | 支配胫骨前肌的神经 |
| WFDB | Waveform Database | PhysioNet 使用的波形存储规范 |
| 增益 | gain | 每单位电压对应的整数计数 |
| ADC 零值 | ADC zero | 零电平对应的整数计数 |
| 校验和 | checksum | 采样值累加和,用于检查文件完整性 |
| ODC-BY | Open Data Commons Attribution | 要求署名的开放数据许可 |
| 降采样 | downsampling | 降低采样率的处理,需配合抗混叠 |
附录 A:核心数字核对表
| 项 | 值 | 来源 | 来源层级 |
|---|---|---|---|
| 记录数 | 3 | RECORDS 三行 |
官方文件 |
| 受试者数 | 3 | 三个 .hea 的年龄性别诊断行 |
官方文件 |
| 年龄 | 44 / 57 / 62 | 三个 .hea 注释行 |
官方文件 |
| 性别 | 全部男性 | 三个 .hea 注释行 |
官方文件 |
| 交付采样率 | 4000 Hz | .hea 第一行第三字段 |
官方文件 |
| 原始采样率 | 50 kHz | 官方正文 | 官方页面 |
| 高通滤波 | 20 Hz | 官方正文 | 官方页面 |
| 低通滤波 | 5 kHz | 官方正文 | 官方页面 |
| 每段时长 | 12.7 / 27.6 / 37.0 秒 | 采样点数除以采样率 | 官方文件换算 |
| 通道数 | 1 | .hea 第一行第二字段 |
官方文件 |
| 电极 | 25 毫米同心针 | 官方正文与 .hea 注释 |
官方页面 |
| 肌肉 | 胫骨前肌 | 官方正文与 .hea 注释 |
官方页面 |
| 采集设备 | Medelec Synergy N2 | 官方正文 | 官方页面 |
| 体量 | 5.1 MB | 官方文件列表 | 官方页面 |
| 文本副本长度 | 21101 行 | .txt 行数 |
官方文件 |
| 许可 | ODC-BY 1.0 | 官方许可栏 | 官方页面 |
| DOI | 10.13026/C24S3D | 官方 DOI 栏 | 官方页面 |
| 首次发布 | 2009-09-05 | 官方版本栏 | 官方页面 |
附录 B:数字的来源分层
官方页面给出的。 采样率 50 kHz 与 4 kHz、20 Hz 高通、5 kHz 低通、25 毫米同心针、胫骨前肌、轻抗阻背屈、采集数秒、Medelec Synergy N2 系统、三名受试者的年龄性别与诊断、多发性肌炎者的用药、5.1 MB 体量、ODC-BY 1.0 许可、DOI、2009 年 9 月 5 日首发。
由官方文件换算得到的。 每段时长(采样点数除以采样率)、每段信号体积(文件列表)、增益的单位含义(每毫伏一万单位即零点一微伏每单位)、文本副本覆盖的信号长度(行数与采样率)。
未核实或官方未公布的。 降采样是否做数字抗混叠、滤波器阶数与响应、进针深度与针尖坐标、受试者当时的皮肤温度与用力水平、健康者的完整筛查结论、诊断所依据的检查结果、三段记录的具体采集日期。
附录 C:完整参考文献
- PhysioNet. Examples of Electromyograms, version 1.0.0. Bethesda (MD): PhysioNet; 2009. DOI: 10.13026/C24S3D. 数据由 Seward Rutkove(Beth Israel Deaconess Medical Center / Harvard Medical School 神经内科)提供。
- Pollard T, Moody BE, Lehman L, Gow B, Fernandes C, Xie C, Johnson A, Mark RG, Heldt T. PhysioNet as a global platform for biomedical research. Nature Health. 2026. DOI: 10.1038/s44360-026-00096-z.
- Kimura J. Electrodiagnosis in Diseases of Nerve and Muscle: Principles and Practice. 3rd ed. New York: Oxford University Press; 2001.(官方页面推荐读物)
- Reaz MBI, Hussain MS, Mohd-Yasin F. Techniques of EMG signal analysis: detection, processing, classification and applications. Biol Proced Online. 2006;8(1):11-35.(官方页面推荐读物)
- Goldberger AL, Amaral LAN, Glass L, Hausdorff JM, Ivanov PCh, Mark RG, Mietus JE, Moody GB, Peng CK, Stanley HE. PhysioBank, PhysioToolkit, and PhysioNet: components of a new research resource for complex physiologic signals. Circulation. 2000;101(23):e215-e220.(PhysioNet 基础文献)
附录 D:三段记录的速查代码
一份把三段的关键信息一次打印出来的脚本,适合下载完之后跑一遍确认文件完整。
import wfdb
import numpy as np
for rid in ['emg_healthy', 'emg_myopathy', 'emg_neuropathy']:
hdr = wfdb.rdheader(rid, pn_dir='emgdb')
rec = wfdb.rdrecord(rid, pn_dir='emgdb')
x = rec.p_signal[:, 0] * 1000.0
txt = ' | '.join(c for c in rec.comments)
print(f'== {rid}')
print(f' fs={hdr.fs} n={hdr.sig_len} sec={hdr.sig_len / hdr.fs:.2f}')
print(f' p2p={np.ptp(x):.1f}uV rms={np.sqrt(np.mean(x**2)):.1f}uV')
print(f' {txt}')
wfdb.rdheader 只读头文件,比连信号一起读快,适合在下载后先做一次确认。
附录 E:如果只记五件事
- 它是三段针极肌电记录,不是表面肌电,不是手势数据集,不是分类基准。
- 三名男性、三块同一肌肉(胫骨前肌)、三种状态(健康、肌病、神经病),各一段。
- 采样率交付值 4 kHz,来自 50 kHz 降采样,记录时走 20 Hz 高通与 5 kHz 低通。
- 没有任何事件级或电位级标注,只有年龄、性别、诊断三行注释。
- 它的价值在教学与方法示范,不在规模与性能证据。
编辑说明
本篇的事实骨架取自 PhysioNet 项目页正文、文件列表、RECORDS、SHA256SUMS.txt 与三个记录的头文件,核验时间为 2026 年 10 月 28 日。三段时长由头文件采样点数除以采样率换算,官方正文只写到「数秒」;文本副本的长度由行数核对,与二进制文件不一致这一点已在 §5.4 与避坑表中标注。未做任何分布统计、频次统计或空值统计。降采样的抗混叠处理、滤波器阶数、进针坐标、皮肤温度等细节官方未公布,文中一律标注为未公布,未做推测性补全。封面提示词为文本描述,未生成图像。
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- phdsm — 共享标签:生理信号 / 神经科学 / 罕见病
- sgamp — 共享标签:生理信号 / 神经科学
- tremordb — 共享标签:生理信号 / 神经科学
- cardioresp-response-orthostat — 共享标签:生理信号 / 神经科学
- earh — 共享标签:生理信号 / 神经科学
- earndb — 共享标签:生理信号 / 神经科学
- mouse-stroke-cylinder-rearing — 共享标签:生理信号 / 神经科学
- music-motion-2015 — 共享标签:生理信号 / 神经科学
- c-elegans-wholebrain-calcium — 共享标签:生理信号 / 神经科学
- drosophila-wholebrain-2p — 共享标签:生理信号 / 神经科学
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

