首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python中的峰值检测算法

Python中的峰值检测算法
EN

Stack Overflow用户
提问于 2018-06-08 16:49:19
回答 3查看 11.4K关注 0票数 2

我正在用Python实现一个峰值检测算法,它只检测那些高于阈值幅度的峰值。我不想使用内置函数,因为我还必须将此模拟扩展到硬件实现。

代码语言:javascript
复制
from math import sin,isnan
from pylab import *

def peakdet(v, delta,thresh,x):
    delta=abs(delta)
    maxtab = []
    mintab = []

    v = asarray(v)

    mn, mx = v[0], v[0]
    mnpos, mxpos = NaN, NaN

    lookformax = True

    for i in arange(len(v)):
        this = v[i]
        if abs(this)>thresh:
            if this > mx:
                mx = this
                mxpos = x[i]
            if this < mn:
                mn = this
                mnpos = x[i]
            if lookformax:
                if (this < mx-delta):
                    if (mx>abs(thresh)) and not isnan(mxpos):
                        maxtab.append((mxpos, mx))
                    mn = this
                    mnpos = x[i]
                    lookformax = False
            else:
                if (this > mn+delta):
                    if (mn<-abs(thresh)) and not isnan(mnpos):
                        mintab.append((mnpos, mn))
                    mx = this
                    mxpos = x[i]
                    lookformax = True
    return array(maxtab), array(mintab)

#Input Signal
t=array(range(100))
series=0.3*sin(t)+0.7*cos(2*t)-0.5*sin(1.2*t)

thresh=0.95 #Threshold value
delta=0.0 #

a=zeros(len(t)) #
a[:]=thresh #

maxtab, mintab = peakdet(series,delta,thresh,t)

#Plotting output
scatter(array(maxtab)[:,0], array(maxtab)[:,1], color='red')
scatter(array(mintab)[:,0], array(mintab)[:,1], color='blue')
xlim([0,t[-1]])
title('Peak Detector')
grid(True)
plot(t,a,color='green',linestyle='--',dashes=(5,3))
plot(t,-a,color='green',linestyle='--',dashes=(5,3))
annotate('Threshold',xy=(t[-1],thresh),fontsize=9)
plot(t,series,'k')
show()

这个程序的问题是,即使一些峰值高于阈值,它也无法检测到它们。这是我得到的输出:

我看过其他有峰值检测问题的帖子,但找不到任何解决方案。请帮助并建议更正。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-06-08 17:42:41

这些代码

代码语言:javascript
复制
        if lookformax:
            if (this < mx-delta):
                if (mx>abs(thresh)) and not isnan(mxpos):
                    maxtab.append((mxpos, mx))
                mn = this
                mnpos = x[i]
                lookformax = False
        else:
            if (this > mn+delta):
                if (mn<-abs(thresh)) and not isnan(mnpos):
                    mintab.append((mnpos, mn))
                mx = this
                mxpos = x[i]
                lookformax = True

仅在以下条件下运行

代码语言:javascript
复制
    if abs(this)>thresh:

因此,只有当阈值上的下一个点小于阈值时,您才能找到峰值。

把它放在条件之外

票数 -3
EN

Stack Overflow用户

发布于 2019-12-10 16:54:50

使用scipy.signalfind_peaks解决方案

代码语言:javascript
复制
from scipy.signal import find_peaks
import numpy as np
import matplotlib.pyplot as plt

# Input signal
t = np.arange(100)
series = 0.3*np.sin(t)+0.7*np.cos(2*t)-0.5*np.sin(1.2*t)

# Threshold value (for height of peaks and valleys)
thresh = 0.95

# Find indices of peaks
peak_idx, _ = find_peaks(series, height=thresh)

# Find indices of valleys (from inverting the signal)
valley_idx, _ = find_peaks(-series, height=thresh)

# Plot signal
plt.plot(t, series)

# Plot threshold
plt.plot([min(t), max(t)], [thresh, thresh], '--')
plt.plot([min(t), max(t)], [-thresh, -thresh], '--')

# Plot peaks (red) and valleys (blue)
plt.plot(t[peak_idx], series[peak_idx], 'r.')
plt.plot(t[valley_idx], series[valley_idx], 'b.')

plt.show()

结果图如下所示。

注意,find_peaks有一个参数height,这就是我们在这里所说的thresh。它还有一个名为threshold的参数,该参数执行其他操作。

Documentation for find_peaks

票数 5
EN

Stack Overflow用户

发布于 2018-06-10 04:54:53

所以,这里你有了一个数值式的解决方案(这比显式地做循环要好得多)。

我使用roll函数将数字移动到+1或-1的位置。“峰值”也被定义为局部最大值,其中先前和后验数字小于中心值。

完整的代码是:

代码语言:javascript
复制
import numpy as np
import matplotlib.pyplot as plt

# input signal
x = np.arange(1,100,1)
y = 0.3 * np.sin(x) + 0.7 * np.cos(2 * x) - 0.5 * np.sin(1.2 * x)
threshold = 0.95

# max
maxi = np.where(np.where([(y - np.roll(y,1) > 0) & (y - np.roll(y,-1) > 0)],y, 0)> threshold, y,np.nan)
# min
mini = np.where(np.where([(y - np.roll(y,1) < 0) & (y - np.roll(y,-1) < 0)],y, 0)< -threshold, y,np.nan)

如果你绘制它,你会得到:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50756793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档