MIT-BIH 是由美国麻省理工学院提供的研究心律失常的数据库。目前国际上公认的可作为标准的心电数据库有三个,分别是美国麻省理工学院提供的MIT-BIH 数据库,美国心脏学会的AHA数据库以及欧洲AT-T心电数据库。其中MIT-BIH 数据库近年来应用比较广泛。

        MIT-BIH 是由美国麻省理工学院提供的研究心律失常的数据库。目前国际上公认的可作为标准的心电数据库有三个,分别是美国麻省理工学院提供的MIT-BIH 数据库,美国心脏学会的AHA数据库以及欧洲AT-T心电数据库。其中MIT-BIH 数据库近年来应用比较广泛。

        MIT-BIH 的数据格式:

        MIT-BIH 为了节省文件长度和存储空间,使用了自定义的格式。一个心电记录由三个部分组成:

(1)头文件[.hea],存储方式ASCII码字符

(2)数据文件[.dat],按二进制存储,每三个字节存储两个数,一个数12bit。

(3)注释文件[.art],按二进制存储。

[.hea]为头文件,其由一行或多行ASCII码字符组成。以100.hea为例

100 2 360 650000

100.dat 212 200 11 1024 995 -22131 0 MLII

100.dat 212 200 11 1024 1011 20052 0 V5

# 69 M 1085 1629 x1

# Aldomet, Inderal

        第一行为记录行,指出该记录为一包含两个采样率为360Hz的信号,每一信号的长度为65万个采样点,采样开始时间和日期没有记录。后面紧跟的两行为信号技术规范说明行,从中可以看出,两个信号都包含在文件格式100.dat中,每一信号都是以12位的位压缩格式(即“212”格式)进行存储的,两个信号的增益都是每200ADC uints/mV,ADC的分辨率为11位,ADC零值为1024,在这里基线值没有明确给出,但可以认为他等于ADC零值1024。两个信号的第一采样点的值分别为995和1011(可以看出这他们都略低于0V),65万个采样点的校验数分别为-22131和20052,输入输出可以以任何尺寸的块来执行,因为文件内容说明了这两个信号的该值都为0,信号描述字段说明了这两个信号分别采自MLII导联和V5导联。文件的最后两行包含了注释字符串,其中第一行说明了患者的性别和年龄以及记录数据,第二行列出了患者的用药情况。(MIT—BIH心率失常数据库的识读及应用,宋喜国,中国医学物理学杂志,2004年7月第21卷第4期)

        [.dat]为数据文件,MIT-BIH数据库中的数据存储格式有Format8、Format16、Format80、Format212、Format310等8种,心律失常数据库统一采用212格式进行存储。

        “212”格式是针对两个信号的数据库记录,这两个信号的数据交替存储,每三个字节存储两个数据。假设这两个数据分别采样自信号0和信号1,信号0的采样数据取自第一、二字节(16位)的高12位,其中第一字节作为低8位,第二字节的高4位作为其高4位;信号1的采样数据由第二字节的低4位(作为组成信号1采样数据的12位的高4位)和下一字节的8位(作为组成信号1采样数据的12位的低8位)共同组成。以100.dat为例。

 

        按照“212”的格式,从第一字节读起,每三个字节(24 位)表示两个值,第一组为“E3 33 F3”,两个值则分别为0x3E3和0x3F3转换为十进制分别为995和1011,代表的信号幅度分别为4.975mv和5.055mv,这两个值分别是两个信号的第一采样点,后面依此类推,分别表示了两个信号的采样值。

        “.atr”为注释文件,记录了心电专家对相应的心电信号的诊断信息,主要有两种格式:MIT格式和AHA格式。MIT格式是一种紧凑型格式,每一注释的长度占用偶数个字节空间,多数情况下是占用两个字节,多用于在线的注释文件;而AHA格式的每一注释占用16个字节的空间,多用于交换文件的情况。这两种格式的在文件中的区分决定于前两个字节的值,若文件的第一字节不为0或第二字节等于“[”(0x5B)或“]”(0x5D),则该文件是以MIT格式存储的,否则是按AHA格式存储的。心律失常数据库采用的MIT格式。

        MIT格式,每一注释单元的前两个字节的第一个字节为最低有效位,16位中的最高6位表示了注释类型代码(具体代码见后表),剩余的10位说明了该注释点的发生时间或辅助信息,若为发生时间,其值为该注释点到前一注释点的间隔(对于第一个注释点为从记录开始到该点的间隔),若为辅助信息则说明了附加信息的长度。以100.atr为例。

        从文件中的第一字节不为0可以判断该文件是以MIT格式存储的。从第一字节开始按照MIT格式进行分析,首先读出16位值0x7012,其高6位的值为0x1C(十进制28),低10位的值为0x12,该类型代码为28,代表意义是节律变化,发生时间在0.05秒(18/360Hz);接着读出后面的16位值0xFC03,其高6为的值为0x3F(十进制63),低10位的值为0x03,该类型代码为63,代表的意义是在该16位值后附加了3个(低10位值代表的数)字节的辅助信息,若字节个数为奇数,则再附加一个字节的空值,在本例中就是“28 4E 00 00”;然后再从下一字节读16位值0x043B,其高6位的值为1,低10位的值为0x3B(十进制59),该类型码1代表正常心搏,发生时间为0.213秒((18+59)/360Hz);依次类推即可读出所有的注释,当读到的16位值为0时,就表示到了文件尾。

        另,当高6位为十进制59时,读取之后第3个16位的高6位,作为类型代码,读取之后第二个16位+第一个16位*2^16;

