ECG-Kit 1.0
(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;