繁体   English   中英

图像覆盖某些像素

[英]Image overlay certain pixels

我有两个功能。
第一个将叠加图像中所有黑色像素的不透明度更改为 0。
第二张图片叠加到另一张图片上,不透明度发生变化。 但仅适用于所有非黑色像素。
总的来说,我想叠加具有不同不透明度的图像,并防止黑色背景不显示。
它工作得很好,但不是很快(均 > 2 秒)。 有没有办法稍微加快这个过程? 例如Numpy?
这是我到目前为止所拥有的:

def remove_background(image):
   im = image.convert('RGBA')
   w, h = im.size
   for i in range(w):
       for j in range(h):
           cordinate = i, j
           rgb_map = im.getpixel(cordinate)
           if rgb_map == (0, 0, 0, 255):
               im.putpixel(cordinate, (0, 0, 0, 0))
   return im


def overlay_image(background, overlay, opacity=0.5):
   background = background.convert('RGBA')
   overlay = overlay.convert('RGBA')
   opacity = int(opacity * 255)
   w, h = background.size
   for i in range(w):
       for j in range(h):
           cordinate = i, j
           rgb_map = overlay.getpixel(cordinate)
           r = rgb_map[0]
           g = rgb_map[1]
           b = rgb_map[2]
           if r == 64 and g == 128 and b == 19:
               overlay.putpixel(cordinate, (64, 128, 19, opacity))
   background.paste(overlay, (0,0), overlay)
   return background

我知道PIL中有一个名为Image.blend()的东西,但这仅适用于整个图像,而不适用于某些像素。

这是我要叠加的示例:

animal

在此处输入图像描述

mask

在此处输入图像描述

result

在此处输入图像描述

更新的答案

我认为这就是您更新的问题正在寻找的内容:

#!/usr/bin/env python3

from PIL import Image

# Open the mask, discarding any alpha channel
mask = Image.open('mask.png').convert('RGB')

# Generate a new alpha channel that is transparent wherever the mask is black
alpha = mask.copy()
alpha = alpha.convert('L')
alpha.point(lambda p: 128 if p > 0 else 0)

# Open the animal, discarding its pointless alpha channel
animal = Image.open('animal.png').convert('RGB')

# Paste the mask over the animal, respecting transparency
animal.paste(mask,mask=alpha)
animal.save('result.png')

在此处输入图像描述

选择

或者,您可以简单地将面具添加到动物身上。 在掩码为黑色(即零)的地方,它不会添加任何内容:

#!/usr/bin/env python3

from PIL import Image, ImageChops

# Open the mask, discarding any alpha channel
mask = Image.open('mask.png').convert('RGB')

# Open the animal, discarding any alpha channel
animal = Image.open('animal.png').convert('RGB')

# Add the mask to the animal
res = ImageChops.add(animal, mask)
res.save('result.png')

在此处输入图像描述

如果绿色太多,您可以先缩放遮罩,比如缩小一半,使用Image.point()和 lambda 如下所示。

原始答案

嗯,如果你想用另一个输入图像屏蔽一个输入图像并显示结果,我认为你需要三个图像,而不是两个。

所以,我猜这就是你想要的,它应该又好又快:

#!/usr/bin/env python3

from PIL import Image

# Open the mask, discarding its pointless alpha channel and colour information
mask = Image.open('mask.png').convert('L')

# Generate a new alpha channel that is transparent wherever the mask is black
mask.point(lambda p: 255 if p > 0 else 0)

# Open the animal, discarding its pointless alpha channel
animal = Image.open('animal.png').convert('RGB')

# Put our lovely new alpha channel into animal image and save
animal.putalpha(mask)
animal.save('result.png')

mask.png

在此处输入图像描述

animal.png

在此处输入图像描述

在此处输入图像描述

只是为了好玩,这是利用 Numpy 的另一种方法:

#!/usr/bin/env python3

from PIL import Image
import numpy as np

# Open the overlay and animal,  discarding any alpha channel
overlay = Image.open('mask.png').convert('RGB')
animal  = Image.open('animal.png').convert('RGB')
mask    = overlay.convert('L')

# Make into Numpy arrays
overlay= np.array(overlay)
animal = np.array(animal)
mask   = np.array(mask)

# Blend animal and overlay
blended = animal//2 + overlay//2

# Choose blended or original at each location depending on mask
res = np.where(mask[...,np.newaxis], blended, animal)

# Revert to PIL Image and save
Image.fromarray(res).save('result.png')

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM