EDF存储说明

EDF存储说明EDF 文件的结构 EDF 文件包括 文件头信息 和 数据存储区域 其中 文件头信息 又分为两部分 文件头前半部分 和 文件头后半部分 EDF 头文件信息全部使用 ascll 表示 头文件中每个功能参数描述均使用固定存储长度 相关信息在存储的时候需要左对齐 剩余未使用的空间使用

大家好,我是讯享网,很高兴认识大家。

EDF文件的结构:

EDF文件包括【文件头信息】和【数据存储区域】,其中,【文件头信息】又分为两部分,【文件头前半部分】和【文件头后半部分】。EDF头文件信息全部使用ascll表示,头文件中每个功能参数描述均使用固定存储长度,相关信息在存储的时候需要左对齐,剩余未使用的空间使用‘ ’(字符空格)补齐;

【文件头前半部分】该部分共256字节,记录了采集行为的相关信息,主要包括通道数、采集时间、患者信息、数据总量等信息;

【文件头后半部分】它记录了各个通道的相关参数信息,每个通道的相关参数占用256字节

现在我们假设需要存储4个通道的数据,数据通道名称分别是PPG、EEG、ECG、HR,采样频率分别是100Hz、20Hz、3Hz、3Hz,记录时长100秒,存储软件1秒存一次数据。根据这个需求来解释EDF存储格式。

【文件头前半部分】:

8字节ASCII码:数据格式版本(0),目前我是用版本0做的实验,版本0存储的是int16类型,低字节在前。存储其他类型,例如float先修改格式版本。

80字节ASCII码:病人信息标识,这个根据实际需求填写,没有需求可以随便填。

80字节ASCII码:记录标识,这个没研究明白,暂时随便填吧。

8字节ASCII码:记录开始日期,顺序为日.月.年,用“.”隔开,例如2023年6月21日:21.03.2023

8字节ASCII码:记录开始时间,顺序为时.分.秒 ,格式要求与日期相同

8字节ASCII码:记录头的字节数 ,此部分记录了文件头数据的总长度,总长度=256+256*通道数量=256+256*4=1280(公式中第一个256是文件头前半部分,第二个256是各个通道的相关参数)

44字节ASCII码:保留

8字节ASCII码:文件中数据记录块数nr,该参数用于解析软件计算edf文件的完整性。

8字节ASCII码:一个数据记录块的记录时间

4字节ASCII码:数据记录的通道数(ns)

【文件头后半部分】:

16字节ASCII码:ns*标识(如 PPG)

16字节ASCII码:ns*标识(如 EEG)

16字节ASCII码:ns*标识(如 ECG)

16字节ASCII码:ns*标识(如 HR)

80 字节ASCII码:传感器类型,如对PPG传感器的一个描述,根据需求写

80 字节ASCII码:传感器类型,如对EEG传感器的一个描述,根据需求写

80 字节ASCII码:传感器类型,如对ECG传感器的一个描述,根据需求写

80 字节ASCII码:传感器类型,如对HR传感器的一个描述,根据需求写

8字节ASCII码:物理信号单位,如mV

8字节ASCII码:物理信号单位,如mV

8字节ASCII码:物理信号单位,如%

8字节ASCII码:物理信号单位,如BMP

8字节ASCII码:物理信号最小值

8字节ASCII码:物理信号最小值

8字节ASCII码:物理信号最小值

8字节ASCII码:物理信号最小值

8字节ASCII码:物理信号最大值

8字节ASCII码:物理信号最大值

8字节ASCII码:物理信号最大值


讯享网

8字节ASCII码:物理信号最大值

8字节ASCII码:数字信号最小值,记录数据超过该值设置的大小,EDFbrowser将显示该值,超出部分被削平,其他通道类似

8字节ASCII码:数字信号最小值

8字节ASCII码:数字信号最小值

8字节ASCII码:数字信号最小值

8字节ASCII码:数字信号最大值,记录数据超过该值设置的大小,EDFbrowser将显示该值,超出部分被削平,其他通道类似

8字节ASCII码:数字信号最大值

8字节ASCII码:数字信号最大值

8字节ASCII码:数字信号最大值

80字节ASCII码:滤波器信息

80字节ASCII码:滤波器信息

80字节ASCII码:滤波器信息

80字节ASCII码:滤波器信息

8字节ASCII码:一个数据记录的采样点数,在一个存储块中本通道的数据个数

8字节ASCII码:一个数据记录的采样点数,在一个存储块中本通道的数据个数

8字节ASCII码:一个数据记录的采样点数,在一个存储块中本通道的数据个数

8字节ASCII码:一个数据记录的采样点数,在一个存储块中本通道的数据个数

32字节ASCII码:保留字节

32字节ASCII码:保留字节

32字节ASCII码:保留字节

32字节ASCII码:保留字节

数字信号最大最小值与物理信号最大最小值控制波形在EDFbrowser中Y轴的显示范围。我们自己做解析软件可能用不到。

【数据存储区域】:

第1块存储数据:PPG波形数据+ EEG波形数据+ECG波形数据+HR波形数据

第1块存储数据:PPG波形数据+ EEG波形数据+ECG波形数据+HR波形数据

.

.

.

第n块存储数据:PPG波形数据+ EEG波形数据+ECG波形数据+HR波形数据

Edf文件对字段长度要求非常严格,错一点都不行

最后给出一个基于QT的例程,无论什么语言,明白了存储原理,存储不是问题。

QString edf_appendData(QString data,int total_len) {     QString edf_data;     edf_data.append(data);     qDebug()<<edf_data<<data.size();     for(int i=0;i<(total_len-data.size());i++)     {         edf_data.append(' ');     }     return edf_data; } void MainWindow::EDFwriteData(QDataStream &file_write,qint16 *PPG,qint16 *HuXi,qint16 *SPO2,qint16 *HR) {     int i;     for ( i = 0; i < 100; i++)   //PPG每秒100个数,即100Hz     {         file_write << PPG[i]; // 写入信号采样值到文件     }     for (i = 0; i <20; i++)    //呼吸每秒20个数,即20Hz     {         file_write << *(HuXi+i); // 写入信号采样值到文件         qDebug()<<*(HuXi+i);     }     for (i = 0; i <3; i++)    //血氧每秒3个数,即3Hz     {         file_write << *(SPO2+i); // 写入信号采样值到文件     }     for (i = 0; i <3; i++)  //脉率每秒3个数,即3Hz     {         file_write << *(HR+i); // 写入信号采样值到文件     } } void MainWindow::on_pushButton_clicked() {     // 创建并打开EDF文件     QFile file("exampl.edf");     if (!file.open(QIODevice::WriteOnly))     {         // 文件打开失败处理         return;     }     file.write(edf_appendData("0",8).toUtf8());  //数据格式版本     file.write(edf_appendData("test",80).toUtf8());  //病人信息标识     file.write(edf_appendData("",80).toUtf8());  //记录标识     file.write(edf_appendData("23.04.21",8).toUtf8());        //记录开始日期,用.分割,日、月、年     file.write(edf_appendData("08.30.00",8).toUtf8());        //记录开始时间,用.分割,时分秒     file.write(edf_appendData("1280",8).toUtf8());        //记录头的字节数 总长度=256+256*通道数量     file.write(edf_appendData("",44).toUtf8());        //保留字段。     file.write(edf_appendData("100",8).toUtf8());        //记录块数 如果1秒为一个记录块,那记录块数就是记录总时间     file.write(edf_appendData("1",8).toUtf8());          //每个记录块的时间长度(以秒为单位)。     file.write(edf_appendData("4",4).toUtf8());           //指示EDF文件中的信号通道数量     file.write(edf_appendData("PPG",16).toUtf8());        //信号通道描述     file.write(edf_appendData("EEG",16).toUtf8());       //信号通道描述     file.write(edf_appendData("ECG",16).toUtf8());       //信号通道描述     file.write(edf_appendData("HR",16).toUtf8());         //信号通道描述     file.write(edf_appendData("Private Edition",80).toUtf8());  //传感器类型,即对传感器的描述     file.write(edf_appendData("+1Kpa~-1Kpa",80).toUtf8());  //传感器类型,即对传感器的描述     file.write(edf_appendData("XueYang",80).toUtf8());  //传感器类型,即对传感器的描述     file.write(edf_appendData("MaiLv",80).toUtf8());  //传感器类型,即对传感器的描述     file.write(edf_appendData("mV",8).toUtf8());        //信号通道单位     file.write(edf_appendData("Kpa",8).toUtf8());        //信号通道单位     file.write(edf_appendData("%",8).toUtf8());        //信号通道单位     file.write(edf_appendData("BPM",8).toUtf8());        //信号通道单位     file.write(edf_appendData("0",8).toUtf8());        //每个信号通道的物理最小值     file.write(edf_appendData("0",8).toUtf8());        //每个信号通道的物理最小值     file.write(edf_appendData("0",8).toUtf8());        //每个信号通道的物理最小值     file.write(edf_appendData("0",8).toUtf8());        //每个信号通道的物理最小值     file.write(edf_appendData("1000",8).toUtf8());        //每个信号通道的物理最大值     file.write(edf_appendData("1000",8).toUtf8());        //每个信号通道的物理最大值     file.write(edf_appendData("1000",8).toUtf8());        //每个信号通道的物理最大值     file.write(edf_appendData("1000",8).toUtf8());        //每个信号通道的物理最大值     file.write(edf_appendData("0",8).toUtf8());        //每个信号通道的数字最小值。     file.write(edf_appendData("0",8).toUtf8());        //每个信号通道的数字最小值。     file.write(edf_appendData("0",8).toUtf8());        //每个信号通道的数字最小值。     file.write(edf_appendData("0",8).toUtf8());        //每个信号通道的数字最小值。     file.write(edf_appendData("1000",8).toUtf8());        //每个信号通道的数字最大值。     file.write(edf_appendData("1000",8).toUtf8());        //每个信号通道的数字最大值。     file.write(edf_appendData("1000",8).toUtf8());        //每个信号通道的数字最大值。     file.write(edf_appendData("1000",8).toUtf8());        //每个信号通道的数字最大值。     file.write(edf_appendData("LV BO QI 10Hz",80).toUtf8()); //滤波器信息     file.write(edf_appendData("LV BO QI 20Hz",80).toUtf8()); //滤波器信息     file.write(edf_appendData("LV BO QI 20Hz",80).toUtf8()); //滤波器信息     file.write(edf_appendData("LV BO QI 20Hz",80).toUtf8()); //滤波器信息     file.write(edf_appendData("100",8).toUtf8());       //一个数据记录块的采样点数     file.write(edf_appendData("20",8).toUtf8());       //一个数据记录块的采样点数     file.write(edf_appendData("3",8).toUtf8());       //一个数据记录块的采样点数     file.write(edf_appendData("3",8).toUtf8());       //一个数据记录块的采样点数     file.write(edf_appendData("",32).toUtf8());        //保留字段。     file.write(edf_appendData("",32).toUtf8());        //保留字段。     file.write(edf_appendData("",32).toUtf8());        //保留字段。     file.write(edf_appendData("",32).toUtf8());        //保留字段。     // 创建并写入EDF文件头部     QDataStream out(&file);     out.setByteOrder(QDataStream::LittleEndian); // 根据EDF文件规范,设置字节顺序  设置大小端     qint16 PPG_Buf[100]={0},HuXi_Buf[20]={0},SPO2_Buf[3]={0},HR_Buf[3]={0};     HR_Buf[0]=1;HR_Buf[1]=20;HR_Buf[2]=30;     for(int i=0;i<100;i++)         PPG_Buf[i]=i;     for(int i=0;i<20;i++)         HuXi_Buf[i]=i;     for(int i=0;i<3;i++)         SPO2_Buf[i]=i;     for(int i=0;i<3;i++)         HR_Buf[i]=i*10;     for (int i = 0;i<100;i++)     {        EDFwriteData(out,PPG_Buf,HuXi_Buf,SPO2_Buf,HR_Buf);     }     // 关闭文件     file.close(); }

讯享网

水平有限,如有疏漏、错误,还望海涵。

小讯
上一篇 2025-03-19 15:34
下一篇 2025-03-07 22:05

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/120546.html