使用Pillow和Numpy进行图像减法

4

我有两张图片: 在此输入图片描述

enter image description here

我想导出一张只有红色“Hello”的图片,如下所示:

enter image description here

所以我正在运行一个简单的Python扣除脚本:

from PIL import Image
import numpy as np

root = '/root/'
im1 = np.asarray(Image.open(root+'1.jpg'))
im2 = np.asarray(Image.open(root+'2.jpg'))

deducted_image = np.subtract(im1, im2)

im = Image.fromarray(np.uint8(deducted_image))
im.save(root+"deduction.jpg")

但是这返回:

enter image description here

我应该做些什么才能避免以上问题?此外,我需要numpy吗,还是只需使用Pillow库即可?

编辑:

它也应该适用于像这样的图片:

enter image description here

我的代码返回的结果:

enter image description here

为什么边缘会如此像素化,让人感到困惑!


还有,@Divakar,为什么它有时候不稳定? - maxisme
反问你一个问题 - 为什么最后一个黑色背景有斑点?黑色没有完全围绕着“Hello”。 - Divakar
4
由于您在保存和加载图像时使用了jpg压缩,所以np.subtract不是减去原始数值,而是减去稍微偏离的压缩数值,导致Hello标志周围出现补丁。因此,要么使用无损格式(如png等),要么使用复杂的斑点查找代码(而不是np.subtract)。 - Divakar
2
它们不被压缩为相同的值,因为它们是两个不同的图像。压缩取决于图像数据。 - Divakar
1
@Maximilian,你可以使用.png格式来消除压缩伪影;如果我没记错的话,这是最常用的无损格式。 - Pedro von Hertwig Batista
显示剩余6条评论
1个回答

3
也许更容易的方法是将第二幅图中你不想要的像素设置为0?
im = im2.copy()
im[im1 == im2] = 0
im = Image.fromarray(im)

对我来说似乎可以(显然只有更大的工件,因为我使用了您上传的JPG)

脚本结果

也可以在不使用numpy的情况下完成此操作:

from PIL import ImageChops
from PIL import Image

root = '/root/'
im1 = Image.open(root + '1.jpg')
im2 = Image.open(root + '2.jpg')

def nonzero(a):
    return 0 if a < 10 else 255

mask = Image.eval(ImageChops.difference(im1, im2), nonzero).convert('1')

im = Image.composite(im2, Image.eval(im2, lambda x: 0), mask)

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