我有一个浮点值的单维数组(c#双加FYI),我需要找到值的“峰值”......就像绘图一样。单维峰值拟合
我不能只拿最高价值,因为峰值实际上是一个波动很小的高原。这个高原正处在一堆噪音中。我正在寻找能够让我成为这个高原中心的解决方案。
一个例子阵列可能是这样的:
1,2,1,1,2,1,3,2,4,4,4,5,6,8,8,8,8 ,7,8,7,9,7,5,4,4,3,3,2,2,1,1,1,1,1,2,1,1,1,1
其中峰值位于粗体部分的某处。
任何想法?
我有一个浮点值的单维数组(c#双加FYI),我需要找到值的“峰值”......就像绘图一样。单维峰值拟合
我不能只拿最高价值,因为峰值实际上是一个波动很小的高原。这个高原正处在一堆噪音中。我正在寻找能够让我成为这个高原中心的解决方案。
一个例子阵列可能是这样的:
1,2,1,1,2,1,3,2,4,4,4,5,6,8,8,8,8 ,7,8,7,9,7,5,4,4,3,3,2,2,1,1,1,1,1,2,1,1,1,1
其中峰值位于粗体部分的某处。
任何想法?
您需要先定义“小”的含义。假设最大值附近的“小”波动被定义为任何在±内的值;最大值为ϵ。那么,确定高原就很简单。
传递数据以确定最大值,然后进行第二遍以确定所有在“+”内的值。最大值为ϵ。
您可以将low-pass filter应用于您的输入数组,以消除小波动,然后在筛选数据中找到峰值。最简单的例子可能是“boxcar”过滤器,其中输出值是距当前数组位置一定距离 内的输入值的总和。在伪代码,它会是这个样子:
for i = 0, samplecount-1
if (i < boxcar_radius) or (i >= (samplecount - boxcar_radius)) then
filtered_data[i] = 0 // boxcar runs off edge of input array, don't use
else
filtered_data[i] = 0
for j = i-boxcar_radius, i+boxcar_radius
filtered_data[i] = filtered_data[i] + input_data[j]
endfor
endif
endfor
如果你有一些想法有多宽“高原”将是,你可以选择棚车半径(约预期高原宽度的一半),在检测功能适当的规模。
峰值检测是Phase Correlation和其他视频压缩等运动估计算法中的一个阶段。一种方法是:考虑一个峰值的候选人和一定数量的邻居的窗口。现在使用标准回归拟合二次函数。具有亚像素精度的峰值处于拟合二次曲线的最大值。
很明显,确切的解决方案取决于细节。如果你的配送总是很好,你可以有:
def GetPeak(l):
large = max(l) * 0.8
above_large = [i for i in xrange(len(l)) if l[i] > large]
left_peak = min(above_large)
right_peak = max(above_large)
return (left_peak, right_peak)
有几个人在这里给出了类似的答案,你的第一个。谢谢匿名,我不认为这样解决问题。我在最大值的±ε范围内检索了一个“窗口”的数组索引,并对这两个值进行了平均。这是速度和准确性的完美结合。再次感谢! – bufferz 2010-05-28 11:37:34