'Remove border from Logo using Python PIL

Hi I want to remove the white border from this Logo using python's pillow library. The only way I have thought of is to extract all white from the image but then this remove's the white eye of the horse as well and that is something I would like to keep.

What I have. https://i.stack.imgur.com/DX2LE.png

What I want. https://i.stack.imgur.com/IPVqi.png

This isn't a daunting task but there are a lot of logo's that I need to do this for so I would like an automated fashion of doing so. Here is some code to extract the image from the source. Thanks for any help anyone can provide.

from PIL import Image
import pandas as pd
import requests

filename = "https://a.espncdn.com/combiner/i?img=/i/teamlogos/ncaa/500/68.png"

image = Image.open(requests.get(filename, stream=True).raw)


Solution 1:[1]

I prefer using OpenCV but we can do it with PIL.

  • Replace white with transparency using the example from here
  • Get the alpha channel.
    Use ImageDraw.floodfill for filling the surrounding zero alpha with 255 color.
    (Only the eye stays black).
  • Invert alpha - make the eye white instead of black.
  • Paste the white eye on the image with the "transparent white".

Code sample (reading local image):

from PIL import Image, ImageDraw, ImageOps
import numpy as np

# https://stackoverflow.com/questions/765736/how-to-use-pil-to-make-all-white-pixels-transparent
def white_to_transparency(img):
    x = np.asarray(img.convert('RGBA')).copy()
    x[:, :, 3] &= (255 * (x[:, :, :3] != 255).any(axis=2)).astype(np.uint8)  # Small modification: &= is used instead of = (in the original code).
    return Image.fromarray(x)


filename = "68.png"

image = Image.open(filename)

im_white_transparent = white_to_transparency(image)

# https://stackoverflow.com/questions/63219166/advanced-cropping-with-python-imaging-library
# Extract alpha channel as new Image
alpha = im_white_transparent.getchannel('A')

# https://stackoverflow.com/questions/46083880/fill-in-a-hollow-shape-using-python-and-pillow-pil
# Fill alpha channel with 255, only the inner part stays 0
ImageDraw.floodfill(alpha, xy=(0, 0), value=255, thresh=200)

mask = ImageOps.invert(alpha)  # Invert alpha - make the eye white instead of black
im_white_transparent.paste(image, (0, 0), mask)  # Paste the white eye on the image with "transparent white".

# Show images for testing
im_white_transparent.show()
alpha.show()
mask.show()

Result:

im_white_transparent:
(change to dark mode for seeing the transparent background):
enter image description here

Same result with transparency as chessboard pattern:
enter image description here

mask:
enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rotem