我有一个地震信号$ y [n] $的离散样本$ n $:


我想在信号中找到局部最大值。

如果$ y [n] $是否为最大值,则进行朴素的测试是:
$$ y [n]:maxima \ textbf {if y [n]> y [n -1] \ textbf {和} y [n]> y [n + 1] $$

但是最大值可能位于样本之间,例如在$ i = 4.25 $处可能存在最大值。

为了在样本之间找到最大值,我相信我需要对$ y [n] $进行插值。


如何使用内插法找到最大值?
我应该使用哪种形式的内插法?

如您所见,我的信号不是很吵,但是如果该方法还进行了一些过滤,以使最大值超过阈值并具有一定的宽度(无尖峰)。

但是,我最大的问题是在样本之间找到峰。
任何建议这样做的好方法?

谢谢您的任何回答!

评论

也许看问题1和问题2。

频谱的几种方法:dspguru.com/dsp/howtos/how-to-interpolate-fft-peak

第二个没有答案@Geerten ;-)

哦..哈哈,好点。好吧,我会在这个问题上再参考这个问题;)

#1 楼

获得子样本分辨率

一种非常便宜(就代码大小而言)的解决方案只是对信号进行上采样。在matlab中,可以使用interp(y ,ratio)完成此操作。一个稍微复杂些的解决方案包括天真地检测峰值。对于每个峰,通过y [peak-1],y [peak],y [peak + 1]拟合抛物线;然后使用抛物线最大的点作为真实的峰值位置。

关于峰值检测

一堆技术可以帮助您:


如希尔马(Hilmar)所建议,通过高斯或汉恩窗口对信号进行卷积,其宽度大约等于您希望在检测到的峰之间看到的最小间隔的一半。由于时间精度对于您的应用程序似乎至关重要,因此请确保考虑到滤波带来的时间延迟!
减去信号本身的中值滤波版本(具有相当大的观察窗口);并将结果除以自身的标准差过滤版本。这消除了趋势,并允许以标准差为单位来表示阈值。
对于峰采集,我使用“高帽”过滤器来表述。将信号的高顶滤波版本定义为yt [n] = max(y [n-W],y [n-W + 1],...,y [n + W-1],y [n + W]);并使用y [n] == yt [n]和y [n]>阈值的点作为峰值。

只需经过几次nlfi​​lter,就可以在Matlab中非常高效地实现所有这些。 br />

评论


$ \ begingroup $
上采样与抛物线插值的组合可能比单独使用的效果更好。
$ \ endgroup $
– hotpaw2
2012年3月22日19:32

#2 楼

尝试使用有损峰值检测器:
y[n] = max(abs(x[n]),a*y[n-1]);

其中,“ a”是小于1的数字,它控制检测器的衰减速度。它可以确定相邻峰之间有多近而又不会陷入一个峰。然后进行阈值检测。

评论


$ \ begingroup $
您的方程式中同时具有x [n]和y [n]。这是正确的还是应该只是y [n]?
$ \ endgroup $
–安迪
2012年3月21日17:11



$ \ begingroup $
x [n]是输入,y [n]是输出。总体而言,答案很差,有一个错字(现已修复),我误解了这个问题。道歉
$ \ endgroup $
–希尔马
2012年3月22日,0:26