2
$\begingroup$

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:

enter image description here

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:

enter image description here

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!

$\endgroup$
1
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ 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! $\endgroup$ – Paulo MiraMor Dec 30 '16 at 12:36
  • $\begingroup$ 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. $\endgroup$ – Paulo MiraMor Dec 30 '16 at 20:21
  • $\begingroup$ I updated the post with the two techniques with some code and a graph. I hope it helps. $\endgroup$ – luciano kruk Dec 30 '16 at 22:40
  • $\begingroup$ Wow! Incredible. Thanks a lot. I'll study more to understand the usage of fft. $\endgroup$ – Paulo MiraMor Dec 31 '16 at 19:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.