【问题标题】:Normal distribution of histogram, mean, standard deviation, within a certain part of an array直方图、均值、标准差的正态分布,在数组的某个部分内
【发布时间】:2020-06-09 12:19:33
【问题描述】:

我在一个文件夹中有很多特定对象的不同图像。我想为色调、饱和度和值设置这些图像的直方图。到目前为止,它已经奏效了。

另一方面,我想将正态分布拟合到直方图,得到均值和标准差。 我遇到了色调直方图的问题。直方图显示它有两个部分,分别是 [0-50] 和 [120-180]。

我的问题是我怎么才能只得到 [120-180] 范围内的平均值和标准差,因为我不知道如何编码。

total_hue_list 中,我尝试统计所有不同颜色代码的出现次数。

import matplotlib.pyplot as plt
import numpy as np
import cv2
import os
from imutils import paths


directory = os.getcwd() + "\Demos/SotetLila"
total_hue_hist = np.zeros((180,))
total_sat_hist = np.zeros((256,))
total_val_hist = np.zeros((256,))


for imagePath in paths.list_images(directory):
    img = cv2.imread(imagePath)
    kernel = np.ones((5, 5), np.uint8)
    blur = cv2.GaussianBlur(img, (5, 5), 0)
    hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
    hsv_image = hsv

    hue, sat, val = hsv_image[:, :, 0], hsv_image[:, :, 1], hsv_image[:, :, 2]

    hue_hist, bin_hue = np.histogram(hue, bins=range(181))
    total_hue_hist += hue_hist

    sat_hist, bin_sat = np.histogram(sat, bins=range(257))
    total_sat_hist += sat_hist

    val_hist, bin_val = np.histogram(val, bins=range(257))
    total_val_hist += val_hist



plt.bar(list(range(180)), total_hue_hist)
#plt.bar(list(range(256)), total_sat_hist)
#plt.bar(list(range(256)), total_val_hist)
plt.show()

【问题讨论】:

    标签: python


    【解决方案1】:

    在我们开始之前只是一个快速指针 - 色调是循环的,所以假设你的最大色调是 180,那么色调值 0 和 1 彼此接近 180 到 0。我不确定你的代码是否180 确实是最大值与否,但只是把这个事实放在那里以防万一。

    回到主题 - 如果我理解正确,您只想考虑色调值在 120 到 180 之间的像素,而忽略所有其他值。如果确实如此,那么np.histogram 具有专门为此设计的值。引用documentation

    range(float, float),可选 bin 的下限和上限。 如果没有提供,范围就是(a.min(), a.max())。外部价值观 范围被忽略。范围的第一个元素必须小于 大于或等于第二个。范围影响自动垃圾箱 计算也是如此。虽然 bin 宽度被计算为基于最优 在范围内的实际数据上,bin 计数将填满整个 范围包括不包含数据的部分。

    但是,如果你真正想要的只是标准差和均值,那么你就不需要直方图,你可以做类似的事情:

    def filter_values(values, v_min, v_max):
        # Flatten the array to a single 1D vector
        # See https://numpy.org/doc/stable/reference/generated/numpy.ndarray.flatten.html
        flat = np.asanyarray(values).flatten()
    
        # Now index the values using "boolean indexing"
        # See https://numpy.org/devdocs/reference/arrays.indexing.html#boolean-array-indexing
        return flat[np.logical_and(flat >= v_min,
                                   flat < v_max)]
    

    然后您可以像这样计算平均值和标准差:

    filtered_hue = filter_values(hue, v_min=120, v_max=180)
    np.mean(filtered_hue), np.std(filtered_hue)
    

    祝你好运!

    【讨论】:

    • 谢谢,这是我的问题。但我还有另一个问题。我想分割图像,所以我应该找到一个阈值,它何时算作前景以及何时算作背景。我多次听说过 Otsu 算法,但我在任何地方都没有找到它的例子。您可能不知道如何使用这种特殊的 Otsu 算法找到 hue、sat 和 val 的阈值?
    • @Cerberus - 在opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/… 中有一个 Otsu 的二值化算法示例。虽然您可以在 V 通道(HSV)上应用它,但由于 V 通道在饱和颜色下的表现,这可能会产生次优结果 - 我建议使用图像的灰度表示来查找阈值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    相关资源
    最近更新 更多