深入浅出理解 EDF 文件协议

深入浅出理解 EDF 文件协议 —— 从脑电图到呼吸机的通用生理数据标准

一、为什么要了解 EDF?

在生理信号采集领域(如 EEG、ECG、EMG、呼吸机、睡眠监测等),**EDF(European Data Format)**是最常见的数据交换标准之一。

它的设计目标非常朴素:

“让不同设备厂商采集的生理信号数据可以在相同的软件中打开与分析。”

换句话说,EDF 是医疗信号界的“CSV”,但比 CSV 更严格、更结构化,也更能描述信号的时间语义。


二、EDF 文件的总体结构

EDF 文件由两部分组成:

  1. Header(头部):描述整个文件和每个信号的元信息
  2. Data Records(数据记录):存储真正的采样数据

一个 EDF 文件就像一本有目录的小说:

  • “目录”(Header)告诉你书的标题、章节数量、每章的页数;
  • “正文”(Data Records)则是每个通道的实际采样值。

文件整体布局

区块名称长度说明
Header固定头部 + 每个信号的头部可变(通常 256 + N×256 字节)描述数据的结构
Data Records信号采样值序列不定按时间片顺序存放所有信号的采样数据

三、EDF Header 结构详解

EDF 的头部信息都是 ASCII 文本(非二进制),固定宽度字段排列。
前 256 字节为通用头部,接着是每个信号的详细描述。

1️⃣ 通用头部(前 256 字节)

字节位置字段名长度示例说明
0–7版本号80 EDF 标识,固定为 0
8–87病人信息80Patient X可包含 ID、性别、出生日期等
88–167记录信息80Start of recording可包含采集者、医院、备注等
168–175起始日期812.11.25dd.mm.yy
176–183起始时间814.30.59hh.mm.ss
184–191Header 长度86144 字节数(=256 + 信号数×256)
192–207保留字段16空白保留
208–215数据记录数量86000 文件中时间片数
216–223每个记录时长(秒)81.000000每条记录持续的时间
224–231信号通道数4–83信号数量,如 EEG、ECG、O2

2️⃣ 信号头部(每个信号 256 字节)

每个通道(signal)都有一组 16 个字段,每个字段都是定长 ASCII。

字节偏移(每通道)字段名长度示例说明
0–15信号标签16EEG Fpz-Cz通道名
16–31传感器类型80microvolt单位或描述
32–47物理最小值8-200单位下的最小值
48–63物理最大值8200单位下的最大值
64–79数字最小值8-32768A/D 转换后的最小值
80–95数字最大值832767A/D 转换后的最大值
96–103预过滤信息80HP:0.1Hz LP:75Hz滤波描述
176–183每记录采样点数8256采样率相关
184–255保留80保留字段

这些字段共同定义了“如何从二进制数据恢复真实物理量”。


四、Data Records 的存储方式

EDF 的数据记录是交织式存储(interleaved):

记录1: [信号1样本][信号2样本][信号3样本]
记录2: [信号1样本][信号2样本][信号3样本]
...

每个信号的数据以 16-bit 二进制(2 字节/采样点) 存储,采用小端序(little-endian)。

举个例子:

假设每个记录持续 1 秒,文件有 3 个信号:

  • EEG:256 Hz
  • ECG:256 Hz
  • O2:1 Hz

则:

  • 每个记录包含 256 + 256 + 1 = 513 个采样点
  • 每个采样点 2 字节
  • 每个记录总大小为 1026 字节

五、从原始字节到实际信号值

每个采样点的原始值是整数(digital value),范围由 数字最小/最大 字段定义。
要恢复物理值(例如 mV 或 L/min),需要进行线性变换:

[
\text{Physical Value} = \frac{(\text{Digital} - D_{min})}{D_{max} - D_{min}} \times (P_{max} - P_{min}) + P_{min}
]

这一步是设备标定信息在 EDF 中最重要的体现。


六、快速实践:用 Python 读取 EDF 文件

Python 有现成库可以直接读取 EDF,比如 pyedflib

import pyedflib

edf_path = "data/patient001_sleep.edf"
f = pyedflib.EdfReader(edf_path)

print("信号数量:", f.signals_in_file)
print("信号标签:", f.getSignalLabels())

# 读取第一个通道的数据
signal_index = 0
data = f.readSignal(signal_index)

print(f"通道 {signal_index} 样本数量:", len(data))
print("采样率:", f.getSampleFrequency(signal_index))

输出示例:

信号数量: 3
信号标签: ['EEG Fpz-Cz', 'EEG Pz-Oz', 'ECG']
通道 0 样本数量: 307200
采样率: 256.0

七、EDF+:事件与注释的增强版

EDF 后来发展出了 EDF+ 标准,增加了“注释信号”(annotation signals)。
这允许你在文件中记录诸如:

  • 患者入睡时间
  • 设备报警事件
  • 呼吸暂停开始/结束

这类信息以专门的“Annotation Channel”信号存放在同一个文件中。
解析时只需识别标签为 "EDF Annotations" 的通道即可。


八、在呼吸机数据中的应用思路

如果你正在构建呼吸机或睡眠监测系统,EDF 可作为数据交换或报告归档格式

可以将以下信息封装进 EDF:

  • 通道1:流量 (Flow, L/min)
  • 通道2:压力 (Pressure, cmH₂O)
  • 通道3:潮气量 (VT, mL)
  • 通道4:漏气量 (Leak, L/min)

再加上 EDF+ 注释记录报警时间、模式切换事件等。

这样,医疗专家或算法团队就能使用标准 EEG 分析工具直接打开你的文件。


九、小结

特性说明
文件类型二进制混合 ASCII
通用性广泛用于 EEG/ECG/EMG/呼吸信号
可扩展性通过 EDF+ 支持注释
易解析有成熟的 Python/Matlab 工具库
适合场景医疗设备数据归档、跨系统交换、信号分析

🔚 十、参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值