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 &lt; 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(:)))&gt;1
  error('Input argument DELTA must be a scalar');
end

if delta &lt;= 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 &gt;= mx, mx = this; mxpos = x(i); end 
  else 
    if this &gt;= mx, mx = this; mxpos = x(i); end
    if this &lt; mn, mn = this; mnpos = x(i); end
  end

  if lookformax
    if this &lt; mx-delta
      maxtab = [maxtab ; mxpos mx];
      mn = this; mnpos = x(i);
      lookformax = 0;
    end  
  else
    if this &gt; 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) &gt;= size(mintab,1)
        inicios = maxtab(1:size(mintab,1),1);
        finais = mintab(:,1);
    elseif size(maxtab,1) &lt; 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!
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&lt;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.