高6位为十进制60,61,62时,继续读下一个16位。

注释代码

说明

0

No TQRS

1

N

Normal beat

正常搏动

2

L

Left bundle branch block beat

左束支传导阻滞

3

R

Right bundle branch block beat

右束支传导阻滞

4

a

Aberrated atrial premature beat

异常房性早搏

5

V

Premature ventricular contraction

室性早搏

6

F

Fusuion of ventricular and normal beat

心室融合心跳

7

J

Nodal (junctional) premature beat

交界性早搏

8

A

Atrial premature beat

房性早搏

9

S

Premature or ectopic supraventricular beat

室上性早搏或异常

10

E

Ventricular escape beat

室性逸搏

11

j

Nodal (junctional) escape beat

交界性逸搏

12

/

Paced beat

起搏心跳

13

Q

Unclassifiable beat

未分类心跳

14

~

Signal quality change

  信号质量发生变化

15

Not specified

16

|

Isolated QRS-like artifact

孤立的类QRS伪迹  

17

Not specified

18

s

ST change

19

T

T-wave change

20

*

Systole

21

D

Diastole

22

"

Comment annotation

23

=

Measurement annotation

24

p

P-wave peak

25

B

Left or right bundle branch block

26

^

Non-conducted pacer spike

27

t

T-wave peak

28

+

Rythm change

29

u

U-wave peak

30

?

Learning

31

!

Ventricular flutter wave

32

[

Start of ventricular flutter/fibrillation

33

]

End of ventricular flutter/fibrillation

34

e

Atrial escape beat

35

n

Supraventricular espace beat

36

Not specified

37

x

Non-conducted P-wave (blocked APB)

38

f

Fusion of paced and normal beat

39

(

Waveform onset, PQ junction(begin of QRS)

40

)

Waveform end, JPT(J point, end of QRS)

41

r

R-on-T premature ventricular contraction

