簡體   English   中英

找出直方圖中兩個最高峰的中心值 Python

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM