I would like to improve the layer mask that I am creating in Python. Although my mask pretty much hits the targeted color, my main problem with it, is it is doing so in binary, the pixel is either pure white or pure black. I'm unable to extrapolate the intensity of the color. I want to achieve something like how Photoshop does it wherein there are mid-tones of grey on the mask.

Here is the current attempt: import cv2
image = cv2.imread('grade_0.jpg')
lower = np.array([0,0,0])
upper = np.array([12,255,255])
mask = cv2.inRange(cv2.cvtColor(image, cv2.COLOR_BGR2HSV), lower, upper)
mask = 255 - mask
# mask = cv2.bitwise_not(mask) #inverting black and white
output = cv2.bitwise_and(image, image, mask = mask)
cv2.imshow("output", output)
cv2.imshow("mask", mask)
cv2.waitKey()

Here are the plain images.

Biiiiiig picture first. It's clickable and should be clicked. Let your eyes wander.

Pick your parameters:
Common definitions and functions:
import numpy as np
import cv2 as cv
target = (75, 105, 150) # BGR
subject = cv.imread(...)
distvecs = subject - np.float32(target)[None, None, :]
One flavor of weighting the color differences:
distvecs *= (0.114, 0.587, 0.299) # blue weighted least, according to perception
distance = distvecs.sum(axis=2) # manhattan distance
Other flavor of weighting the color differences:
# equal weight, euclidean distance
distance = np.linalg.norm(distvecs, axis=2)
You can come up with whatever you like. You could even mess around with color spaces. There are no rules.
Applying the gaussian to the distances:
def gaussian(x, sigma):
return np.exp(-np.power(x, 2) / (2 * np.power(sigma, 2)))
def max_normalize(x):
return x / x.max()
scored = max_normalize(gaussian(distance, sigma))
And that's the "mask".
And here's another result with a different target color, BGR tuple (68, 60, 100)

And another, for (121, 45, 87):

I'm surprised that everyone seems to do some kind of threshold, i.e. visible discontinuities.
There is some of that in my solution too, but only where the pictures contain high frequency components (strong gradients).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With