Я полагаю, у вас есть дальнейшее чтение о том, как работает цветовое пространство HSL / HSV, возможно, начиная с статьи Википедии ?Кроме того, чтобы легко получить некоторые начальные значения для работы, вы можете использовать калькулятор HSL, например, this one.
Чтобы обнаружить детали белого цвета на изображении, оттенок (H)значение может быть произвольным, если значение lightness (L) достаточно высоко (нам нужны яркие цвета), а значение насыщенности (S) достаточно мало (нам нужны цвета с низким насыщением).
В общемЗначения H находятся в пределах [0 ... 360]
, тогда как значения S и L находятся в пределах [0.0 ... 1.0]
.Документация OpenCV по преобразованию цветов сообщает, что эти значения отображаются в H в пределах [0 ... 180]
, а S и L в [0 ... 255]
(для 8-битных изображений).
ТеперьЧтобы обнаружить желтоватые участки изображения, соответствующие значения H, S и L могут быть взяты из вышеупомянутого калькулятора HSL путем «игры», что может соответствовать цветам, которые можно найти на изображении.
Я подготовил следующий пример кода, пожалуйста, посмотрите:
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)
Белая маска выглядит так:
Маска желтого цвета выглядит следующим образом:
Маскированное изображение из вашего кода выглядит следующим образом:
Как видите, необходимо выполнить точную настройку параметров.Но я надеюсь, что теперь у вас есть общее представление, и вы можете продолжить самостоятельно.