【问题标题】:PIL remove background image from imagePIL 从图像中删除背景图像
【发布时间】:2016-02-21 03:27:31
【问题描述】:

使用背景图片,我能否从另一张图片中删除该背景并获得所有差异?例如:

假设我保存了这两张图片。如何在保留所有猫的同时从第二张图片中删除第一张图片?

【问题讨论】:

    标签: python background python-imaging-library


    【解决方案1】:

    根据PIL handbookImageChops模块有减法运算:

    ImageChops.subtract(image1, image2, scale, offset) => image
    Subtracts two images, dividing the result by scale and adding the offset.
    If omitted, scale defaults to 1.0, and offset to 0.0.
    out = (image1 - image2) / scale + offset
    

    您可以将生成的图像用作带有猫的图像的蒙版:保留蒙版不为零的像素,否则使它们成为所需的背景颜色。

    示例代码如下:

    from PIL import Image
    from PIL import ImageChops
    image1 = Image.open("image1.jpg") # no cats
    image2 = Image.open("image2.jpg") # with cats
    
    image = ImageChops.subtract(image2, image1)
    
    mask1 = Image.eval(image, lambda a: 0 if a <= 24 else 255)
    mask2 = mask1.convert('1')
    
    blank = Image.eval(image, lambda a: 0)
    
    new = Image.composite(image2, blank, mask2) 
    new.show()
    

    它几乎可以工作:-)

    这两个图像之间的差异比看起来要大一些。由于图像以 JPG 格式存储,因此它们是有损的。它们的渲染会略有不同,因此对于相同区域中的像素,减法运算不会总是导致为零(即黑色)。

    出于这个原因,我不得不将lambda a: 0 if a &lt;= 24 else 255 用于eval 函数以获得合理的结果。

    如果您使用无损图像,它应该可以正常工作。然后您应该使用0 if a == 0 else 255 创建掩码。

    请注意,如果某些“猫”像素意外与背景像素相同,它们将显示为黑色像素。

    【讨论】:

    • ImageChops.subtract() 行出现“ValuesError:图像不匹配”
    • @NeonWizard 如果我使用您发布的图像,它对我来说很好。我已经添加了我得到的图像。也许您使用的原始图像不同,因为您从背景图像创建了“猫”图像,并在执行此操作时更改了一些图像属性(例如大小)。您可以使用print image.infoprint image.size等打印图像属性。参见effbot.org/imagingbook/image.htm#tag-Image.Image.verify
    • 我用别的东西测试了它,一个游戏。我确保图像尺寸相同。 i.imgur.com/eC2MZHb.pngi.imgur.com/UqSKEzN.png
    • @NeonWizard 我得到了和你一样的错误。原因是因为你的图像不一样。一个是RGB,另一个是RGBA。如果我使用image.convert('RGB') 将第二个图像转换为RGB 它可以工作。
    • 你怎么知道一个是 RGBA 而另一个是 RGB?