编辑 将所有内容整合成一个工作程序,使用您发布的图像:
from __future__ import division
import numpy as np
import itertools
from PIL import Image
img = np.array(Image.open('test_img.png'))
def bounding_boxes(img) :
r, g, b = [np.unique(img[..., j]) for j in (0, 1, 2)]
bounding_boxes = {}
for r0, g0, b0 in itertools.product(r, g, b) :
rows, cols = np.where((img[..., 0] == r0) &
(img[..., 1] == g0) &
(img[..., 2] == b0))
if len(rows) :
bounding_boxes[(r0, g0, b0)] = (np.min(rows), np.max(rows),
np.min(cols), np.max(cols))
return bounding_boxes
In [2]: %timeit bounding_boxes(img)
1 loops, best of 3: 30.3 s per loop
In [3]: bounding_boxes(img)
Out[3]:
{(0, 0, 255): (3011, 3176, 755, 2546),
(0, 128, 0): (10, 2612, 0, 561),
(0, 128, 128): (1929, 1972, 985, 1438),
(0, 255, 0): (10, 166, 562, 868),
(0, 255, 255): (2938, 2938, 680, 682),
(1, 0, 0): (10, 357, 987, 2591),
(128, 0, 128): (417, 1873, 984, 2496),
(205, 186, 150): (11, 56, 869, 1752),
(255, 0, 0): (3214, 3223, 570, 583),
(255, 20, 147): (2020, 2615, 956, 2371),
(255, 255, 0): (3007, 3013, 600, 752),
(255, 255, 255): (0, 3299, 0, 2591)}
即使实际检查的颜色数量很少,速度也不是很快...
您可以通过以下方式找到颜色r0
,g0
,b0
的边界框:
rows, cols = np.where((ra == r0) & (ga == g0) & (ba == b0))
top, bottom = np.min(rows), np.max(rows)
left, right = np.min(cols), np.max(cols)
与其遍历所有RGB颜色的2**24
种组合,你可以仅使用非零直方图条目的笛卡尔积来大大减少搜索空间:
for r0, g0, b0 in itertools.product(np.nonzero(rhist),
np.nonzero(ghist),
np.nonzero(bhist)) :
您可能会遇到不存在的组合泄漏问题,但您可以通过检查rows
和cols
是否为空元组来过滤掉这些组合。但在您的示例中,您已将搜索空间从2 ** 24
个组合减少到了只有125个。