OpenCV:使用radius有替代cv2.inRange吗?

问题描述 投票:1回答:2

我熟悉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中非常慢......

谢谢!

python image-processing colors opencv3.0
2个回答
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

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
© www.soinside.com 2019 - 2024. All rights reserved.