我有一个非常简单的用例,我正在对图像进行网格化并计算每个单元格中最频繁出现的颜色。
我遇到一个问题,即某些视觉上看起来像黑色的单元格应该是最常见的颜色,而其模式为白色(255)。这样的一个例子是单元格(6,3)-首先从零开始的索引列,然后是行。
应该不是黑色的,但结果却是白色的。我的代码有问题吗?还是看不到盐和胡椒粉的声音?
def mode_filter(self, roi):
values = np.zeros((1, 256), dtype="uint8")
for pos, val in np.ndenumerate(roi):
values[0, val] += 1
print(values)
return int(np.argmax(values[0]))
def get_roi(self, src, pt1, pt2):
col1, col2 = (pt1[0], pt2[0]) if pt1[0] < pt2[0] else (pt2[0], pt1[0])
row1, row2 = (pt1[1], pt2[1]) if pt1[1] < pt2[1] else (pt2[1], pt1[1])
return src[row1:row2, col1:col2]
def grid_img(self, src, nCols=7, nRows=7):
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
cells = np.zeros(gray.shape, dtype="uint8")
cell_w = int(gray.shape[1] / nCols)
cell_h = int(gray.shape[0] / nRows)
for c in range(nCols):
for r in range(nRows):
roi = self.get_roi(gray, (c*cell_w, r*cell_h), ((c+1)*cell_w, (r+1)*cell_h))
mode = self.mode_filter(roi)
cv2.rectangle(cells, (c*cell_w, r*cell_h), ((c+1)*cell_w, (r+1)*cell_h), (mode,), -1)
cv2.imshow('roi', roi)
cv2.imshow('cells', cells)
cv2.imshow('src', src)
print('{}, {}'.format((c,r), mode))
cv2.waitKey(0)
return cells
可以在此处找到完整的工作示例:https://pastebin.com/k7kUTmXG
答案 0 :(得分:3)
用于计算每种颜色出现次数的数组的定义如下:
values = np.zeros((1, 256), dtype="uint8")
这意味着每个计数都由一个字节表示,即最大值为255。一旦出现该颜色的另一个像素,计数将溢出为0。
这几乎可以肯定会发生,因为您要处理的ROI的大小约为100x100像素。
解决方案很简单-使用更大的数据类型,例如int32
。
def mode_filter(self, roi):
values = np.zeros((1, 256), dtype="int32")
for pos, val in np.ndenumerate(roi):
values[0, val] += 1
print(values)
return int(np.argmax(values[0]))
例如,在图块(0,5)上,看起来像这样:
您的函数给出以下输出:
[[144 15 9 13 8 1 5 9 4 5 5 1 2 4 4 4 4 6
7 5 4 2 1 2 1 1 0 1 2 1 6 3 4 7 2 3
1 1 2 1 0 4 2 2 3 2 0 2 0 2 0 1 2 5
1 3 2 4 2 2 3 3 1 3 4 2 2 2 2 4 3 2
4 0 1 2 0 2 2 2 1 0 2 2 1 1 2 1 0 3
2 0 1 1 0 4 1 3 1 2 3 1 0 3 0 1 1 0
0 1 2 1 2 0 1 2 2 1 1 0 1 2 2 4 2 1
2 1 1 1 1 2 1 1 1 3 1 1 2 3 2 1 2 0
1 1 1 3 4 2 3 1 1 2 1 1 5 3 1 2 1 1
1 0 2 3 0 1 1 3 4 0 2 1 4 3 0 1 4 1
1 2 2 1 0 1 1 2 1 1 1 3 2 3 1 5 0 2
2 1 2 2 0 2 1 0 1 1 4 2 4 2 2 4 1 4
4 4 1 3 1 0 3 6 3 2 0 2 3 5 3 3 5 5
5 4 3 6 7 4 1 7 2 10 5 10 6 10 7 7 16 8
10 14 16 125]]
0
而更正后的版本将产生以下结果:
[[2960 15 9 13 8 1 5 9 4 5 5 1 2 4
4 4 4 6 7 5 4 2 1 2 1 1 0 1
2 1 6 3 4 7 2 3 1 1 2 1 0 4
2 2 3 2 0 2 0 2 0 1 2 5 1 3
2 4 2 2 3 3 1 3 4 2 2 2 2 4
3 2 4 0 1 2 0 2 2 2 1 0 2 2
1 1 2 1 0 3 2 0 1 1 0 4 1 3
1 2 3 1 0 3 0 1 1 0 0 1 2 1
2 0 1 2 2 1 1 0 1 2 2 4 2 1
2 1 1 1 1 2 1 1 1 3 1 1 2 3
2 1 2 0 1 1 1 3 4 2 3 1 1 2
1 1 5 3 1 2 1 1 1 0 2 3 0 1
1 3 4 0 2 1 4 3 0 1 4 1 1 2
2 1 0 1 1 2 1 1 1 3 2 3 1 5
0 2 2 1 2 2 0 2 1 0 1 1 4 2
4 2 2 4 1 4 4 4 1 3 1 0 3 6
3 2 0 2 3 5 3 3 5 5 5 4 3 6
7 4 1 7 2 10 5 10 6 10 7 7 16 8
10 14 16 7293]]
255