Python 使用 cv2 将像素值映射到它的直方图 bin
Python map pixel value to it's histogram bin with cv2
给定一张图像,有没有一种快速的方法可以将像素值映射到它的 bin 中?
img = cv2.imread('test_image.jpg')
hist_g = cv2.calcHist([img[x:x+w,y:y+h,:]], [1], None, [9], [0, 256])
这个 return 是一个 9x1 数组,其中的像素数落入 0 - 256 范围内的 9 个区间。我认为。
我想要的是 [x:x+w,y:y+h]
矩阵,每个条目都有像素映射到的 bin 编号。我该怎么做?
例如,假设我有矩阵
x = np.array([[154, 192],[67,115]])
我要return矩阵
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 中,依此类推
如果你想将像素映射到 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())
使用 Google "numpy histcounts matlab"
我还发现 使用 np.digitize()
来复制 histcounts
并且它也给了我 [[5, 6], [2, 4]]
而不是[[5, 7], [3, 4]]
但我不知道我是否正确创建了 bin 范围。
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())
给定一张图像,有没有一种快速的方法可以将像素值映射到它的 bin 中?
img = cv2.imread('test_image.jpg')
hist_g = cv2.calcHist([img[x:x+w,y:y+h,:]], [1], None, [9], [0, 256])
这个 return 是一个 9x1 数组,其中的像素数落入 0 - 256 范围内的 9 个区间。我认为。
我想要的是 [x:x+w,y:y+h]
矩阵,每个条目都有像素映射到的 bin 编号。我该怎么做?
例如,假设我有矩阵
x = np.array([[154, 192],[67,115]])
我要return矩阵
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 中,依此类推
如果你想将像素映射到 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())
使用 Google "numpy histcounts matlab"
我还发现 np.digitize()
来复制 histcounts
并且它也给了我 [[5, 6], [2, 4]]
而不是[[5, 7], [3, 4]]
但我不知道我是否正确创建了 bin 范围。
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())