在opencv 2中扩展像素选择

问题描述

我在cv2中的图像上有一个选择蒙版,我想扩展像素的选择范围,以便可以将已选择像素半径R之内的每个像素都添加到选择范围中。

我希望它的工作方式与Photoshop中的扩展功能相同。

我能想到的唯一方法是查看图像中的每个像素,如果它在选择中,则将半径R之内的每个像素更改为选择的一部分。

最大的问题是它具有运行时O(R ^ 2 *#像素)。

这真的很慢,我知道必须有更好的方法,因为即使对于大图片,Photoshop扩展选择方法也几乎可以立即起作用。 所以我想要一种方法来更改cv2或numpy中的方法以使其更快。 (也许有一种矢量化方法,但我不知道)

解决方法

我想出了如何扩展选区的唯一问题,即选区的图像边缘可能会出现一些错误。假设您具有布尔值掩码,这实际上很简单。除非它实际上没什么大不了,但是如果掩码是代表未选定区域的零和代表选定区域的正数,掩码仍然可以工作。

def expand(selection,radius):
    cop = np.copy(selection)
    for x in range(-radius,radius+1):
        for y in range(-radius,radius+1):
            if (y==0 and x==0) or (x**2 + y**2 > radius **2):
                continue
            shift = np.roll(np.roll(selection,y,axis = 0),x,axis = 1)
            cop += shift

    return cop
    

这是一个效果很好的简单示例

sel = np.array([[False,False,False],\
                [False,True,False]])
expand(sel,2)

这运行得更快,我也相信O(R ^ 2)相当快。它还为Photoshop扩展功能提供了类似于选择的结果。我相信唯一的区别是我的方法选择的是半径为R的圆内的像素,但是Photoshop选择的半径为R的六边形内的像素,这是可以添加到if语句中的细微差别。