scipy signal find_peaks_cwt没有准确找到峰值?

时间:2014-08-29 15:16:12

标签: python scipy signal-processing image-segmentation

我有一个1-D信号,其中我试图找到峰值。我希望找到它们。

我目前正在做:

import scipy.signal as signal
peaks = signal.find_peaks_cwt(data, np.arange(100,200))

以下是带有红点的图表,显示find_peaks_cwt()找到的峰的位置。

Signal + Peaks

如您所见,计算出的峰值不够准确。非常重要的是右侧的三个。

我的问题:如何让这更准确?

更新:数据在此处:http://pastebin.com/KSBTRUmW

对于某些背景,我尝试做的是在图像中找到手指之间的空间。绘制的是手周围轮廓的x坐标。青色斑点=峰。如果有更可靠/更健全的方法,请发表评论。

enter image description here

4 个答案:

答案 0 :(得分:17)

解决,解决方案:

首先过滤数据:

  window = signal.general_gaussian(51, p=0.5, sig=20)
  filtered = signal.fftconvolve(window, data)
  filtered = (np.average(data) / np.average(filtered)) * filtered
  filtered = np.roll(filtered, -25)

然后按照rapelpy的回答使用angrelextrema。

结果:

enter image description here

答案 1 :(得分:14)

使用此功能有一个更简单的解决方案: https://gist.github.com/endolith/250860 这是http://billauer.co.il/peakdet.html

的改编

我刚试过你提供的数据,我得到了下面的结果。无需预过滤...

享受: - )

peak detection

答案 2 :(得分:3)

获取原始数据后编辑。

argelmax和arglextrma已退出竞争。

曲线非常嘈杂,因此您必须使用较小的峰宽(如提到的pv。)和噪音。

我发现的最好看起来不太好。

import numpy as np
import scipy.signal as signal

peakidx = signal.find_peaks_cwt(y_array, np.arange(10,15), noise_perc=0.1)
print peakidx

[10, 100, 132, 187, 287, 351, 523, 597, 800, 1157, 1451, 1673, 1742, 1836]

enter image description here

答案 3 :(得分:0)

基于@cjm2671 的回答,这是一个用于在嘈杂信号中查找相对最大值和最小值的工作函数:

from scipy import signal
def relativeMaxMin(data, nPointsWindow, sigmaWindow):
    window = signal.general_gaussian(nPointsWindow, p=1, sig=sigmaWindow)
    dataFiltered =  signal.fftconvolve(data, window, 'same')
    dataFiltered *= np.average(data) / np.average(dataFiltered)
    indexMax = signal.argrelmax(dataFiltered)[0]
    indexMin = signal.argrelmin(dataFiltered)[0]
    return dataFiltered, indexMax, indexMin

在搜索最大值和最小值之前,该函数使用与高斯窗口的卷积来过滤信号。高斯窗口是用scipy的signal.general_gaussian定义的,它需要窗口的点数,窗口的形状p(例如,p=1为高斯和{{1} } 用于拉普拉斯分布)和窗口的标准偏差 p=0.5。您应该在特定情况下调整此参数。最后,sig 将卷积缩小到原始数据。

以下是应用于带有噪声的信号的函数示例,其中我使用了 dataFiltered *= np.average(data) / np.average(dataFiltered)nPointsWindow = 50

enter image description here

在这种情况下,这种方法比使用 signal.find_peaks_cwt 效果更好。