Remove everything of a specific color (with a color variation tolerance) from an image with Python

Issue

I have some text in blue #00a2e8, and some text in black on a PNG image (white background).

How to remove everything in blue (including text in blue) on an image with Python PIL or OpenCV, with a certain tolerance for the variations of color?

Indeed, every pixel of the text is not perfectly of the same color, there are variations, shades of blue.

Here is what I was thinking:

  • convert from RGB to HSV
  • find the Hue h0 for the blue
  • do a Numpy mask for Hue in the interval [h0-10, h0+10]
  • set these pixels to white

Before coding this, is there a more standard way to do this with PIL or OpenCV Python?

Example PNG file: foo and bar blocks should be removed

enter image description here

Solution

Your image has some issues. Firstly, it has a completely superfluous alpha channel which can be ignored. Secondly, the colours around your blues are quite a long way from blue!

I used your planned approach and found the removal was pretty poor:

#!/usr/bin/env python3

import cv2
import numpy as np

# Load image
im = cv2.imread('nwP8M.png')

# Define lower and upper limits of our blue
BlueMin = np.array([90,  200, 200],np.uint8)
BlueMax = np.array([100, 255, 255],np.uint8)

# Go to HSV colourspace and get mask of blue pixels
HSV  = cv2.cvtColor(im,cv2.COLOR_BGR2HSV)
mask = cv2.inRange(HSV, BlueMin, BlueMax)

# Make all pixels in mask white
im[mask>0] = [255,255,255]
cv2.imwrite('DEBUG-plainMask.png', im)

That gives this:

enter image description here

If you broaden the range, to get the rough edges, you start to affect the green letters, so instead I dilated the mask so that pixels spatially near the blues are made white as well as pixels chromatically near the blues:

# Try dilating (enlarging) mask with 3x3 structuring element
SE   = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
mask = cv2.dilate(mask, kernel, iterations=1)

# Make all pixels in mask white
im[mask>0] = [255,255,255]
cv2.imwrite('result.png', im)

That gets you this:

enter image description here

You may wish to diddle with the actual values for your other images, but the principle is the same.

Answered By – Mark Setchell

Answer Checked By – Timothy Miller (AngularFixing Admin)

Leave a Reply

Your email address will not be published.