OpenCV:使用radius有替代cv2.inRange吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV:使用radius有替代cv2.inRange吗?相关的知识,希望对你有一定的参考价值。
我熟悉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中非常慢......
谢谢!
答案
创建一个掩码,指示欧几里德距离比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
另一答案
终于得到了一个有效的答案确切地说,我不想将自己限制为一种颜色,而是允许多种颜色。我正在使用内置的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
以上是关于OpenCV:使用radius有替代cv2.inRange吗?的主要内容,如果未能解决你的问题,请参考以下文章