MIT-BIH公开数据集下载地址如下:
MIT-BIH Arrhythmia Database v1.0.0 (physionet.org)https://www.physionet.org/content/mitdb/1.0.0/可以知道,心电数据的储存通常通过三个类型的文件,详解参考:
(138条消息) MIT-BIH数据的读取,以及各文件的作用_LLLijiahao的博客-CSDN博客https://blog.csdn.net/qq_40695191/article/details/110846845
matlab代码如下:
国外大神原创(具体叫啥得回来找找- -),可以读取三个类型文件
clc; clear all;
%------ SPECIFY DATA ------------------------------------------------------
%%选择文件名称
stringname='111';
%选择你要处理的信号点数
points=10000;
PATH= 'F:\ECG\MIT-BIH database directory'; % path, where data are saved
HEADERFILE= strcat(stringname,'.hea'); % header-file in text format
ATRFILE= strcat(stringname,'.atr'); % attributes-file in binary format
DATAFILE=strcat(stringname,'.dat'); % data-file
SAMPLES2READ=points; % 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:nosigz= fgetl(fid1);A= sscanf(z, '%*s %d %d %d %d %d',[1,5]);dformat(k)= A(1); % format; here only 212 is allowedgain(k)= A(2); % number of integers per mVbitres(k)= A(3); % bitresolutionzerovalue(k)= A(4); % integer value of ECG zero pointfirstvalue(k)= A(5); % first integer value of signal (to test for errors)
end;
fclose(fid1);
clear A;%------ LOAD BINARY DATA --------------------------------------------------
if dformat~= [212,212], error('this script does not apply binary formats different to 212.'); end;
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);
PRL=bitshift(bitand(A(:,2),8),9); % sign-bit
PRR=bitshift(bitand(A(:,2),128),5); % sign-bit
M( : , 1)= bitshift(M1H,8)+ A(:,1)-PRL;
M( : , 2)= bitshift(M2H,8)+ A(:,3)-PRR;
if M(1,:) ~= firstvalue, error('inconsistency in the first bit values'); end;
switch nosig
case 2M( : , 1)= (M( : , 1)- zerovalue(1))/gain(1);M( : , 2)= (M( : , 2)- zerovalue(2))/gain(2);TIME=(0:(SAMPLES2READ-1))/sfreq;
case 1M( : , 1)= (M( : , 1)- zerovalue(1));M( : , 2)= (M( : , 2)- zerovalue(1));M=M';M(1)=[];sM=size(M);sM=sM(2)+1;M(sM)=0;M=M';M=M/gain(1);TIME=(0:2*(SAMPLES2READ)-1)/sfreq;
otherwise % this case did not appear up to now!% here M has to be sorted!!!disp('Sorting algorithm for more than 2 signals not programmed yet!');
end;
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<=saaannoth=bitshift(A(i,2),-2);if annoth==59ANNOT=[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==63hilfe=bitshift(bitand(A(i,2),3),8)+A(i,1);hilfe=hilfe+mod(hilfe,2);i=i+hilfe/2;elseATRTIME=[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))/sfreq;
ind= find(ATRTIME <= TIME(end));
ATRTIMED= ATRTIME(ind);
ANNOT=round(ANNOT);
ANNOTD= ANNOT(ind);%------ DISPLAY DATA ------------------------------------------------------
figure(1); clf, box on, hold on ;grid on ;
plot(TIME, M(:,1),'r');
if nosig==2plot(TIME, M(:,2),'b');
end;
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');
python代码如下:
##################################################import numpy as np
import matplotlib.pyplot as pltPATH="./MIT-BIH/" #path, 这里就是写刚才你保存的数据地址
HEADERFILE="105.hea" #文件格式为文本格式
ATRFILE="105.atr" #attributes-file 文件以二进制格式
DATAFILE="105.dat" #data-file
SAMPLES2READ=3000 #读取的数据样本点数
####################读取头文件######################
f=open(PATH+HEADERFILE,"r")
z=f.readline().split()
nosig,sfreq=int(z[1]),int(z[2]) #% number of signals,sample rate of datadformat,gain,bitres,zerovalue,firstvalue=[],[],[],[],[]
for i in range(nosig):z=f.readline().split()dformat.append(int(z[1])) #format; here only 212 is allowedgain.append(int(z[2])) #number of integers per mVbitres.append(int(z[3])) #bitresolutionzerovalue.append(int(z[4])) #integer value of ECG zero pointfirstvalue.append(int(z[5])) #first integer value of signal (to test for errors)
f.close()
####################读取dat文件######################
f=open(PATH+DATAFILE,"rb") #以二进制格式读入dat文件
b=f.read()
f.close()A_init=np.frombuffer(b,dtype=np.uint8) #将读入的二进制文件转化为unit8格式
A_shape0=int(A_init.shape[0]/3)
A=A_init.reshape(A_shape0,3)[:SAMPLES2READ] #将A转为3列矩阵M=np.zeros((SAMPLES2READ,2)) #创建矩阵MM2H=A[:,1]>>4 #字节向右移四位,即取字节的高四位
M1H=A[:,1]&15 #取字节的低四位PRL=(A[:,1]&8)*(2**9) #sign-bit 取出字节低四位中最高位,向左移九位,等于乘2^9
PRR=A[:,1]&128<<5 #sign-bit 取出字节高四位中最高位,向左移五位M1H=M1H*(2**8)
M2H=M2H*(2**8)M[:,0]=A[:,0]+M1H-PRL
M[:,1]=A[:,2]+M2H-PRRif ((M[1,:]!=firstvalue).any()):print("inconsistency in the first bit values")if nosig==2:M[:, 0] = (M[:, 0] - zerovalue[0]) / gain[0]M[:, 1] = (M[:, 1] - zerovalue[1]) / gain[1]TIME=np.linspace(0,SAMPLES2READ-1,SAMPLES2READ)/sfreq
elif nosig==1:M2=[]M[:, 0] = M[:, 0] - zerovalue[0]M[:, 1] = M[:, 1] - zerovalue[1]for i in range(M.shape[0]):M2.append(M[:,0][i])M2.append(M[:,1][i])M2.append(0)del M2[0]M2=np.array(M2)/gain[0]TIME=np.linspace(0,2*SAMPLES2READ-1,2*SAMPLES2READ)/sfreq
else:print("Sorting algorithm for more than 2 signals not programmed yet!")
####################读取atr文件######################
f=open(PATH+ATRFILE,"rb") #主要是读取ATR文件中各周期数据并在之后打印在图中
b=f.read()
f.close()A_init=np.frombuffer(b,dtype=np.uint8)
A_shape0=int(A_init.shape[0]/2)
A=A_init.reshape(A_shape0,2)ANNOT,ATRTIME=[],[]
i=0
while i < A.shape[0]:annoth=A[i,1]>>2if annoth==59:ANNOT.append(A[i+3,1]>>2)ATRTIME.append(A[i+2,0]+A[i+2,1]*(2**8)+A[i+1,0]*(2**16)+A[i+1,1]*(2**24))i+=3elif annoth==60:passelif annoth==61:passelif annoth==62:passelif annoth==63:hilfe=(A[i,1]&3)*(2**8)+A[i,0]hilfe=hilfe+hilfe%2i+=int(hilfe/2)else:ATRTIME.append((A[i,1]&3)*(2**8)+A[i,0])ANNOT.append(A[i,1]>>2)i+=1del ANNOT[len(ANNOT)-1]
del ATRTIME[len(ATRTIME)-1]ATRTIME=np.array(ATRTIME)
ATRTIME=np.cumsum(ATRTIME)/sfreqind=np.where(ATRTIME<=TIME[-1])[0]
ATRTIMED=ATRTIME[ind]ANNOT=np.round(ANNOT)
ANNOTD=ANNOT[ind]
#####################显示ECG####################
plt.plot(TIME,M[:,0],linewidth="0.5",c="r")
if nosig==2:plt.plot(TIME, M[:, 1], linewidth="0.5", c="b")
for i in range(len(ATRTIMED)):plt.text(ATRTIMED[i],0,str(ANNOTD[i]))
plt.xlim(TIME[0],TIME[-1])
plt.xlabel("Time / s")
plt.ylabel("Votage / mV")
plt.title("ECG signal ")
plt.show()
python补充解释版参考:
(138条消息) MIT-BIH介绍(三)如何使用MIT-BIH?_Cou流氓也要有文化的博客-CSDN博客_mitbih采样频率https://blog.csdn.net/sinat_34337520/article/details/111869530?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-4.pc_relevant_default&spm=1001.2101.3001.4242.3&utm_relevant_index=7
然鹅,python有一个wfdb的包,可以专门用来读取心电信号233
好的没关系,我们弄懂一些ECG的原理也是好的。
下面开始介绍这个wfdb的包及用法,参考,继续整理:
(138条消息) Python中的WFDB库使用_卷福1995的博客-CSDN博客_python wfdbhttps://blog.csdn.net/weixin_44191286/article/details/86305591
感谢参考:
(37 封私信 / 80 条消息) 如何利用python语言对MIT-BIH数据库里的dat、hea、atr数据进行读取画图? - 知乎 (zhihu.com)https://www.zhihu.com/question/273874101