matlab gui

这个MATLAB代码实现了一个手动检查GUI,用于处理心电图数据。通过打开CSV文件,它能过滤信号并检测峰值。用户可以通过接受或拒绝峰值来选择心跳,并将结果保存。该GUI包含按钮来浏览、接受、拒绝心电图峰值,并具有键盘快捷键操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

function varargout = manual_check(varargin)
% MANUAL_CHECK MATLAB code for manual_check.fig
%      MANUAL_CHECK, by itself, creates a new MANUAL_CHECK or raises the existing
%      singleton*.
%
%      H = MANUAL_CHECK returns the handle to a new MANUAL_CHECK or the handle to
%      the existing singleton*.
%
%      MANUAL_CHECK('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in MANUAL_CHECK.M with the given input arguments.
%
%      MANUAL_CHECK('Property','Value',...) creates a new MANUAL_CHECK or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before manual_check_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to manual_check_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES


% Edit the above text to modify the response to help manual_check


% Last Modified by GUIDE v2.5 29-Oct-2014 11:41:26


% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @manual_check_OpeningFcn, ...
                   'gui_OutputFcn',  @manual_check_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end


if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT




% --- Executes just before manual_check is made visible.
function manual_check_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to manual_check (see VARARGIN)


% Choose default command line output for manual_check
handles.output = hObject;


% Update handles structure
guidata(hObject, handles);


% UIWAIT makes manual_check wait for user response (see UIRESUME)
% uiwait(handles.figure1);




% --- Outputs from this function are returned to the command line.
function varargout = manual_check_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% Get default command line output from handles structure
varargout{1} = handles.output;




% --- Executes on button press in bt_open.
function bt_open_Callback(hObject, eventdata, handles)
% hObject    handle to bt_open (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global signal peaks current nbeats foldername filename accepted rejected rejectpoint


[filename,foldername,~] = uigetfile('*.csv');


if isequal(filename,0)|| isequal(foldername,0)
    return;
end
set(handles.txt_filename, 'String', filename);


rawdata = csvread(strcat(foldername,'\',filename));
filtered = ECG_filter(rawdata);
signal = filtered(64:end);
peaks = ECG_Peak_Detection(signal);


if(peaks(1)<64)
    peaks(1) = [];
end
if(peaks(end)>length(signal)-96)
    peaks(end) = 0;
end


nbeats = length(peaks);
accepted = [];
rejected = 0;
current = 1;
if(nbeats<1)
    return;
elseif(nbeats>1)
    set(handles.bt_next,'Enable', 'on');
end
set(handles.bt_previous,'Enable', 'off');
set(handles.bt_open,'Enable', 'off');


%set(handles.bt_accept,'Enable', 'on');
%set(handles.bt_reject,'Enable', 'on');








axes(handles.axes1);         
OneBeat = plot(1:160, signal(peaks(1)-63:peaks(1)+96),'b-', 64,signal(peaks(1)), 'r^' );
set(handles.axes1,'XLim',[0 160]);
set(handles.axes1,'YLim',[-15000 25000]);
set(handles.txt_total,'String',num2str(nbeats));
set(handles.txt_current,'String',num2str(1));
set(handles.txt_accepted,'String',num2str(0));
set(handles.txt_rejected,'String',num2str(0));




rejectpoint = zeros(1,length(signal));


for i=1:length(peaks)
    rejectpoint(peaks(i))=1;
end




function txt_filename_Callback(hObject, eventdata, handles)
% hObject    handle to txt_filename (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% Hints: get(hObject,'String') returns contents of txt_filename as text
%        str2double(get(hObject,'String')) returns contents of txt_filename as a double




% --- Executes during object creation, after setting all properties.
function txt_filename_CreateFcn(hObject, eventdata, handles)
% hObject    handle to txt_filename (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called


% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end




% --- Executes on button press in bt_accept.
function bt_accept_Callback(hObject, eventdata, handles)
% hObject    handle to bt_accept (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global accepted current peaks
accepted = [accepted;peaks(current)];
current = current+1;
set(handles.txt_accepted, 'String', num2str(length(accepted)));
if strcmp(get(handles.bt_previous,'Enable'), 'off')
    set(handles.bt_previous,'Enable', 'on')
end
if(current > length(peaks))
    save(accepted);
    set(handles.bt_next,'Enable', 'off');
    set(handles.bt_previous,'Enable', 'off');
    set(handles.bt_accept,'Enable', 'off');
    set(handles.bt_reject,'Enable', 'off');
    set(handles.bt_open,'Enable', 'on');
else
    showBeat(current,handles);
end




% --- Executes on button press in bt_reject.
function bt_reject_Callback(hObject, eventdata, handles)
% hObject    handle to bt_reject (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global accepted current peaks rejected 
current = current+1;
rejected = rejected + 1;
set(handles.txt_rejected, 'String', num2str(rejected));
if strcmp(get(handles.bt_previous,'Enable'), 'off')
    set(handles.bt_previous,'Enable', 'on')
end
if(current > length(peaks))
    save(accepted);
    set(handles.bt_next,'Enable', 'off');
    set(handles.bt_previous,'Enable', 'off');
    set(handles.bt_accept,'Enable', 'off');
    set(handles.bt_reject,'Enable', 'off');
    set(handles.bt_open,'Enable', 'on');
else
    showBeat(current,handles);
end




% --- Executes on button press in bt_previous.
function bt_previous_Callback(hObject, eventdata, handles)
% hObject    handle to bt_previous (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global current accepted
if (current>1)
    current = current-1;
    accepted(end) = [];
    showBeat(current,handles);
end
if(current==1)
    accepted(end) = [];
    showBeat(current,handles);
    set(handles.bt_previous,'Enable', 'off');   %%%%%%%%%%%%%%%%%modify
end


% --- Executes on button press in bt_next.
function bt_next_Callback(hObject, eventdata, handles)
% hObject    handle to bt_next (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


global current peaks num signal


len = 1360;


if(current==1)
    current =2;
end


num=0;




if (current<length(peaks))   % solve the edge problem
    num =0;
    
    
    while(peaks(current+num)+96<peaks(current)+len-63)
        
        num=num+1;
        if(current+num == length(peaks))
            current=current -1
            break
        end  
    end
    
    
    
    
                      
    showBeat(current,handles);
    axes1_ButtonDownFcn(handles.axes1, [], handles)
    current = current+num;
end












% --- Executes on key press with focus on figure1 or any of its controls.
function figure1_WindowKeyPressFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  structure with the following fields (see FIGURE)
% Key: name of the key that was pressed, in lower case
% Character: character interpretation of the key(s) that was pressed
% Modifier: name(s) of the modifier key(s) (i.e., control, shift) pressed
% handles    structure with handles and user data (see GUIDATA)


switch eventdata.Key
    case 'uparrow'
        bt_accept_Callback(handles.bt_accept, [], handles);
    case 'downarrow'
        bt_reject_Callback(handles.bt_reject, [], handles);
    case 'leftarrow'
        bt_previous_Callback(handles.bt_previous, [], handles);
    case 'rightarrow'
        bt_next_Callback(handles.bt_next, [], handles);
end


% --- Executes on mouse press over axes background.
function axes1_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to axes1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


%axes1_ButtonDownFcn(handles.axes1, [], handles)


global pointX current peaks rejectpoint num


hold on
disp('单击鼠标左键点取需要的点');


but=1;
while but==1
    dist =[];
    [xi,yi,but]=ginput(1);
    if (yi<-1.5)
        break
    end
    plot(xi,yi,'bo')
    
    for i=1:num+1
        dist =[dist norm(xi-pointX(i))];   %judge the nearest point base on x-label
    end
    
    [C,I]=min(dist);
    I
    rejectpoint(peaks(current+I))= -1 ;
end


hold off




% --- Executes on button press in pushbutton11.
function pushbutton11_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton11 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global rejectpoint


xlswrite('label.csv', rejectpoint')  %write the data into file


%%%%%%---------------------------- subroutines ----------------------%%%%%%
function [] = save(accepted)
global signal foldername filename peaks
    accepted = unique(accepted);
    data = [-ones(length(signal),1)*32768,signal];
    data(accepted,1) = 1;
    [~,name,~] = fileparts(filename); 
    csvwrite(strcat(foldername,name,'_chked.csv' ),data);
    fid = fopen(strcat(foldername,'\summary.txt'),'a+');
    fprintf(fid, '%26s %6d %6d %8.2f \n', name, length(peaks),length(accepted),length(accepted)/length(peaks));
    fclose(fid);
    
function [] = showBeat(current,handles)
global signal peaks pointX pointY num
    axes(handles.axes1);  
    
%     
%     current
%     num
%     
    
    s = signal(peaks(current)-63:peaks(current+num)+96);  %show one more peak = num +1
    
    s = detrend(s);
    
    len = length(s); %indicate the size of the windows can change
    
    p = [];          %p store the x-value of each peaks
    pointX = [64];
    pointY= [s(64)];
    for i=current:current+num
    p = [p peaks(i+1)-peaks(current)+64];  %sizeof p = num+1
    end
    
%     length(p)
    
    hold off
    
    plot(1:len, s(1:len),'b-')
    
    hold on
    
    for k= 1:num
        pointX = [pointX p(k)] ;
        pointY = [pointY s(p(k))];
        
    end
    
%     length(pointX)    %size = num +1
%     pointX
    
    
    
    for kk= 1:num
        plot(pointX(kk),pointY(kk),'r^')% plot the peak point
    end
    
    plot(pointX(num+1),pointY(num+1),'g^') %plot the first peak in the next frame
    
    
    Asort=sort(pointY); 
    
    
    set(handles.axes1,'XLim',[0 len]);
    %set(handles.axes1,'YLim',[-15000 25000]);
    set(handles.axes1,'YLim',[-15000 Asort(length(Asort)-0)*1.1]);
    set(handles.txt_current,'String',num2str(current));
           
    
function [filtered] = ECG_filter(rawdata)
% band pass fir filter, order:127, pass band: [3Hz ~ 40Hz]
fir_coef = fir1(127,[1.0/125,40/125]);
ecgFir = filter(fir_coef, 1, rawdata);
ecgFirDc = filter(ones(1,128)./128, 1, ecgFir);
filtered = ecgFir - ecgFirDc;


function peak = ECG_Peak_Detection(ECG_raw)


    %%% parameter setting
    Fs               = 250;          % sampling frequency
    Sig_max          = 5000;
    Sig_min          = 0.0;


    hpf_len          = 40;
    bpf_len          = 42;
    lpf_len          = 11;  
    QRSwindow        = round(240*Fs/1000);    %240ms
    MIN_QRS_interval = 240*Fs/1000;           %240ms
    local_max_window_len = 15;


    % coefficient for threshold update
    coef_thr_udt_k  = .5;           
    coef_thr_udt_b  = .1;           


    % coefficient for threshold min update
    coef_thr_min_a  = 0.05; %0.005;
    coef_thr_min_b  = 0.95;
    coef_thr_min_c  = 1-coef_thr_min_b;
    coef_thr_min_d  = 0.2;


    % coefficient for ecg_lpf_max/min_lim
    coef_ecg_lpf_max_lim = 0.1;
    coef_ecg_lpf_min_lim = 0.1;




    %%% Initialization
    % coef_bpf = fir1(bpf_len-1,[10 25]/(Fs/2));  
    % coef_lpf = fir1(lpf_len-1, 10/Fs/2);
    coef_bpf = [0.0013    0.0007    0.0001   -0.0001    0.0005    0.0025    0.0057    0.0089    0.0097    0.0052   -0.0065   -0.0251   -0.0470   -0.0657   -0.0735   -0.0642   -0.0359    0.0075    0.0566    0.0993    0.1240    0.1240    0.0993    0.0566    0.0075   -0.0359   -0.0642    -0.0735   -0.0657   -0.0470   -0.0251   -0.0065    0.0052    0.0097    0.0089    0.0057     0.0025    0.0005   -0.0001    0.0001    0.0007    0.0013];
    coef_lpf = [0.0144    0.0304    0.0724    0.1245    0.1668    0.1830    0.1668    0.1245    0.0724    0.0304    0.0144];




    ECG_hpf         = zeros(size(ECG_raw));
    ECG_bpf         = zeros(size(ECG_raw));
    ECG_abs         = zeros(size(ECG_raw));
    ECG_lpf         = zeros(size(ECG_raw));


    thr_c           = 0;            % current threshold
    thr_n           = 0;            % next threshold
    thr_p1          = 0;            % 1st previous threshold
    thr_p2          = 0;            % 2nd previous threshold


    thr_hist        = zeros(size(ECG_raw));                     % history of threshold


    QRS_raw         = zeros(ceil(size(ECG_raw)/QRSwindow));     % QRS (R-peak) index for raw ECG data
    QRS_lpf         = zeros(ceil(size(ECG_raw)/QRSwindow));     % QRS (R-peak) index for lpf ECG data
    QRS_num         = 0;


    newQRS          = 0;




    ecg_lpf_max_lim  = coef_ecg_lpf_max_lim*(Sig_max-Sig_min);
    ecg_lpf_min_lim  = coef_ecg_lpf_min_lim/(Sig_max-Sig_min);


    thr_min          = coef_thr_min_a*(Sig_max-Sig_min);
    thr_min_hist = zeros(size(ECG_raw));


    %%% ECG algorithm start
    for i=2:length(ECG_raw)/QRSwindow-2
        newQRS  = 0;
        index_s = (i-1)*QRSwindow+1;        % start index for i-th processing unit
        index_e = i*QRSwindow;              % end   index for i-th processing unit


        % threshold calculation
        thr_p2   = thr_p1;
        thr_p1   = thr_c;
        thr_c    = thr_p1 - coef_thr_udt_k*(thr_p1 - thr_min) - coef_thr_udt_b*( thr_p1 - thr_p2 );
        thr_n    = thr_c  - coef_thr_udt_k*(thr_c  - thr_min) - coef_thr_udt_b*( thr_c  - thr_p1 );


        thr_hist(index_s:index_e) = thr_c - (thr_c-thr_n)./(QRSwindow+1).*[0:QRSwindow-1];
        thr_min_hist(index_s:index_e) = thr_min;


        % R-peak (QRS) detection
        % high pass filtering
        for j=0:QRSwindow-1
            ECG_hpf(index_s+j) = ECG_raw(index_s+j) - mean( ECG_raw([-floor(hpf_len/2)+1:ceil(hpf_len/2)]+index_s+j) );
        end    


        % band pass filtering
        for j=0:QRSwindow-1
    %         fprintf('%d, %d\n', length(coef_bpf), length(ECG_raw( [-floor(bpf_len/2)+1:ceil(bpf_len/2)]+index_s+j)));
            ECG_bpf(index_s+j) = coef_bpf * ECG_raw( [-floor(bpf_len/2)+1:ceil(bpf_len/2)]+index_s+j);
        end    


        % differentiation and abs operation
        ECG_abs(index_s:index_e) = abs( ECG_bpf(index_s:index_e) - ECG_bpf(index_s-1:index_e-1) );


        % low pass filtering
        for j=0:QRSwindow-1       
            ECG_lpf(index_s+j) = coef_lpf * ECG_abs([-floor(lpf_len/2)+1:ceil(lpf_len/2)]+index_s+j);        
        end


        [ecg_lpf_max_val, ecg_lpf_max_idx] = max(ECG_lpf(index_s:index_e));
        ecg_lpf_max_idx                   = ecg_lpf_max_idx + index_s - 1;


        % Start of R-peak (QRS) detection
        if (QRS_num == 0) || (ecg_lpf_max_val > thr_hist(ecg_lpf_max_idx))         
            [local_max_val, local_max_idx] = max( ECG_hpf([-local_max_window_len:local_max_window_len]+ecg_lpf_max_idx));
            local_max_idx                 = local_max_idx + ecg_lpf_max_idx - (local_max_window_len+1);


            [local_min_val, local_min_idx] = min( ECG_hpf([-local_max_window_len:local_max_window_len]+ecg_lpf_max_idx));
            local_min_idx                 = local_min_idx + ecg_lpf_max_idx - (local_max_window_len+1);


            if local_max_val*2 < abs(local_min_val)
                Rpeak_idx_tmp = local_min_idx;
                Rpeak_val_tmp = ECG_raw(local_max_idx);
            else
                Rpeak_idx_tmp = local_max_idx;
                Rpeak_val_tmp = ECG_raw(local_min_idx);
            end


            if QRS_num == 0
                newQRS          = 1;
                QRS_num         = QRS_num+1;
            elseif Rpeak_idx_tmp - QRS_raw(QRS_num) > MIN_QRS_interval
                newQRS          = 1;
                QRS_num         = QRS_num+1;
            elseif ecg_lpf_max_val > ecg_lpf_max_val_p
                newQRS          = 1;
            end
        end 


        if newQRS == 1
            QRS_lpf(QRS_num)    = ecg_lpf_max_idx;
            QRS_raw(QRS_num)    = Rpeak_idx_tmp;  
            thr_c               = ECG_lpf(ecg_lpf_max_idx);
            ecg_lpf_max_val_p   = ecg_lpf_max_val;


            if ecg_lpf_max_lim > ecg_lpf_max_val > ecg_lpf_min_lim
                thr_min = coef_thr_min_b*thr_min + coef_thr_min_c*coef_thr_min_d*ecg_lpf_max_val;
            end
        end
    end     


    peak = QRS_raw(1:QRS_num);






        





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值