使用matlab代碼讀取展示MIT-BIH心律失常數據庫數據(帶註釋)

%*讀取MIT-BIH 心律失常數據庫

%------ SPECIFY DATA ------------------------------------------------------
%------ 指定數據文件 -------------------------------------------------------
PATH= ‘C:\Users\lenovo\Desktop\MITBIH\104’; % 指定數據的儲存路徑
HEADERFILE= ‘104.hea’; % .hea 格式,頭文件,可用記事本打開
ATRFILE= ‘104.atr’; % .atr 格式,屬性文件,數據格式爲二進制數
DATAFILE=‘104.dat’; % .dat 格式,ECG 數據
SAMPLES2READ=3600; % 指定需要讀入的樣本數
% 若.dat文件中存儲有兩個通道的信號:
% 則讀入 2*SAMPLES2READ 個數據

%------ LOAD HEADER DATA --------------------------------------------------
%------ 讀入頭文件數據 -----------------------------------------------------
%
% 示例:用記事本打開的117.hea 文件的數據
%
% 117 2 360 650000
% 117.dat 212 200 11 1024 839 31170 0 MLII
% 117.dat 212 200 11 1024 930 28083 0 V2
% # 69 M 950 654 x2
% # None
%
%-------------------------------------------------------------------------
fprintf(1,’\n$> WORKING ON %s …\n’, HEADERFILE); % 在Matlab命令行窗口提示當前工作狀態
%
% 【注】函數 fprintf 的功能將格式化的數據寫入到指定文件中。
% 表達式:count = fprintf(fid,format,A,…)
% 在字符串’format’的控制下,將矩陣A的實數數據進行格式化,並寫入到文件對象fid中。該函數返回所寫入數據的字節數 count。
% fid 是通過函數 fopen 獲得的整型文件標識符。fid=1,表示標準輸出(即輸出到屏幕顯示);fid=2,表示標準偏差。
%
signalh= fullfile(PATH, HEADERFILE); % 通過函數 fullfile 獲得頭文件的完整路徑
fid1=fopen(signalh,‘r’); % 打開頭文件,其標識符爲 fid1 ,屬性爲’r’–“只讀”
z= fgetl(fid1); % 讀取頭文件的第一行數據,字符串格式
A= sscanf(z, ‘%*s %d %d %d’,[1,3]); % 按照格式 ‘%*s %d %d %d’ 轉換數據並存入矩陣 A 中
nosig= A(1); % 信號通道數目
sfreq=A(2); % 數據採樣頻率
clear A; % 清空矩陣 A ,準備獲取下一行數據
for k=1:nosig % 讀取每個通道信號的數據信息
z= fgetl(fid1);
A= sscanf(z, ‘%*s %d %d %d %d %d’,[1,5]);
dformat(k)= A(1); % 信號格式; 這裏只允許爲 212 格式
gain(k)= A(2); % 每 mV 包含的整數個數
bitres(k)= A(3); % 採樣精度(位分辨率)
zerovalue(k)= A(4); % ECG 信號零點相應的整數值
firstvalue(k)= A(5); % 信號的第一個整數值 (用於偏差測試)
end;
fclose(fid1);
clear A;

%------ LOAD BINARY DATA --------------------------------------------------
%------ 讀取 ECG 信號二值數據 ----------------------------------------------
%
if dformat~= [212,212], error(‘this script does not apply binary formats different to 212.’); end;
signald= fullfile(PATH, DATAFILE); % 讀入 212 格式的 ECG 信號數據
fid2=fopen(signald,‘r’);
A= fread(fid2, [3, SAMPLES2READ], ‘uint8’)’; % matrix with 3 rows, each 8 bits long, = 212bit
fclose(fid2);
% 通過一系列的移位(bitshift)、位與(bitand)運算,將信號由二值數據轉換爲十進制數
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 2
M( : , 1)= (M( : , 1)- zerovalue(1))/gain(1);
M( : , 2)= (M( : , 2)- zerovalue(2))/gain(2);
TIME=(0:(SAMPLES2READ-1))/sfreq;
case 1
M( : , 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<=saa
annoth=bitshift(A(i,2),-2);
if annoth59
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 annoth61
% 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))/sfreq;
ind= find(ATRTIME <= TIME(end));
ATRTIMED= ATRTIME(ind);
ANNOT=round(ANNOT);
ANNOTD= ANNOT(ind);

%------ DISPLAY DATA ------------------------------------------------------
figure(1); %clf, box on, hold on
plot(TIME, M(:,1),‘b’);
plot(M(:,1),‘r’);
if nosig==2
plot(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(’ MLII導聯 / mV’);
string=[‘MIT心律失常ECG原始signal ‘,DATAFILE];
title(string);
fprintf(1,’\nKaTeX parse error: Undefined control sequence: \n at position 28: … DATA FINISHED \̲n̲'); fprintf(1,'…> ALL FINISHED \n’);
ecg1=M(:,1);大家基本都使用的這一列數據,進行實驗,因爲這組數據波形比較好一些。

其中,ATRTIMED爲標註R的時間(單位s),ANNOTD爲ATRTIMED處的標記。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章