在图像上绘制多个透明蒙版

was*_*tor 5 python numpy python-imaging-library

我有一个图像和一些二进制蒙版,我想应用于图像以突出显示某些区域。我能够绘制一个蒙版,但随后应用的每个蒙版都会使前一个蒙版和原始图像越来越亮。

如何应用多个蒙版,同时保持每个蒙版和图像亮度恒定?

import numpy as np
import matplotlib
from matplotlib.pyplot import imshow
from PIL import Image, ImageDraw, ImageFont
import requests

matplotlib.rcParams['figure.figsize'] = (20.0, 10.0)

url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Grumpy_Cat_by_Gage_Skidmore.jpg/480px-Grumpy_Cat_by_Gage_Skidmore.jpg'
image = (Image.open(requests.get(url, stream=True).raw)).convert('RGBA')

annotation1 = (np.ones((image.size[1], image.size[0], 3))*255).astype(np.uint8)
annotation1[350:400, 50:450] = (255, 0, 0)
mask1 = (np.zeros((image.size[1], image.size[0])))
mask1[350:400, 50:450] = 1
mask1 = Image.fromarray(mask1, mode='1')

annotation2 = (np.ones((image.size[1], image.size[0], 3))*255).astype(np.uint8)
annotation2[400:450, 50:450] = (255, 0, 0)
mask2 = (np.zeros((image.size[1], image.size[0])))
mask2[350:400, 50:450] = 1
mask2 = Image.fromarray(mask2, mode='1')

annotation1 = Image.fromarray(annotation1, mode='RGB').convert('RGBA')
annotation2 = Image.fromarray(annotation2, mode='RGB').convert('RGBA')
annotation1.putalpha(128)
annotation2.putalpha(128)

image = Image.alpha_composite(image, annotation1)
image = Image.alpha_composite(image, annotation2)
imshow(image)
Run Code Online (Sandbox Code Playgroud)

我也尝试过使用Image.composite(),但它只显示蒙版并将图像的其余部分变白。

image = Image.composite(image, annotation1, mask1)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

was*_*tor 5

您可以使用ImageDraw.bitmap(xy, bitmap, fill=None)从位图绘制蒙版。每个面罩可以有多种色调,但只能有一种颜色。

url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Grumpy_Cat_by_Gage_Skidmore.jpg/480px-Grumpy_Cat_by_Gage_Skidmore.jpg'
image = (Image.open(requests.get(url, stream=True).raw)).convert('RGBA')
image.putalpha(128)

mask1 = (np.zeros((image.size[1], image.size[0]))).astype(np.uint8)
mask1[350:400, 50:450] = 255
mask1 = Image.fromarray(mask1, mode='L')

mask2 = (np.zeros((image.size[1], image.size[0]))).astype(np.uint8)
mask2[410:460, 50:450] = 255
mask2[415:455, 55:445] = 128
mask2 = Image.fromarray(mask2, mode='L')

overlay = Image.new('RGBA', image.size, (255,255,255,0))
drawing = ImageDraw.Draw(overlay)
drawing.bitmap((0, 0), mask1, fill=(255, 0, 0, 128))
drawing.bitmap((0, 0), mask2, fill=(255, 0, 0, 128))

image = Image.alpha_composite(image, overlay)

imshow(image)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述