在好例子网,分享、交流、成长!
您当前所在位置:首页MATLAB 开发实例MATLAB语言基础 → MIT-BIH心电信号读取

MIT-BIH心电信号读取

MATLAB语言基础

下载此实例
  • 开发语言:MATLAB
  • 实例大小:7.90KB
  • 下载次数:15
  • 浏览次数:317
  • 发布时间:2019-04-29
  • 实例类别:MATLAB语言基础
  • 发 布 人:JLM2019
  • 文件格式:.m
  • 所需积分:2
 相关标签: 信号 注释详细 初学

实例介绍

【实例简介】
【实例截图】
【核心代码】


% This programm reads ECG data which are saved in format 212.212格式
% (e.g., 100.dat from MIT-BIH-DB, cu01.dat from CU-DB,...)
% 数据与注释一起显示在图形中。
% 注释保存在矢量annot中,相应的时间(以秒为单位)保存在矢量atrtime中。
% 注释被保存为数字,数字的含义可以在www.physinot.org上提供的代码表“ecgcodes.h”中找到。
%
% ANNOT仅包含最重要的信息,该信息与第3行的rdann程序(可在www.physinot.org上获得)一起显示。
% 第4到第6行不保存在注释中。
%
%
%      created on Feb. 27, 2003 by
%      Robert Tratnig (Vorarlberg University of Applied Sciences)
%      (email: rtratnig@gmx.at),
%
%      algorithm is based on a program written by
%      Klaus Rheinberger (University of Innsbruck)
%      (email: klaus.rheinberger@uibk.ac.at)
%
%-------------------------------------------------------------------------
clc; 
%------ SPECIFY DATA ------------------------------------------------------
%------ 指定数据文件 -------------------------------------------------------
PATH= 'D:\matlab2019\111'; % 指定数据的储存路径
HEADERFILE= '111.hea';      % .hea 格式,头文件,可用记事本打开 按ASCII码方式存储
ATRFILE= '111.atr';         % .atr 格式,属性文件,数据格式为二进制数 
DATAFILE='111.dat';         % .dat 格式,ECG 数据 每三个字节存储两个数,一个数12bit 212格式
points=1800;          % 指定需要读入的样本数
                            % 若.dat文件中存储有两个通道的信号:
                            % 则读入 2*points 个数据 

%------ LOAD HEADER DATA --------------------------------------------------
%------ 读入头文件数据 -----------------------------------------------------
%
% 示例:用记事本打开的111.hea 文件的数据
%
% 111 2 360 650000   第一行为记录行,指出该记录为一包含两个采样率为360Hz的信号,每一信号的长度为65万个采样点,采样开始时间和日期没有记录
% 111.dat 212 200 11 1024 1017 20838 0 MLII 两行为信号技术规范说明行,从中可以看出:两个信号都包含在文件格式100.dat中;每一-信号都是以12位的位压缩格式(即212”格式)进行存储的,两个信号的增益都是每200ADC uints/mV, ADC的分辨率大11位,ADC零值为1024,在这里基线值没有明确给出,但可以认为他等于ADC零值1024 两个信号的第一采样点的值分别为1017和1031 (可以看出这他们都略低于0V),65万个采样点的校验数分别为20838和12452,
% 111.dat 212 200 11 1024 1031 12452 0 V1   信号描述字段说明了这两个信号分别采自MLII导联和V1导联
% # 47 F 937 167 x1 最后两行包含了注释字符串,其中第-行说明了患者的性别和年龄以及记录数据
% # Digoxin, Lasix 第二行列出了患者的用药情况
% # There is first degree AV block.  There are short bursts of both baseline
% # shifts and muscle noise, but in general, the quality is excellent.
% 有一级房室传导阻滞。有短脉冲的基线漂移和肌电干扰,但一般来说,质量是很好的。
%-------------------------------------------------------------------------
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'--“只读” fidl=1打开成功,fidl=0打开失败
z= fgetl(fid1);             % 读取头文件的第一行数据,字符串格式 fidl是通过fopen函数打开文件后得到的一个整型的文件标识
A= sscanf(z, '%*s %d %d %d',[1,3]); % 按照格式 '%*s %d %d %d' 转换数据并存入矩阵 A 中 %d就是输出整型 %f就是输出小数 %c就是输出字符串 %s就是输出字符串 加‘*’可以跳过该字段
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);            % 采样精度(位分辨率)11
    zerovalue(k)= A(4);         % ECG 信号零点相应的整数值 1024
    firstvalue(k)= A(5);        % 信号的第一个整数值/第一采样点 (用于偏差测试) 1017 
end;

fclose(fid1);
clear A;

%------ 读取 ECG 信号二值数据 ----------------------------------------------
% 两个通道都要为212格式
if dformat~= [212,212], error('this script does not apply binary formats different to 212.'); 
end;
signald= fullfile(PATH, DATAFILE);            % 读入 212 格式的 ECG 信号数据
fid1=fopen(signald,'r');
A= fread(fid1, [3, points])';  % fread  Read binary data from file.在matlab中只要不指定默认精度为‘uint8’矩阵有3行,每个8位长 = 2*12bit
fclose(fid1);
% 通过一系列的移位(bitshift)、位与(bitand)运算,将信号由二值数据转换为十进制数
M1H= bitand(A(:,2), 15);          %取字节的低四位 15=00001111 67=01000011=43
M2H= bitshift(A(:,2), -4);        %字节向右移四位,即取字节的高四位 
PRL=bitshift(bitand(A(:,2),8),9);     % sign-bit   取出字节低四位中最高位,向右移九位
PRR=bitshift(bitand(A(:,2),128),5);   % sign-bit   取出字节高四位中最高位,向右移五位
y=bitshift(M1H,8)  A(:,1);
M( : , 1)= bitshift(M1H,8)  A(:,1)-PRL;%M1H右移时前面的零舍掉在最后补零成为12位
M( : , 2)= bitshift(M2H,8)  A(:,3)-PRR;%212格式就是像249 67 7,三个字节中存储两个数据,把三个字节写成二进制,把第二个字节的低四位成为第一个12位数据的高四位,第一个字节作为第一个数据的低八位,第二个数据:第二个字节的高四位 第三个字节八位
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:(points-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*(points)-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);      % 带有注释数据的属性文件
fid3=fopen(atrd,'r');
A= fread(fid3, [2, inf])';
fclose(fid3);
ATRTIME=[];
ANNOT=[];
sa=size(A);     %A矩阵大小
saa=sa(1);      %A矩阵有多少行
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;                               %读入.atr文件,按照.atr文件格式一般第一个字节不为0就是MIT格式
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),'r');
if nosig==2
    plot(TIME, M(:,2),'b');
end;
for k=1:length(ATRTIMED)
    text(ATRTIMED(k),0,num2str(ANNOTD(k)));%将数字转换为字符串
end;
grid;
xlim([TIME(1), TIME(end)]);   %给x轴定区间
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');

实例下载地址

MIT-BIH心电信号读取

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警