给定一个数组h, 从左往右扫描。
用S记录当前的状态(未知0, 下坡1,上坡2)
当S=0, 如果 h[i] > h[i+1] 修改状态为 下坡1, 否则为上坡 2
当S=1, 如果 h[i] < h[i+1], 则判断为由下坡变为上坡, 此处为一个波谷。 如果该波谷比上一个rangesize范围内的波谷更低,则修改上一个波谷的值。 否则就将该波谷加入波谷列表。
当S=2, 如果 h[i] > h[i+1], 则判断为由上坡变为下坡, 此处为一个波峰。 如果该波峰比上一个rangesize范围内的波峰更高,则修改上一个波谷的值。 否则就将该波峰加入波峰列表。
最后返回波峰和波谷列表。
import numpy as np
def get_peaks_troughs(h,rangesize):
peaks = list()
troughs = list()
S = 0
for x in range(1,len(h)-1):
if S == 0:
if h[x] > h[x+1]:
S = 1 ## down
else:
S = 2 ## up
elif S == 1:
if h[x] < h[x+1]:
S = 2
## from down to up
if len(troughs):
## check if need merge
(prev_x,prev_trough) = troughs[-1]
if x - prev_x < rangesize:
if prev_trough > h[x]:
troughs[-1] = (x,h[x])
else:
troughs.append((x,h[x]))
else:
troughs.append((x,h[x]))
elif S == 2:
if h[x] > h[x+1]:
S = 1
## from up to down
if len(peaks):
prev_x,prev_peak = peaks[-1]
if x - prev_x < rangesize:
if prev_peak < h[x]:
peaks[-1] = (x,h[x])
else:
peaks.append((x,h[x]))
else:
peaks.append((x,h[x]))
return peaks,troughs
if __name__ == "__main__":
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread("peak.png",0)
img = 255 - imgY,X = img.shape
print Y,Xh = np.zeros((X,1))
for i in range(X):
for j in range(Y):
if img[j,i] > 0:
h[i] = Y - jpeaks,troughs = get_peaks_troughs(h,10)
plt.subplot(1,2,1)
plt.imshow(img)
plt.subplot(1,2,2)
plt.plot(np.arange(len(h)),h)
for x,y in peaks:
plt.text(x,y,y,fontsize=10,verticalalignment="bottom",horizontalalignment="center")
for x,y in troughs:
plt.text(x,y,y,fontsize=10,verticalalignment="top",horizontalalignment="center")plt.show()
peaks,troughs = get_peaks_troughs(h,50) ## 跨度修改成50后
跨度为50