PIL remove background image from image

前端 未结 1 1894
囚心锁ツ
囚心锁ツ 2021-01-21 03:02

With a background image, would I be able to remove that background from another image and get all of the discrepancies? For example:

Pretend I have the

相关标签:
1条回答
  • 2021-01-21 03:47

    According to the PIL handbook, the ImageChops module has a subtract operation:

    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
    

    You can use the resulting image as a mask for the image with the cats: Keep the pixels where the mask is non-zero, otherwise make them the desired background colour.

    Sample code below:

    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()
    

    It almost works :-)

    There is a bit more difference between the two images than it seems. Because the images are stored as JPGs, they are lossy. They will be rendered slightly differently, so the subtract operation will not always result in zero (i.e. black) for the pixels in the areas that are the same.

    For this reason, I had to use lambda a: 0 if a <= 24 else 255 for the eval function to get a reasonable result.

    If you use loss-less images it should work properly. You should then use 0 if a == 0 else 255 to create the mask.

    Note that if some 'cat' pixels accidentally are the same as the background pixel, they will show up as black pixels.

    0 讨论(0)
提交回复
热议问题