OpenCV inRange () работает для RGB, но не для цветового пространства HSV - PullRequest
2 голосов
/ 09 июля 2019

Я сгенерировал диаграмму рассеяния моего изображения в формате RGB и HSV и использую inRange(), чтобы ограничить выделение одного цвета глазом графика.

Чтобы получить точные значения RGB и HSV, я использую палитру цветов paint.net, чтобы получить значение RGB, а затем Преобразователь RGB в HSV , чтобы получить значения HSV.

enter image description here

Цвета пикселей и график рассеяния генерируются:

img = cv2.imread('C:\\b_.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)


pixel_colors = img.reshape((np.shape(img)[0]*np.shape(img)[1], 3))
norm = colors.Normalize(vmin=-1., vmax=1.)
norm.autoscale(pixel_colors)
pixel_colors = norm(pixel_colors).tolist()

h, s, v = cv2.split(img_hsv)
fig = plt.figure()
axis = fig.add_subplot(1, 1, 1, projection="3d")

axis.scatter(h.flatten(), s.flatten(), v.flatten(), facecolors=pixel_colors, marker=".")
axis.set_xlabel("Hue")
axis.set_ylabel("Saturation")
axis.set_zlabel("Value")
plt.show()

Мне нужно извлечь желтый цвет из моего изображения. Как уже упоминалось, я использую палитру цветов paint.net для получения значений RGB светло-желтого и темно-желтого. А затем используйте конвертер, чтобы получить значения HSV для функции inRange().

light_yellow = (60, 89, 97)    # HSV VALUES
dark_yellow = (61, 36.6, 43.9)

mask = cv2.inRange(img_hsv, light_yellow, dark_yellow)
result = cv2.bitwise_and(img, img, mask=mask)

но сгенерированный результат является черным изображением, однако, если я использую значения RGB непосредственно светлого и темно-желтого и использую изображение RGB, а не преобразованное изображение HSV, сегментация работает.

light_yellow = (249, 249, 125)    # RGB VALUES
dark_yellow = (111, 112, 71)

mask = cv2.inRange(img, light_yellow, dark_yellow)
result = cv2.bitwise_and(img, img, mask=mask)

enter image description here

Несмотря на то, что выше описана сегментация RGB, я чувствую, что она может быть улучшена в HSV. Почему мой диапазон HSV не дает выхода?

1 Ответ

4 голосов
/ 09 июля 2019

Как это выражено в документации cvtColor .Когда это CV_8U, значение H, которое обычно изменяется от 0 до 360, делится на 2 и идет от 0 до 180.Значения S и V обычно в процентах (0-100%), и они варьируются от 0 до 255.

Итак, ваше значение:

light_yellow = (60, 89, 97)    # HSV VALUES
dark_yellow = (61, 36.6, 43.9)

Должно быть больше похоже на:

# (H/2, (S/100) * 255, (V/100) * 255) 
light_yellow = (30, 227, 247)    # HSV VALUES
dark_yellow = (31, 93, 112)

Теперь у вас есть еще одна проблема, inRanges ищет значения внутри диапазона низких и высоких частот, а не по светлому и темно-желтому.Таким образом, ваши пределы должны быть:

low = (30,93,112)
high = (31, 227,247)

mask = cv2.inRange(img_hsv, low, high)

Еще одна вещь, я бы использовал больший диапазон для цвета H ... 30-31 довольно мало, может быть, 20-32 лучше?

...