【问题标题】:Find the centre value of the two highest peaks in a histogram Python在直方图中找到两个最高峰的中心值 Python
【发布时间】:2017-11-02 22:58:06
【问题描述】:

我试图找到直方图中最高和第二高峰之间的“中间”值。我当然可以手动执行此操作,但我想创建一个自动化方法。要计算我的直方图,我使用:

hist= cv2.calcHist([gray_scale_img], [0], None, [256], [0, 256])

到目前为止,我只知道如何使用max = np.argmax(hist) 计算出最大峰值。我附上了一张红色的图片,这是我想要找到的。 HISTOGRAM IMAGE

【问题讨论】:

  • 添加如何“计算”最大峰值。您显示的自己的代码越多,您将获得更好的响应。否则答案会出现分歧,问题会变得广泛
  • 其他人也可以通过阅读您的问题来学习
  • 使用 np.argmax(hist) 给了我最大的峰值
  • 好吧,把它放在你的问题中。 知道你是怎么得到它的,但也许世界其他地方不知道。把max_point = np.argmax(hist)
  • 看看 hereherehere... 并在 google 上玩得开心。顺便说一句,你正在寻找的点似乎是一个本地化最小值......谷歌也是;)

标签: python opencv histogram


【解决方案1】:

这是计算直方图前 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 个峰彼此相邻,则不会有中点。您可以根据自己的需要调整这种情况。

【讨论】:

    【解决方案2】:

    您正在尝试的似乎与Otsu thresholding algorithm 非常相似。在这种情况下,您可以使用

    ret, otsu = cv2.threshold(gray_scale_img , 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    

    如果您的数据是强三峰且 Otsu 的方法不令人满意,则对应的方法是应用 kmeans clustering 和 3 个集群。 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 阶多项式拟合到直方图,然后找到转折点。

    【讨论】:

    • 欢迎来到 Stack Overflow!我同意 Otsu 的方法听起来像是 OP 的好方法。考虑添加一些文档或教程链接,以便将来查找此问题的任何人都可以了解 Otsu 的方法为何/如何完成 OP 的要求。
    • 直觉不错,但 Otsu 一般不会工作,因为它假设 双峰 分布
    猜你喜欢
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多