为什么 cv2.calcHist() 的最小值和最大值与生成直方图的数组不同?

问题描述 投票:0回答:1

概述:

  • 我想可视化像素值标准化的图像的像素值分布(范围边界 [0, 1])并使用 cv2.calcHist() 获取直方图。

代码:

def create_histogram(array: np.ndarray):
    array_min, array_max = np.min(array), np.max(array)
    print(f"Array: min {array_min} . . .  max {array_max}")
    hist = cv2.calcHist([array], channels = [0], mask = None, histSize = [100], ranges = [0, 1])
    histo_min, histo_max = np.min(hist), np.max(hist)
    print(f"Histogram: min {histo_min} . . .  max {histo_max}")
    return hist

输出:

Array: min 0.0 . . .  max 1.0 Histogram: min 0.0 . . .  max 4152712.0

理解检查: 根据我的理解,原始数组正确地传递给函数并按应有的方式读取,最小和最大像素值为 1。

(1)我不明白的是,为什么直方图的最大值与图像最大值不对应? (2) 如果我在 cv2.calcHist() 函数中将范围设置为 [0, 1] 范围,为什么我的直方图输出的 x 轴表示范围超出 4? (3) 最后,我不明白绘制直方图中的“1e7”是从哪里来的[图 1]。 1]

如图。 1 - 直方图输出图片

如果相关,这是用于生成直方图的代码行:

plt.hist(histo_dict[k], bins = 100, color = 'deeppink', edgecolor = 'black', alpha = 0.2)

我尝试使用 cv2.calcHist() 创建直方图,但这并没有产生预期的结果。

编辑:我相信直方图数组的最大值实际上只是最高卷箱的长度。这仍然无法解释最终直方图上出现的 x 轴范围似乎超出了 [0, 1] 上限。

python histogram
1个回答
0
投票

为什么

hist = cv2.calcHist([array], channels = [0], mask = None, histSize = [100], ranges = [0, 1])
的最小值和最大值与生成直方图的数组不同?

让我们看看一个简单的数组示例的文本输出以及该数组的直方图:

The image array [(0.1, 0.1, 0.1), (0.2, 0.2, 0.2), (0.2, 0.2, 0.2), (0.3, 0.3, 0.3), (0.3, 0.3, 0.3), (0.3, 0.3, 0.3), (0.4, 0.4, 0.4), (0.4, 0.4, 0.4), (0.4, 0.4, 0.4), (0.4, 0.4, 0.4), (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (1.0, 1.0, 1.0)]
The histogram array [[0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [3.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [6.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [9.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [12.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [18.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0]]

从上面可以看出,直方图没有考虑数组值的范围。为了让 x 轴显示值的范围,您需要构建适当绘图的 x 轴,如下面的代码所示,这也是打印上面提供的输出的代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Your existing code to calculate the histogram
L = [0.1, 0.2, 0.2, 0.3, 0.3, 0.3, 0.4, 0.4, 0.4, 0.4, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0]
img = list(zip(L, L, L))
array = np.array(img, dtype=np.float32)
print( "The image array" , img )

hist = cv2.calcHist([array], [0], None, [100], [0, 1])
print( "The histogram array", hist.tolist() )

hist = hist.flatten()  # Flatten the histogram to 1D for plotting

# Generate the bin centers
bin_edges = np.linspace(0, 1, 101)  # 100 bins between 0 and 1
bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2

# Set up the plot
fig, ax = plt.subplots()

# Plotting: x-axis for values in bins, y-axis for bin indices

ax.plot(bin_centers, range(len(bin_centers)), marker='o')

# Labeling the axes
ax.set_xlabel('Bin Value')
ax.set_ylabel('Bin Index')

# Showing the plot
plt.show()

按照您的预期绘制数据:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.