【问题标题】:Python map pixel value to it's histogram bin with cv2Python 使用 cv2 将像素值映射到它的直方图 bin
【发布时间】:2020-04-24 20:38:09
【问题描述】:

给定一张图像,有没有一种快速的方法可以将像素值映射到它的 bin 中?

img = cv2.imread('test_image.jpg')
hist_g = cv2.calcHist([img[x:x+w,y:y+h,:]], [1], None, [9], [0, 256])

这将返回一个 9x1 数组,其中像素数落入 0 到 256 之间的 9 个 bin 中。我认为。

我想要的是[x:x+w,y:y+h] 矩阵,每个条目都有像素映射到的 bin 编号。我该怎么做?

例如,假设我有矩阵

x = np.array([[154, 192],[67,115]])

我想返回矩阵

x_histcounts = np.array([[5, 7],[3,4]])

基于cv2.calcHist([img[x:x+w,y:y+h,:]], [1], None, [9], [0, 256])

因为 154 在第 5 个 bin 中,192 在第 7 个 bin 中,等等。

【问题讨论】:

  • 我不明白你想做什么,但9x1 是直方图的正确大小。矩阵[x:x+w,y:y+h] 不是直方图。看来您应该使用将每个值除以 9 并获得整数值来获得您期望的值。类似result = img[x:x+w,y:y+h,:] // 9

标签: python cv2


【解决方案1】:

如果您想将像素映射到9 箱,那么您可以转换为灰度,然后使用// 除以(256/9) 以获得整数

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

result = img_gray[x:x+w,y:y+h] // (256/9)

calcHist 中,您使用通道列表[1],因此您只需要一个通道的直方图,这意味着您不必转换为灰度,而是使用[..., ..., 1]

result = img[x:x+w, y:y+h, 1] // (256/9)

编辑:我测试了你的示例数据[[154, 192], [67, 115]],它给了我 [[5, 6], [2, 4]] 而不是 [[5, 7], [3, 4]]

import numpy as np

bins_number = 9

x = np.array([[154, 192], [67, 115]])
result = (x // (256/bins_number)).astype(int)

print('result:', result.tolist())

使用谷歌"numpy histcounts matlab" 我还发现How do i replicate this matlab function in numpy? 使用np.digitize() 复制histcounts,它也给了我[[5, 6], [2, 4]] 而不是[[5, 7], [3, 4]],但我不知道我是否正确创建了垃圾箱范围。

import numpy as np

bins_number = 9

x = np.array([[154, 192], [67, 115]])

bins = [(256/bins_number)*x for x in range(1, bins_number+1)]
result = np.digitize(x, bins)

print('result:', result.tolist())
print('bins:', bins)

我没有Matlab,所以我尝试在Octave 中使用histc()

>> [a, b] = histc([154, 192, 67, 115], [ 28.44444444,  56.88888889,  
85.33333333, 113.77777778, 142.22222222, 170.66666667, 199.11111111, 227.55555556, 256. ])

a =

   0   1   0   1   1   1   0   0   0

b =

   5   6   2   4

它还给了我[[5, 6], [2, 4]] 而不是[[5, 7], [3, 4]]


编辑:我发现 numpy.histogram_bin_edges 可以生成 bin 范围

import numpy as np

bins_number = 9

x = np.array([[154, 192], [67, 115], [0,1]])

bins = np.histogram_bin_edges(x, bins=9, range=(0, 256))

print('bins:', bins)

但它将0 添加为第一条边,因此稍后它使用数字1-9 而不是0-8,但如果您使用bins[1:],那么它仍然使用数字0-8

import numpy as np

bins_number = 9

x = np.array([[154, 192], [67, 115]])

bins = np.histogram_bin_edges(x, bins=9, range=(0, 255))
print('bins:', bins)

print('result:', np.digitize(x, bins[1:]).tolist())

【讨论】:

  • 我澄清了这个问题。我基本上想要一个 Matlab 有的 histcounts 方法。
  • 我的代码为您的示例数据提供了几乎相同的结果。我的代码向下取整(地板),但您的数据向上取整(屋顶)或四舍五入到最接近的整数。
  • 我添加了关于numpy.histogram_bin_edges的信息
猜你喜欢
  • 1970-01-01
  • 2020-07-01
  • 2019-07-10
  • 2021-12-27
  • 1970-01-01
  • 2022-10-04
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
相关资源
最近更新 更多