如何根据分割图对图像进行模糊处理

How to blur the image according to segmentation map

如果我不是母语人士,无法很好地解释,请原谅我。

我正在根据分割图的白色部分对图像的部分进行模糊处理。例如,这是我的分割图像(bmp 图像)。 .

现在我想要的是在分割图中模糊原始图像中像素为白色的部分。我只是写了下面的代码。

mask = mask >= 0.5
mask = np.reshape(mask, (512, 512))

mh, mw = 512, 512
mask_n = np.ones((mh, mw, 3))

mask_n[:,:,0] *= mask
mask_n[:,:,1] *= mask
mask_n[:,:,2] *= mask

# discard padded area
ih, iw, _ = image_n.shape

delta_h = mh - ih
delta_w = mw - iw

top = delta_h // 2
bottom = mh - (delta_h - top)
left = delta_w // 2
right = mw - (delta_w - left)

mask_n = mask_n[top:bottom, left:right, :]


# addWeighted
image_n = image_n *1 +   cv2.blur(mask_n * 0.8, (800, 800))

请帮助我,谢谢。

您可以按照以下步骤进行:

  1. 加载原始图像和蒙版图像。
  2. 模糊整个原始图像并将其保存在不同的变量中。
  3. 使用 np.where() 方法 select 蒙版中您想要模糊值的像素,然后替换它。

查看下面的示例代码:

import cv2
import numpy as np

img = cv2.imread("./image.png")
blurred_img = cv2.GaussianBlur(img, (21, 21), 0)
mask = cv2.imread("./mask.png")

output = np.where(mask==np.array([255, 255, 255]), blurred_img, img)
cv2.imwrite("./output.png", output)

这是@Chris Henri 提出的解决方案的替代方案。它依赖于 scipy.ndimage.filters.gaussian_filter and NumPy's boolean indexing:

from skimage import io
import numpy as np
from scipy.ndimage.filters import gaussian_filter
import matplotlib.pyplot as plt

mask = io.imread('https://i.stack.imgur.com/qJiKf.png')
img = np.random.random(size=mask.shape[:2])
idx = mask.min(axis=-1) == 255
blurred = gaussian_filter(img, sigma=3)
blurred[~idx] = 0

fig, axs = plt.subplots(1, 3, figsize=(12, 4))
for ax, im in zip(axs, [img, mask, blurred]):
    ax.imshow(im, cmap='gray')
    ax.set_axis_off()
plt.show(fig)

这是另一种方法,尽管当您有一个 2D 分割数组指示每个索引 (i,j) 的像素分割对象 class(互斥)和 3D您要应用模糊的图片。

def gaussian_blur(image: np.ndarray,
              segmentation: np.ndarray,
              classes_of_interest: list,
              gaussian_variance: float = 10) -> np.ndarray:
'''
Function that applies a gaussian filter to the image,
specifically to the pixels contained in the possible segmented classes.
Returns an image (np.ndarray) where the gaussian blur intensity is
regulated by the parameter gaussian_variance. 
'''
#Apply masking to select only the indices where the specific class is present
mask = np.isin(segmentation, classes_of_interest)
#Creating a 3D mask for all the channels and place it at channel axis
mask_3d = np.stack([mask,mask,mask], axis=2)
#Mask the image according to the 3D mask
img_masked = np.where(mask_3d, img, 0).astype(np.int8)
#Define gaussian blur noisy function
def noisy(image):
    row,col,ch= image.shape
    mean = 0
    var = gaussian_variance
    sigma = np.sqrt(var)
    gauss = np.random.normal(mean,sigma,(row,col,ch))
    gauss = gauss.reshape(row,col,ch)
    #Sums up gaussian noise to img
    noisy = image + gauss
    return noisy.astype(np.uint8)
#Blurs the masked segmentation
img_masked_noisy = noisy(img_masked)
#Puts the blurred part back in the original image as substitution
img[mask_3d] = img_masked_noisy[mask_3d]
return img

这是一个玩具示例:

import numpy as np
possible_classes = [1,2,3]
#Setting up a toy example with a small image,                               
#shape (N, N, 3)
img = np.floor(np.random.random(size=(8,8,3)) * 256).astype(np.uint8)
#Setting up a fake segmentation with 3 mutually exclusive possible classes, 
#shape (N, N)
segmentation = np.random.choice(possible_classes, size=(8,8))
new_img_blurred = gaussian_blur(img,
              segmentation= segmentation,
              classes_of_interest= possible_classes[:2])