在 opencv 2 中扩展像素选择

expand a selection of pixels in opencv 2

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

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

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

最大的问题是它的运行时间为 O(R^2 * # of pixels)。

这真的很慢,我知道一定有更好的方法,因为 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, False],\
                [False, False, False, False, False],\
                [False, False, True, False, False],\
                [False, False, False, False, False],\
                [False, False, False, False, False]])
expand(sel, 2)

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