第二部分:读取代码


  1. % This programm reads ECG data which are saved in format 212.
  2. % (e.g., 100.dat from MIT-BIH-DB, cu01.dat from CU-DB,...)
  3. % The data are displayed in a figure together with the annotations.
  4. % The annotations are saved in the vector ANNOT, the corresponding
  5. % times (in seconds) are saved in the vector ATRTIME.
  6. % The annotations are saved as numbers, the meaning of the numbers can
  7. % be found in the codetable "ecgcodes.h" available at www.physionet.org.
  8. %
  9. % ANNOT only contains the most important information, which is displayed
  10. % with the program rdann (available on www.physionet.org) in the 3rd row.
  11. % The 4th to 6th row are not saved in ANNOT.
  12. %
  13. %
  14. %      created on Feb. 27, 2003 by
  15. %      Robert Tratnig (Vorarlberg University of Applied Sciences)
  16. %      (email: rtratnig@gmx.at),
  17. %
  18. %      algorithm is based on a program written by
  19. %      Klaus Rheinberger (University of Innsbruck)
  20. %      (email: klaus.rheinberger@uibk.ac.at)
  21. %
  22. % -------------------------------------------------------------------------
  23. clc; clear all;
  24. %------ SPECIFY DATA ------------------------------------------------------
  25. PATH= 'E:\2.课题资料\3.09-10年初项目计划——特异性诊断指标挖掘\4.MIT-BIH'; % path, where data are saved
  26. HEADERFILE= '105.hea';      % header-file in text format
  27. ATRFILE= '105.atr';         % attributes-file in binary format
  28. DATAFILE='105.dat';         % data-file
  29. SAMPLES2READ=3000;         % number of samples to be read
  30.                             % in case of more than one signal:
  31.                             % 2*SAMPLES2READ samples are read
  32. %------ LOAD HEADER DATA --------------------------------------------------
  33. fprintf(1,'\\n$> WORKING ON %s ...\n', HEADERFILE);
  34. signalh= fullfile(PATH, HEADERFILE);
  35. fid1=fopen(signalh,'r');
  36. z= fgetl(fid1);
  37. A= sscanf(z, '%*s %d %d %d',[1,3]);
  38. nosig= A(1);  % number of signals
  39. sfreq=A(2);   % sample rate of data
  40. clear A;
  41. for k=1:nosig
  42.     z= fgetl(fid1);
  43.     A= sscanf(z, '%*s %d %d %d %d %d',[1,5]);
  44.     dformat(k)= A(1);           % format; here only 212 is allowed
  45.     gain(k)= A(2);              % number of integers per mV
  46.     bitres(k)= A(3);            % bitresolution
  47.     zerovalue(k)= A(4);         % integer value of ECG zero point
  48.     firstvalue(k)= A(5);        % first integer value of signal (to test for errors)
  49. end;
  50. fclose(fid1);
  51. clear A;
  52. %------ LOAD BINARY DATA --------------------------------------------------
  53. if dformat~= [212,212], error('this script does not apply binary formats different to 212.'); end;
  54. signald= fullfile(PATH, DATAFILE);            % data in format 212
  55. fid2=fopen(signald,'r');
  56. A= fread(fid2, [3, SAMPLES2READ], 'uint8')';  % matrix with 3 rows, each 8 bits long, = 2*12bit
  57. fclose(fid2);
  58. M2H= bitshift(A(:,2), -4);        %字节向右移四位,即取字节的高四位
  59. M1H= bitand(A(:,2), 15);          %取字节的低四位
  60. PRL=bitshift(bitand(A(:,2),8),9);     % sign-bit   取出字节低四位中最高位,向右移九位
  61. PRR=bitshift(bitand(A(:,2),128),5);   % sign-bit   取出字节高四位中最高位,向右移五位
  62. M( : , 1)= bitshift(M1H,8)+ A(:,1)-PRL;
  63. M( : , 2)= bitshift(M2H,8)+ A(:,3)-PRR;
  64. if M(1,:) ~= firstvalue, error('inconsistency in the first bit values'); end;
  65. switch nosig
  66. case 2
  67.     M( : , 1)= (M( : , 1)- zerovalue(1))/gain(1);
  68.     M( : , 2)= (M( : , 2)- zerovalue(2))/gain(2);
  69.     TIME=(0:(SAMPLES2READ-1))/sfreq;
  70. case 1
  71.     M( : , 1)= (M( : , 1)- zerovalue(1));
  72.     M( : , 2)= (M( : , 2)- zerovalue(1));
  73.     M=M';
  74.     M(1)=[];
  75.     sM=size(M);
  76.     sM=sM(2)+1;
  77.     M(sM)=0;
  78.     M=M';
  79.     M=M/gain(1);
  80.     TIME=(0:2*(SAMPLES2READ)-1)/sfreq;
  81. otherwise  % this case did not appear up to now!
  82.     % here M has to be sorted!!!
  83.     disp('Sorting algorithm for more than 2 signals not programmed yet!');
  84. end;
  85. clear A M1H M2H PRR PRL;
  86. fprintf(1,'\\n$> LOADING DATA FINISHED \n');
  87. %------ LOAD ATTRIBUTES DATA ----------------------------------------------
  88. atrd= fullfile(PATH, ATRFILE);      % attribute file with annotation data
  89. fid3=fopen(atrd,'r');
  90. A= fread(fid3, [2, inf], 'uint8')';
  91. fclose(fid3);
  92. ATRTIME=[];
  93. ANNOT=[];
  94. sa=size(A);
  95. saa=sa(1);
  96. i=1;
  97. while i<=saa
  98.     annoth=bitshift(A(i,2),-2);
  99.     if annoth==59
  100.         ANNOT=[ANNOT;bitshift(A(i+3,2),-2)];
  101.         ATRTIME=[ATRTIME;A(i+2,1)+bitshift(A(i+2,2),8)+...
  102.                 bitshift(A(i+1,1),16)+bitshift(A(i+1,2),24)];
  103.         i=i+3;
  104.     elseif annoth==60
  105.         % nothing to do!
  106.     elseif annoth==61
  107.         % nothing to do!
  108.     elseif annoth==62
  109.         % nothing to do!
  110.     elseif annoth==63
  111.         hilfe=bitshift(bitand(A(i,2),3),8)+A(i,1);
  112.         hilfe=hilfe+mod(hilfe,2);
  113.         i=i+hilfe/2;
  114.     else
  115.         ATRTIME=[ATRTIME;bitshift(bitand(A(i,2),3),8)+A(i,1)];
  116.         ANNOT=[ANNOT;bitshift(A(i,2),-2)];
  117.    end;
  118.    i=i+1;
  119. end;
  120. ANNOT(length(ANNOT))=[];       % last line = EOF (=0)
  121. ATRTIME(length(ATRTIME))=[];   % last line = EOF
  122. clear A;
  123. ATRTIME= (cumsum(ATRTIME))/sfreq;
  124. ind= find(ATRTIME <= TIME(end));
  125. ATRTIMED= ATRTIME(ind);
  126. ANNOT=round(ANNOT);
  127. ANNOTD= ANNOT(ind);
  128. %------ DISPLAY DATA ------------------------------------------------------
  129. figure(1); clf, box on, hold on
  130. plot(TIME, M(:,1),'r');
  131. if nosig==2
  132.     plot(TIME, M(:,2),'b');
  133. end;
  134. for k=1:length(ATRTIMED)
  135.     text(ATRTIMED(k),0,num2str(ANNOTD(k)));
  136. end;
  137. xlim([TIME(1), TIME(end)]);
  138. xlabel('Time / s'); ylabel('Voltage / mV');
  139. string=['ECG signal ',DATAFILE];
  140. title(string);
  141. fprintf(1,'\\n$> DISPLAYING DATA FINISHED \n');
  142. % -------------------------------------------------------------------------
  143. fprintf(1,'\\n$> ALL FINISHED \n');

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