I suggest, you have a further reading on how the HSL/HSV color space works, maybe starting at the Wikipedia article? Furthermore, to easily get some initial values to work on, you can use a HSL calculator, e.g. this one.
To detect white-ish parts in the image, the hue (H) value might by arbitrary, as long as the lightness (L) value is high enough (we want bright colors), and the saturation (S) value is low enough (we want low saturated colors).
In general, H values are within [0 ... 360]
, whereas S and L values are within [0.0 ... 1.0]
. The OpenCV documentation on color conversions tells you, that these values are mapped to H within [0 ... 180]
, and S and L within [0 ... 255]
(for 8-bit images).
Now, to detect yellow-ish parts in the image, appropriate H, S, and L values can be taken from the afore-mentioned HSL calculator by "playing around", what might fit to the colors to be found in the image.
I prepared the following example code, please have a look:
import cv2
import numpy as np
# Load input image
input = cv2.imread('images/input.png', cv2.IMREAD_COLOR)
# Convert to HLS color space
hls = cv2.cvtColor(input, cv2.COLOR_BGR2HLS)
# White-ish areas in image
# H value can be arbitrary, thus within [0 ... 360] (OpenCV: [0 ... 180])
# L value must be relatively high (we want high brightness), e.g. within [0.7 ... 1.0] (OpenCV: [0 ... 255])
# S value must be relatively low (we want low saturation), e.g. within [0.0 ... 0.3] (OpenCV: [0 ... 255])
white_lower = np.array([np.round( 0 / 2), np.round(0.75 * 255), np.round(0.00 * 255)])
white_upper = np.array([np.round(360 / 2), np.round(1.00 * 255), np.round(0.30 * 255)])
white_mask = cv2.inRange(hls, white_lower, white_upper)
# Yellow-ish areas in image
# H value must be appropriate (see HSL color space), e.g. within [40 ... 60]
# L value can be arbitrary (we want everything between bright and dark yellow), e.g. within [0.0 ... 1.0]
# S value must be above some threshold (we want at least some saturation), e.g. within [0.35 ... 1.0]
yellow_lower = np.array([np.round( 40 / 2), np.round(0.00 * 255), np.round(0.35 * 255)])
yellow_upper = np.array([np.round( 60 / 2), np.round(1.00 * 255), np.round(1.00 * 255)])
yellow_mask = cv2.inRange(hls, yellow_lower, yellow_upper)
# Calculate combined mask, and masked image
mask = cv2.bitwise_or(yellow_mask, white_mask)
masked = cv2.bitwise_and(input, input, mask = mask)
# Write output images
cv2.imwrite('images/white_mask.png', white_mask)
cv2.imwrite('images/yellow_mask.png', yellow_mask)
cv2.imwrite('images/masked.png', masked)
The white-ish mask looks like this:
The yellow-ish mask looks like this:
The masked image from your code looks like this:
As you can see, fine-tuning the parameters must be done. But I hope, you now get the general idea, and can continue on your own.