如何使用带面膜的PIL膏?

时间:2017-12-08 22:36:54

标签: python numpy python-imaging-library

我正在尝试使用PIL paste()功能。我也想戴上面具,但我不断收到这个错误:

  

ValueError:具有多个元素的数组的真值是不明确的。使用a.any()或a.all()

canvases[0].paste(mnist_images[i],
                  box=tuple(map(lambda p: int(round(p)), positions[i])), mask=mask)

代码无需掩码即可运行。面具是一个numpy数组。我没有看到带掩码的示例,文档也不清楚。

https://pillow.readthedocs.io/en/latest/reference/Image.html#PIL.Image.Image.paste

  

如果给出了掩码,则此方法仅更新掩码指示的区域。您可以使用"1""L""RGBA"图像(在后一种情况下,Alpha波段用作蒙版)。掩码为255时,给定图像按原样复制。掩码为0时,保留当前值。中间值会将两个图像混合在一起,包括它们的alpha通道。

我没有RGBA,那么如何使用"1""L"

1 个答案:

答案 0 :(得分:8)

面具也必须是PIL Image。这并没有明确提到in the docs,但确实说明了:

  

您可以使用“1”,“L”或“RGBA”图像(在后一种情况下,Alpha波段用作蒙版)。掩码为255时,给定图像按原样复制。掩码为0时,保留当前值。中间值会将两个图像混合在一起,包括它们的alpha通道。

所以这暗示他们需要成为PIL Image。来自Pillow concepts page

  

图像的模式定义了像素中的像素的类型和深度   图片。当前版本支持以下标准模式:

     

1(1位像素,黑白,每字节存储一个像素)
  L(8位像素,黑色和白色)
  ...

然后修复只需将面具转换为PIL Image

mask = Image.fromarray(mask)

但是,请注意,对于二进制掩码,PIL期望掩码在其中仅包含0和255,如上所述(将在混合之间的值)。因此,如果你的面具是一个numpy bool类型,那么你想做的事情如下:

mask = Image.fromarray(np.uint8(255*mask))

例如:

>>> import numpy as np
>>> import cv2
>>> from PIL import Image
>>> img = Image.fromarray(np.uint8(255*np.random.rand(400, 400, 3)))
>>> sub_img = Image.fromarray(np.uint8(255*np.ones((200, 200, 3))))
>>> mask = Image.fromarray(np.uint8(255*(np.random.rand(200, 200) > 0.7)))
>>> img.paste(sub_img, (0, 0), mask)

Masked paste

在这里,我将白色sub_img粘贴在左上方的img上,并屏蔽了粘贴操作中约70%的像素,因此只有~30%的像素在该地区实际上是白色的。