I have to detect repetitions in a signal, and I am managing to do it by finding peaks and valleys, and cutting the desired pieces. The following figure shows the pattern wanted, shaded areas are the portions of interest:
The problem is: some of the signals that I'm analyzing, instead of starting with a constant zero, show a very smooth decline, as shown in the following figure:
As a consequence, a peak is detected as one of the first values, and the first repetition is detected wrongly. I'm looking for suggestions to avoid it. I have already tried (not sure if correctly):
- Using derivatives (
diff) to detect inclination.
- Using a robust regression (
robustfit) and finding inclination by the coefficients - too slow.
I'm using a MATLAB code created by someone else, modified by me (original can be found here):
function repeticoes = peakdet(v, delta, x) %PEAKDET Detect peaks in a vector % [MAXTAB, MINTAB] = PEAKDET(V, DELTA) finds the local % maxima and minima ("peaks") in the vector V. % MAXTAB and MINTAB consists of two columns. Column 1 % contains indices in V, and column 2 the found values. % % With [MAXTAB, MINTAB] = PEAKDET(V, DELTA, X) the indices % in MAXTAB and MINTAB are replaced with the corresponding % X-values. % % A point is considered a maximum peak if it has the maximal % value, and was preceded (to the left) by a value lower by % DELTA. % Eli Billauer, 3.4.05 (Explicitly not copyrighted). % This function is released to the public domain; Any use is allowed. maxtab = ; mintab = ; v = v(:); % Just in case this wasn't a proper vector if nargin < 3 x = (1:length(v))'; else x = x(:); if length(v)~= length(x) error('Input vectors v and x must have same length'); end end if (length(delta(:)))>1 error('Input argument DELTA must be a scalar'); end if delta <= 0 error('Input argument DELTA must be positive'); end mn = Inf; mx = -Inf; mnpos = NaN; mxpos = NaN; lookformax = 1; for i=1:length(v)-1 this = v(i); if isempty(maxtab) if this >= mx, mx = this; mxpos = x(i); end else if this >= mx, mx = this; mxpos = x(i); end if this < mn, mn = this; mnpos = x(i); end end if lookformax if this < mx-delta maxtab = [maxtab ; mxpos mx]; mn = this; mnpos = x(i); lookformax = 0; end else if this > mn+delta mintab = [mintab ; mnpos mn]; mx = this; mxpos = x(i); lookformax = 1; end end end if size(maxtab, 1) == 0 inicios = ; finais = ; elseif size(maxtab,1) >= size(mintab,1) inicios = maxtab(1:size(mintab,1),1); finais = mintab(:,1); elseif size(maxtab,1) < size(mintab,1) inicios = maxtab(:,1); finais = mintab(1:size(maxtab, 1),1); else disp('Erro ao reconhecer repeticoes!') end repeticoes = [inicios finais]; end
Any suggestions are welcome!