# How to detect peaks ignoring soft declivity?

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!

## 1 Answer

You mentioned that you have tried the signal derivative to catch the declines. What problems have you faced?

It seems that your problem might be addressed with different words: Let $s(t)$ be your signal, and let $u(t)=ds(t)/dt$. You want a detector to indicate when $a\le u(t)\le b$, with $a,b<0$, for at least $T$ seconds.

If this rewrite of the problem is true, the challenge now is to calculate $u(t)$. You can use u=diff(s), as you mentioned if the signal $s(t)$ has no noise, or you need to estimate $u(t)$ using other techniques like these two for instance.

• Well, I did something similar to what you suggested, without the "a" variable, and failed to determine a proper "b". I'll retry to do it with your suggestions and give a feedback. Thanks! – Paulo MiraMor Dec 30 '16 at 12:36
• It turns out that the derivation did not work by any method because the signal is noisy - I also tried five-point stencil derivation, but most of the output was flat. Besides, I tried to implement the fft method in the link that you provided, but I'm new to fft and signal processing and could not implement any of the suggested methods in the link. I also tried some filtering without any success. – Paulo MiraMor Dec 30 '16 at 20:21
• I updated the post with the two techniques with some code and a graph. I hope it helps. – luciano kruk Dec 30 '16 at 22:40
• Wow! Incredible. Thanks a lot. I'll study more to understand the usage of fft. – Paulo MiraMor Dec 31 '16 at 19:56