我正在尝试使用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"
?
答案 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)
在这里,我将白色sub_img
粘贴在左上方的img
上,并屏蔽了粘贴操作中约70%的像素,因此只有~30%的像素在该地区实际上是白色的。