我该如何将一张图片叠加在另一张图片上,使得暗色背景变为透明?

4

我有两张图片,test1.jpg和test2.jpg,它们都是RGB图像。它们已经从2D numpy数组转换为单色图像。它们具有相同的形状。当我使用paste函数时,我只能看到其中一张图片而不是两张。

这里是test1和test2的jpg文件:

test1

test2.

这是我在执行test1.paste(test2)test1.save('final.jpg')之后得到的结果:

result of paste

为什么只显示test2?

这是我的代码:

im1 = Image.open('test1.jpg')
im2 = Image.open('test2.jpg')
im1.paste(im2)
im1.save('final.jpg')

我认为粘贴基本上是将两个图像叠加在一起。那不对吗?我希望"arms"都在同一张图像中,而我认为这就是粘贴的作用。 - Harsh Ambardekar
“在执行test1.paste(test2)和test2.save('final.jpg')之后,我得到的结果是什么?”“你是要保存test1还是test2? 样例代码与你的解释不同。这个样例应该是可以工作的。” - user25004
哦,那很有道理。我想我误解了粘贴的作用。是否有一种方法/函数可以将两个图像的内容合并在一起,而不考虑背景(我希望在一个图像中有两只手臂,因此基本上只需将第一个图像中的白色部分添加到第二个图像中的完全相同位置)? - Harsh Ambardekar
3个回答

5
你只需要使用 PIL 通道操作 选择在每个点上两张图像中更轻的那一张:
from PIL import Image, ImageChops

im1 = Image.open('test1.jpeg')
im2 = Image.open('test2.jpeg')

# Choose lighter of the two images at each pixel location
combined = ImageChops.lighter(im1,im2)

enter image description here


请注意,您可以按照最初的意图使用paste(),但它会将image2中的所有黑色像素和白色像素粘贴到image1上。为了避免这种情况,您需要制作一个蒙版,并仅在image2非零时才进行粘贴。代码如下所示:

im1 = Image.open('test1.jpeg')
im2 = Image.open('test2.jpeg')

# Make greyscale mask from image2
mask = im2.convert('L')
mask = mask.point(lambda i: 255 if i>0 else 0)

# Paste image2 into image1 only where image2 has non-black content
im1.paste(im2, mask=mask)

我认为ImageChops.lighter()方法更简单。


请注意,这两种方法将给出略有不同的结果。例如,如果像素在image1中是192,在image2中为67,则ImageChops.lighter()方法将导致192,而paste()方法会看到image2中有内容,因此会给你67。由您决定!

谢谢!这两种方法都很好。 - Harsh Ambardekar

2

paste这个工具并不适合这个任务,因为它会完全替换原始图片,以显示你要粘贴的图片。看起来你需要更接近混合函数的东西,它可以产生两张图像的混合效果。不幸的是,这会导致图像变暗,因为白色与黑色混合后会变成中灰色;您可能需要将值加倍以进行补偿。

final = Image.blend(test1, test2, 0.5)
final = Image.eval(final, lambda x: 2*x))

1
一种解决方案是使用OpenCV而不是PIL。 OpenCV的图像与2D numpy数组完全相同,这意味着您可以仅使用基本矩阵加法来生成组合图像,而“黑色”像素只是0。
import cv2 as cv

im1 = cv.imread('test1.jpg')
im2 = cv.imread('test2.jpg')

im3 = im1 + im2
cv.imwrite('test3.jpg', im3)

黑色像素保持不变,因为你将0加上0,而填充的像素具有两个图像组合的填充值(在这种情况下,0 + 最大255,如果两个图像之间没有重叠)。
最终的图像:

Combined form of the supplied test images

如果存在重叠的非零像素,您可以对数组应用255上限,或者根据您的使用情况,将合并图像归一化为新的最大值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接