ECG-Kit 1.0

File: <base>/common/PeakDetection2.m (4,364 bytes)
function peakloc = PeakDetection2(data,fs,varargin)
%
% peaks = PeakDetection2(x,fs,wlen,fp1,fp2,th,flag),
% R-peak detector based on Pan-Tompkins method.
%
% inputs:
% x: vector of input data
% fs: sampling rate
% wlen: moving average window length (default = 150ms)
% fp1: lower cut-off frequency (default = 10Hz)
% fp2: upper cut-off frequency (default = 33.3Hz)
% th: detection threshold (default = 0.2)
% flag: search for positive (flag=1) or negative (flag=0) peaks. By default
% the maximum absolute value of the signal, determines the peak sign.
%
% output:
% peaks: vector of R-peak impulse train
%
%
% Open Source ECG Toolbox, version 2.0, March 2008
% Released under the GNU General Public License
% Copyright (C) 2008  Reza Sameni
% Sharif University of Technology, Tehran, Iran -- GIPSA-Lab, INPG, Grenoble, France
% reza.sameni@gmail.com
% 
% This program is free software; you can redistribute it and/or modify it
% under the terms of the GNU General Public License as published by the
% Free Software Foundation; either version 2 of the License, or (at your
% option) any later version.
% This program is distributed in the hope that it will be useful, but
% WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
% Public License for more details.
% 
% See also ECGtask_QRS_detection
% 
% Adapted by Mariano Llamedo Soria llamedom@electron.frba.utn.edu.ar 
% to ecg-kit toolbox for Matlab.
% Version: 0.1 beta
% Last update: 14/5/2014
% Birthdate  : 21/4/2015
% Copyright 2008-2015
% 

if(nargin>2  && ~isempty(varargin{1})),
    winlen = varargin{1};
else
    winlen = .150; % 150ms
end

if(nargin>3 && ~isempty(varargin{2})),
    fp1 = varargin{2};
else
    fp1 = 10;
end

if(nargin>4  && ~isempty(varargin{3})),
    fp2 = varargin{3};
else
    fp2 = 33.3;
end

if(nargin>5  && ~isempty(varargin{4})),
    thr = varargin{4};
else
    thr = 0.2;
end

if(nargin>6  && ~isempty(varargin{5})),
    flag = varargin{5};
else
    flag = abs(max(data))>abs(min(data));
end


N = length(data);
data = data(:);

L1 = round(fs/fp2);    % first zero of the LP filter is placed at f = 33.3Hz;
L2 = round(fs/fp1);    % first zero of the HP filter is placed at f = 3Hz;

fprintf(1, '.');

% x0 = data - Median(data',N,round(fs*winlen/3));

q = ceil(fs/150);
N_padded = (ceil(N / q) * q);
data = [data; zeros(N_padded-N,1)];
data = data - resample(MedianFilt(resample(data,1,q), round(fs*winlen/3/q)), q, 1);
data = data(1:N);
% x0 = data;

fprintf(1, '.');

% LP filter
x = filter([1 zeros(1,L1-1) -1],[L1 -L1],data);
x = filter([1 zeros(1,L1-1) -1],[L1 -L1],x);
x = [x(L1:end);zeros(L1-1,1) + x(end)]; % lag compensation

fprintf(1, '.');

% HP filter
y = filter([L2-1 -L2 zeros(1,L2-2) 1],[L2 -L2],x);

% differentiation
z = diff([y(1) ; y]);

% squaring
w = z.^2;

fprintf(1, '.');

% moving average
L3 = round(fs*winlen);
v = filter([1 zeros(1,L3-1) -1],[L3 -L3],w);
v = [v(round(L3/2):end);zeros(round(L3/2)-1,1) + v(end)]; % lag compensation

vmax = max(v);
p = v > (thr*vmax);

fprintf(1, '.');

% edge detection
rising  = find(diff([0 ; p])==1);      % rising edges
falling = find(diff([p ; 0])==-1);     % falling edges

if( length(rising) == length(falling)-1 ),
    rising = [1 ; rising];
elseif( length(rising) == length(falling)+1 ),
    falling = [falling ; N];
end

fprintf(1, '.');

peakloc = zeros(length(rising),1);
width = zeros(length(rising),1);

Nrising = max(1, length(rising)/20);
j = 0;

if(flag)
    for i=1:length(rising)
        
        if( j > Nrising)
            fprintf(1, '.');
            j = 0;
        else
            j = j + 1;
        end
        
        [val mx] = max( data(rising(i):falling(i)) );
        peakloc(i) = mx - 1 + rising(i);
        width(i) = falling(i) - rising(i);
    end
else
    for i=1:length(rising)
        if( j > Nrising)
            fprintf(1, '.');
            j = 0;
        else
            j = j + 1;
        end
        
        [val mn] = min( data(rising(i):falling(i)) );
        peakloc(i) = mn - 1 + rising(i);
        width(i) = falling(i) - rising(i);
    end
end
fprintf(1, '\n');

% peaks = zeros(1,N);
% peaks(peakloc) = 1;