如何检测忽略软倾斜的峰?

信息处理 matlab 峰值检测
2022-02-03 18:14:30

我必须检测信号中的重复,我设法通过找到峰值和谷值并切割所需的部分来做到这一点。下图显示了想要的图案,阴影区域是感兴趣的部分:

在此处输入图像描述

问题是:我正在分析的一些信号,不是从一个恒定的零开始,而是显示出非常平滑的下降,如下图所示:

在此处输入图像描述

结果,峰值被检测为第一值之一,并且错误地检测到第一重复。我正在寻找避免它的建议。我已经尝试过(不确定是否正确):

  • 使用导数 ( diff) 检测倾斜度。
  • 使用稳健回归 ( robustfit) 并通过系数找到倾向 - 太慢了。

我正在使用由其他人创建并由我修改的 MATLAB 代码(可以在此处找到原始代码):

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

欢迎任何建议!

1个回答

您提到您已尝试使用信号导数来捕捉下跌。你遇到过什么问题?

您的问题似乎可以用不同的词来解决:让s(t)成为你的信号,让u(t)=ds(t)/dt. 您希望检测器指示何时au(t)b, 和a,b<0, 至少T秒。

如果这个问题的改写是真的,那么现在的挑战是计算u(t). 您可以使用u=diff(s),如您所提到的,如果信号s(t)没有噪音,或者你需要估计u(t)例如,使用像这两个这样的其他技术