引自https://blog.youkuaiyun.com/xxty1122/article/details/78105896
暑假实习搞了一段时间的深度的学习,公司老总让我把MIT-BIH的数据按着给的注释文件读出来,并且分类,为此我可是耗费了好长时间整理了这个程序供大家参考。闲话不多说,我交代下这个程序的作用:
1.把R波作为101点,向前取100点,向后取199个点,构成300点,作为一个心电周期(采样率为360HZ,所以300点完全可以保证一个心电周期)
2.按着数据名+第n个R波+疾病(N:正常,V:心律异常,O:其他)来命名
3.保存成txt格式,和无坐标轴的png格式。
代码如下:
clc; clear all; %这个程序可以一次性把48个数据都分类。 %------ SPECIFY DATA ------------------------------------------------------ PATH= 'S:\MIT'; % path, where data are saved下载下来的心电数据 d = dir('S:\MIT\*.dat'); a = dir('S:\MIT\*.atr'); v= dir('S:\MIT\*.hea'); l=2;%1为MLII通道,2为VI通道 for c=1:length(d) HEADERFILE= v(c).name; % header-file in text format ATRFILE= a(c).name; % attributes-file in binary format DATAFILE=d(c).name; % data-file SAMPLES2READ=660000; % number of samples to be read % in case of more than one signal: % 2*SAMPLES2READ samples are read %------ LOAD HEADER DATA -------------------------------------------------- fprintf(1,'\\n$> WORKING ON %s ...\n', HEADERFILE); signalh= fullfile(PATH, HEADERFILE); fid1=fopen(signalh,'r'); z= fgetl(fid1); A= sscanf(z, '%*s %d %d %d',[1,3]); nosig= A(1); % number of signals sfreq=A(2); % sample rate of data clear A; for k=1:nosig z= fgetl(fid1); A= sscanf(z, '%*s %d %d %d %d %d',[1,5]); dformat(k)= A(1); % format; here only 212 is allowed gain(k)= A(2); % number of integers per mV bitres(k)= A(3); % bitresolution zerovalue(k)= A(4); % integer value of ECG zero point firstvalue(k)= A(5); % first integer value of signal (to test for errors) end fclose(fid1); clear A; signald= fullfile(PATH, DATAFILE); % data in format 212 fid2=fopen(signald,'r'); A= fread(fid2, [3, SAMPLES2READ], 'uint8')'; % matrix with 3 rows, each 8 bits long, = 2*12bit fclose(fid2); M2H= bitshift(A(:,2), -4); %字节向右移四位,即取字节的高四位 M1H= bitand(A(:,2), 15); %取字节的低四位 M( : , 1)= bitshift(M1H,8)+ A(:,1); %低四位向左移八位 M( : , 2)= bitshift(M2H,8)+ A(:,3); %高四位向左移八位 M = (M-1024)/200; %这个M就是咱们解码出来的数据 clear A M1H M2H PRR PRL; fprintf(1,'\\n$> LOADING DATA FINISHED \n'); %------ LOAD ATTRIBUTES DATA ---------------------------------------------- atrd= fullfile(PATH, ATRFILE); % attribute file with annotation data fid3=fopen(atrd,'r'); A= fread(fid3, [2, inf], 'uint8')'; fclose(fid3); ATRTIME=[]; ANNOT=[]; sa=size(A); saa=sa(1); i=1; while i<=saa annoth=bitshift(A(i,2),-2); if annoth==59 ANNOT=[ANNOT;bitshift(A(i+3,2),-2)]; ATRTIME=[ATRTIME;A(i+2,1)+bitshift(A(i+2,2),8)+... bitshift(A(i+1,1),16)+bitshift(A(i+1,2),24)]; i=i+3; elseif annoth==60 % nothing to do! elseif annoth==61 % nothing to do! elseif annoth==62 % nothing to do! elseif annoth==63 hilfe=bitshift(bitand(A(i,2),3),8)+A(i,1); hilfe=hilfe+mod(hilfe,2); i=i+hilfe/2; else ATRTIME=[ATRTIME;bitshift(bitand(A(i,2),3),8)+A(i,1)]; ANNOT=[ANNOT;bitshift(A(i,2),-2)]; end i=i+1; end ANNOT(length(ANNOT))=[]; % last line = EOF (=0) ATRTIME(length(ATRTIME))=[]; % last line = EOF clear A; ATRTIME= (cumsum(ATRTIME)); %用来存放注释R波的位置。 ind= find(ATRTIME <= SAMPLES2READ); ATRTIMED= ATRTIME(ind); ANNOT=round(ANNOT); ANNOTD= ANNOT(ind); %------ DISPLAY DATA ------------------------------------------------------ figure(1); clf, box on, hold on for k=1:length(ATRTIMED) text(ATRTIMED(k),0,num2str(ANNOTD(k))); end %xlim([TIME(1), TIME(end)]); xlabel('Time / s'); ylabel('Voltage / mV'); string=['ECG signal ',DATAFILE]; title(string); fprintf(1,'\\n$> DISPLAYING DATA FINISHED \n'); % ------------------------------------------------------------------------- fprintf(1,'\\n$> ALL FINISHED \n'); %-----------------------保存数据---------------- len1=length(ATRTIME); for t=4:len1-3 %保存分割的数据,前三个和后三个都不要 str=num2str(t,'%04d'); if(ANNOT(t)==1) %心电异常分类 z=78; else if(ANNOT(t)==28) z=86; else z=79; end end fd=num2str(c); name=['S:\MIT-txt\',v(c).name(1:end-4) '-' str, '-' z,'.txt']; %文件命名 fid=fopen(name,'wt'); f=100;%向前取100点 b=199;%向后取100点 m1=ATRTIME(t)-f; m2=ATRTIME(t)+b; n=1; for e=m1:1:m2 fprintf(fid,'%5.3f\n',M(e,l)); end figure; plot(M(m1:m2,l)); set(gcf,'visible','off'); axis off; saveas(gcf,['S:\MIT-png\', v(c).name(1:end-4) '-' str, '-' z,'.png'])%图片命名 delete(gcf); fclose(fid); end end