在Python中使用掩模对图像进行有效模糊

use*_*014 5 python opencv numpy image-processing blur

我需要模糊图像的特定区域。我得到图像和描述图像中需要模糊的区域的蒙版。它可以工作,但比预期慢一点,因为我需要模糊数十张图像。

这是我使用的代码:

def soft_blur_with_mask(image: np.ndarray, mask: np.ndarray) -> np.ndarray:
    assert len(mask.shape) == 2, mask.shape
    # Create a blurred copy of the original image. This can take up to 1-2 seconds today, because the image is big (~5-10 Megapixels)
    blurred_image = cv2.GaussianBlur(image, (221, 221), sigmaX=20, sigmaY=20)
    image_height, image_width = image.shape[:2]
    mask = cv2.resize(mask.astype(np.uint8), (image_width, image_height), interpolation=cv2.INTER_NEAREST)
    # Blurring the mask itself to get a softer mask with no firm edges
    mask = cv2.GaussianBlur(mask.astype(np.float32), (11, 11), 10, 10)[:, :, None]
    mask = mask/255.0

    # Take the blurred image where the mask it positive, and the original image where the image is original
    return (mask * blurred_image + (1.0 - mask) * image).clip(0, 255.0).astype(np.uint8)
Run Code Online (Sandbox Code Playgroud)

Pio*_*ski 2

您需要使用不同的算法进行模糊。让我们定义两个参数:n- 图像中的像素数和r高斯模糊滤波器的窗口大小。

你使用一个非常大的内核 - 221x221 像素所以r等于 221。使用标准卷积方法,每个像素需要 221^2 = 48841 次操作。这将导致 O( r^2*n) 的计算复杂度。但是,您可以使用中心极限定理,并在两个方向上分别使用一系列盒式滤波器来近似模糊中使用的内核。如果您利用两个连续像素的邻域仅在一个像素上不同的事实,则可以获得更快的处理时间。最后你可以得到与窗口大小无关的计算复杂度:O(· n)。请参阅解释整个过程的链接。它是用 Javascript 编写的,但数学很简单并且解释得很好,所以你绝对可以使用 Python 来实现它。