我有一个地震信号 y(i):
在这里,我发现了一个最大值: i=152.54, y=222.29 手动并将其绘制为红色。
我想自动找到所有最大值。
我读到 Savitzky Golay 滤波器 (SGF) 可用于找到信号及其导数的平滑估计,并且 SGF 的好处之一是它比其他滤波器更好地保留最小值和最大值。这听起来很适合我的使用。
我找到了一个生成 SGF 系数的 Matlab 脚本。 并用它来找到导数的四阶 SGF 系数。我编写了一个小的 Matlab 脚本
- 通过将信号与导数的四阶 SGF 系数进行卷积来找到信号的导数
- 找到导数改变符号的样本对 (i,i+1)
- 通过 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。
这是因为它们要接近其他最大值吗?
如何控制最近的两个最大值?
提前感谢您的任何答案!