【问题标题】:How to crop an image by its mask [duplicate]如何通过蒙版裁剪图像[重复]
【发布时间】:2022-02-22 11:12:30
【问题描述】:

我有这张图片:

对于胡须,我有这个面具:

我想用这样的透明背景的面具剪掉胡须:

我遵循了SO post 的尝试。这里是:

for img in input_images:
    gaberiel = Image.open(path + '/gaberiel-images/' + img)

    beard_mask = imread(path + '/gaberiel-masks/' + 'beard_binary_' + img[:-4] + '.png', cv2.IMREAD_GRAYSCALE)

    gaberiel_x, gaberiel_y = gaberiel.size
    beard_mask_x, beard_mask_y, _ = beard_mask.shape

    x_beard_mask= min(gaberiel_x, beard_mask_x)
    x_half_beard_mask = beard_mask.shape[0] // 2

    mask_beard = beard_mask[x_half_beard_mask - x_beard_mask // 2: x_half_beard_mask + x_beard_mask // 2 + 1, :gaberiel_y]

    gaberiel_width_half = gaberiel.size[1] // 2
    gaberiel_to_mask = gaberiel[:, gaberiel_width_half - x_half_beard_mask:gaberiel_width_half + x_half_beard_mask]
    masked = cv2.bitwise_and(gaberiel_to_mask, gaberiel_to_mask, mask=mask_beard)

    tmp = cv2.cvtColor(masked, cv2.COLOR_BGR2GRAY)
    _, alpha = cv2.threshold(tmp, 0, 255, cv2.THRESH_BINARY)
    b, g, r = cv2.split(masked)
    rgba = [b, g, r, alpha]
    masked_tr = cv2.merge(rgba, 4)

    plt.axis('off')
    plt.imshow(masked_tr)

但这是我得到的错误:

gaberiel_to_mask = gaberiel[:, gaberiel_width_half - x_half_beard_mask:gaberiel_width_half + x_half_beard_mask]
TypeError: 'PngImageFile' object is not subscriptable

我认为我的尝试总体上很糟糕。有没有办法可以简化这个过程?

【问题讨论】:

标签: python machine-learning computer-vision semantic-segmentation


【解决方案1】:

确保您的蒙版与您的图像大小相同,然后使用如下功能:

def apply_mask(image, mask):
    # Convert to numpy arrays
    image = np.array(image)
    mask = np.array(mask)
    # Convert grayscale image to RGB
    mask = np.stack((mask,)*3, axis=-1)
    # Multiply arrays
    resultant = image*mask
    return resultant

image = ...
mask = ...

resultant = apply_mask(image, mask)

结果:

要使代码正常工作,图像数组必须在 0-255 范围内,并且掩码数组必须是二进制(0 或 1)。在遮罩数组中,胡须区域的像素值必须为 1,其余为 0,这样图像与遮罩相乘就会得到所需的图像,如上所示。

将图像保存为具有透明背景的 png:

import matplotlib.pyplot as plt
plt.plot(resultant)
plt.savefig('image.png', transparent=True)

【讨论】:

  • 如果我想让背景透明而不是黑色怎么办?另外,您如何将其保存为png?结果的 dtype 是什么?
  • @oo92 结果的dtype将是图像数组的dtype
  • @oo92 我已经更新了我的答案,看看吧。
  • resultant = image * mask 抛出此错误:ValueError: operands could not be broadcast together with shapes (280,300,3) (280,300,3,3)
  • @oo92 那是因为你的蒙版已经是RGB了,只要在apply_mask函数中注释掉灰度到RGB的转换线,就会排除错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-10
  • 2021-10-02
  • 2015-11-04
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
相关资源
最近更新 更多