OpenCV:使用radius是否可以替代cv2.inRange?

时间:2018-10-09 12:23:03

标签: python image-processing colors opencv3.0

我熟悉OpenCV的inRange函数来创建遮罩。假设我要获得某个颜色“周围”的颜色范围内的像素蒙版,可以这样做:

color = np.array([240, 60, 70])
max_dist = 50
img = cv2.inRange(img, [color] - max_dist, [color] + max_dist)

但是,这会将所有BGR颜色掩盖在中心颜色周围的“立方体”中。我正在寻找在BGR空间中中心颜色周围使用“球体”(即欧几里德距离)的替代方法。有什么想法吗?

我当然可以遍历图像,使用scipy.spatial.distance.cdist计算距离,然后一遍遍遍所有像素,然后将其包括在遮罩中或从遮罩中排除。但是,这在python中非常慢...

谢谢!

2 个答案:

答案 0 :(得分:2)

创建一个遮罩,以指示其欧几里德距离小于max_dist的像素:

R = img[:, :, 0].astype(np.float32)
G = img[:, :, 1].astype(np.float32)
B = img[:, :, 2].astype(np.float32)

sq_dist = (R - color[0]) ** 2 + (G - color[1]) ** 2 + (B - color[2]) ** 2

mask = sq_dist < (max_dist ** 2)

masked_img = np.repeat(mask[..., None], 3, axis=2) * img

答案 1 :(得分:0)

最后得到了一个可行的答案。确切地说,我不想将自己限制为一种颜色,而是允许多种颜色。我正在使用内置的cdist函数+ dobkind上面建议的后处理,以将距离转换为蒙版。这比以前的方法快约7%。

max_dist = 10
colors = np.array([[250,40,60],[245,245,245]])
dist = scipy.spatial.distance.cdist(colors, img.reshape(-1, 3), 'euclidean')
mask = np.any(dist <= max_dist, axis=0).reshape(img.shape[0], img.shape[1])
img = np.repeat(mask[..., None], 3, axis=2) * img