Is it possible to isolate a BGR color gradient with cv2.inRange()?
Problem Description:
I am writing a program that observes an area on the screen that displays a number between 0 and 100. When the number is 100, it has green text. When the number is 0, it has red text. As the number decreases from 100, it slowly shifts in a gradient from solid green to solid red.
Some examples:
100
is rgb(0, 255, 0)
84
is rgb(73, 255, 0)
,
65
is rgb(172, 255, 0)
,
41
is rgb(255, 213, 0)
,
17
is rgb(255, 88, 0)
0
is rgb(255, 0, 0)
Question
Is it possible to isolate any/all colors in this range using cv2.inRange(img, lower, upper)
where lower
and upper
are numpy arrays in the form [B, G, R]
? If there is a suitable range, can you explain why it works?
I have this code:
import cv2
import numpy as np
image = cv2.imread("image_of_text.png")
# Generate mask for color range
lower = [0, 0, 0]
upper = [0, 0, 0]
mask = cv2.inRange(image, np.array(lower), np.array(upper))
# Create black mask
h, w = image.shape[:2]
mask_b = np.zeros([h, w, 1], dtype=np.uint8)
# Combine masks
mask = cv2.bitwise_or(mask_b, mask)
cv2.imshow('result', mask)
cv2.waitKey(0)
I would prefer to avoid HSV ranges as the rest of my program is not well suited for switching color spaces on the fly.
Solution – 1
Well, I solved this as I was writing up the question.
From what I can tell, we need to isolate two separate ranges:
GREEN –> lower
= rgb(0, 255, 0)
, upper
= rgb(255, 255, 0)
RED –> lower
= rgb(255, 0, 0)
, upper
= rgb(255, 255, 0)
Code:
import cv2
import numpy as np
image = cv2.imread("image_of_text.png")
upper = [0, 255, 255] # uppper is same for both
# Green range
lower = [0, 255, 0]
mask_g = cv2.inRange(image, np.array(lower), np.array(upper))
# Red range
lower = [0, 0, 255]
mask_r = cv2.inRange(image, np.array(lower), np.array(upper))
# Create black mask
h, w = image.shape[:2]
mask_b = np.zeros([h, w, 1], dtype=np.uint8)
# Combine masks
mask = cv2.bitwise_or(mask_b, mask_g)
mask = cv2.bitwise_or(mask, mask_r)
cv2.imshow('result', mask)
cv2.waitKey(0)
Just from looking at the text colors I listed in the question, I noticed how both middle numbers were close to rgb(255, 255, 0), but since there were two distinct ends to this gradient, I needed to specify two separate lower bounds while they both have the same upper bound.