Reputation: 6826
I have an image and some binary masks I want to apply to the image to highlight certain areas. I'm able to draw one mask, but each subsequent applied mask lightens the previous mask and the original image more and more.
How can I apply multiple masks while keeping each mask and the image brightness constant?
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)
I have also tried using Image.composite()
, but it only shows the mask and whites out the rest of the image.
image = Image.composite(image, annotation1, mask1)
Upvotes: 5
Views: 3718
Reputation: 6826
You can use ImageDraw.bitmap(xy, bitmap, fill=None) to draw masks from bitmaps. You can have multiple shades per mask, but only one color.
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)
Upvotes: 5