[英]Find the centre value of the two highest peaks in a histogram Python
我試圖在直方圖中找到最高和第二高峰值之間的“中間”值。 我當然可以手動執行此操作,但我想創建一個自動化方法。 要計算我的直方圖,我使用:
hist= cv2.calcHist([gray_scale_img], [0], None, [256], [0, 256])
到目前為止,我只知道如何使用max = np.argmax(hist)
計算出最大峰值。 我附上了一張圖片,紅色是我想要找到的。 直方圖圖像
以下是計算直方圖前 2 個峰值之間的索引和值的方法(使用 OpenCV 和 Python 3)。
import numpy as np
import cv2
img = cv2.imread('../test.jpg', cv2.IMREAD_GRAYSCALE)
#Compute histogram
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
#Convert histogram to simple list
hist = [val[0] for val in hist]
#Generate a list of indices
indices = list(range(0, 256))
#Descending sort-by-key with histogram value as key
s = [(x,y) for y,x in sorted(zip(hist,indices), reverse=True)]
#Index of highest peak in histogram
index_of_highest_peak = s[0][0]
#Index of second highest peak in histogram
index_of_second_highest_peak = s[1][0]
print(index_of_highest_peak)
print(index_of_second_highest_peak)
#If top 2 indices are adjacent to each other, there won't be a midpoint
if abs(index_of_highest_peak - index_of_second_highest_peak) < 2:
raise Exception('Midpoint does not exist')
else: #Compute mid index
midpoint = int( (index_of_highest_peak + index_of_second_highest_peak) / 2.0 )
print('Index Between Top 2 Peaks = ', midpoint)
print('Histogram Value At MidPoint = ', hist[midpoint])
我假設如果前 2 個峰彼此相鄰,則不會有中點。 您可以根據您的需要調整此案例。
您正在嘗試的內容似乎與Otsu thresholding algorithm非常相似。 在這種情況下,您可以使用
ret, otsu = cv2.threshold(gray_scale_img , 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
如果您的數據是強三峰的並且 Otsu 的方法不令人滿意,對應的方法是應用具有 3 個集群的kmeans 聚類。 Otsu 的方法和 kmeans 都通過最小化類內方差來對數據進行分類。 在代碼中:
import numpy as np
from sklearn.cluster import KMeans
# Make trimodal data
# (if image is large, consider downsampling it)
n1 = np.random.normal(80, 10, 200)
n2 = np.random.normal(120, 10, 200)
n3 = np.random.normal(180, 10, 400)
imflat = np.r_[n1, n2, n3]
# shuffle and reshape
np.random.shuffle(imflat)
im = imflat.reshape(-1, 1)
km = KMeans(n_clusters=3, random_state=0).fit(im)
lab = km.labels_
# maxmimum data value in each cluster
[im[np.argwhere(lab==i)].flatten().max() for i in range(3)]
不過,這並不能確定 3 個集群中的哪一個在直方圖中具有最高峰。 為不完整的解決方案道歉。 另一個建議可能是將 6 階多項式擬合到直方圖,然后找到轉折點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.