如何使用Savitzky Golay滤波器在离散采样的1D信号中找到局部最大值(在采样之间)?


9

我有一个地震信号y(i): 在此处输入图片说明

在这里,我找到了一个最大值:手动将i = 152.54,y = 222.29绘制为红色。

我想自动查找所有最大值。

我读到,Savitzky Golay滤波器(SGF)可用于找到信号及其导数的平滑估计,并且SGF的好处之一是它比其他滤波器更好地保留了最小值和最大值。这对我来说听起来很棒。

我发现了一个生成SGF系数的Matlab脚本。 并以此发现导数的四阶SGF系数。我编写了一个小的Matlab脚本

  1. 通过将信号与导数的4阶SGF系数进行卷积来找到信号的导数
  2. 查找导数更改符号的样本对(i,i + 1)
  3. 通过i和i + 1之间的线性插值找到导数的零交叉

脚本:

function [maxX,maxY] = findLocalMax(y)
% Kernel for 4th order Savitzky-Golay filter for finding derivative:
d4 = [0.0724 -0.1195 -0.1625 -0.1061 0 0.1061 0.1625 0.1195 -0.0724];

dy = conv(y,d4,'same'); % derivative

[m n] = size(dy);
maxX = [];
maxY = [];
for i = 1 : n - 1
  if dy(i) < 0 && dy(i+1) > 0 % max somewhere between i and i+1
    a = dy(i)/(dy(i) - dy(i+1)); % linear interpolation
    mx = i + a;
    maxX = [maxX mx];
    my = y(i)*(1-a) + y(i+1)*a; % linear interpolation
    maxY = [maxY my];
  end
end

在我的脚本中,我必须测试导数是否从负变为正,才能使函数提供所需的结果,但这使我感到困惑。 最大值的导数不应该从正变负吗? 有什么更好的方法来区分最大值和最小值?

以下是使用此函数查找信号最大值的结果: 在此处输入图片说明

结果看起来不错,但我注意到未找到一些最大值:i = 143.13、190.88、256.97。

这是因为它们要接近其他最大值吗?

如何控制最接近的两个最大值?

预先感谢您的任何回答!


你能画出滤波器的输出吗?
Jim Clay

Answers:


5

尽管我不熟悉这种特定类型的过滤器,但根据您显示的图,我想您的过程找不到的最大值只是与该过程固有的时间分辨率相对应。任何一种“平滑”都意味着感兴趣的信号在时间上存在一些拖尾现象,因此,如果附近有两个峰,则有可能它们会合并为一个。低阶滤波器可能会表现出较少的这种行为,可能是以您获得的平滑量为代价的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.