Выбор правильных верхних и нижних границ HSV для определения цвета с помощью 'cv :: inRange' (OpenCV)
У меня есть изображение кофе с оранжевой крышкой, которую я хочу найти.
Вот он
.
Утилита
gcolor2 показывает HSV в центре крышки (22, 59, 100).
Вопрос в том, как выбрать границы цвета? Я попробовал min = (18, 40, 90) и max = (27, 255, 255), но получил неожиданный ![result]()
Вот код Python:
import cv
in_image = 'kaffee.png'
out_image = 'kaffee_out.png'
out_image_thr = 'kaffee_thr.png'
ORANGE_MIN = cv.Scalar(18, 40, 90)
ORANGE_MAX = cv.Scalar(27, 255, 255)
COLOR_MIN = ORANGE_MIN
COLOR_MAX = ORANGE_MAX
def test1():
frame = cv.LoadImage(in_image)
frameHSV = cv.CreateImage(cv.GetSize(frame), 8, 3)
cv.CvtColor(frame, frameHSV, cv.CV_RGB2HSV)
frame_threshed = cv.CreateImage(cv.GetSize(frameHSV), 8, 1)
cv.InRangeS(frameHSV, COLOR_MIN, COLOR_MAX, frame_threshed)
cv.SaveImage(out_image_thr, frame_threshed)
if __name__ == '__main__':
test1()
Ответы
Ответ 1
Проблема 1: Различные приложения используют разные шкалы для HSV. Например, gimp использует H = 0-360, S = 0-100 and V = 0-100
. Но OpenCV использует H: 0-179, S: 0-255, V: 0-255
. Здесь я получил значение оттенка 22 в GIMP. Поэтому я взял половину, 11, и определил диапазон для этого. т.е. (5,50,50) - (15,255,255)
.
Проблема 2: А также, OpenCV использует формат BGR, а не RGB. Поэтому измените код, который преобразует RGB в HSV, следующим образом:
cv.CvtColor(frame, frameHSV, cv.CV_BGR2HSV)
Теперь запустите это. Я получил вывод следующим образом:
![enter image description here]()
Надеюсь, это то, что вы хотели. Есть несколько ложных обнаружений, но они маленькие, поэтому вы можете выбрать самый большой контур, которым является ваша крышка.
РЕДАКТИРОВАТЬ:
Как сказал в своем комментарии Карл Филипп, было бы неплохо добавить новый код. Но есть изменение только одной строки. Итак, я хотел бы добавить тот же код, реализованный в новом модуле cv2
, чтобы пользователи могли сравнить легкость и гибкость нового модуля cv2
.
import cv2
import numpy as np
img = cv2.imread('sof.jpg')
ORANGE_MIN = np.array([5, 50, 50],np.uint8)
ORANGE_MAX = np.array([15, 255, 255],np.uint8)
hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
frame_threshed = cv2.inRange(hsv_img, ORANGE_MIN, ORANGE_MAX)
cv2.imwrite('output2.jpg', frame_threshed)
Это дает тот же результат, что и выше. Но код намного проще.
Ответ 2
Я создал эту простую программу для получения кодов HSV в реальном времени
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
def nothing(x):
pass
# Creating a window for later use
cv2.namedWindow('result')
# Starting with 100 to prevent error while masking
h,s,v = 100,100,100
# Creating track bar
cv2.createTrackbar('h', 'result',0,179,nothing)
cv2.createTrackbar('s', 'result',0,255,nothing)
cv2.createTrackbar('v', 'result',0,255,nothing)
while(1):
_, frame = cap.read()
#converting to HSV
hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
# get info from track bar and appy to result
h = cv2.getTrackbarPos('h','result')
s = cv2.getTrackbarPos('s','result')
v = cv2.getTrackbarPos('v','result')
# Normal masking algorithm
lower_blue = np.array([h,s,v])
upper_blue = np.array([180,255,255])
mask = cv2.inRange(hsv,lower_blue, upper_blue)
result = cv2.bitwise_and(frame,frame,mask = mask)
cv2.imshow('result',result)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
Ответ 3
Хорошо, найти цвет в пространстве HSV
- это старый, но общий вопрос. Я сделал hsv-colormap
чтобы быстро найти особый цвет. Вот:
![enter image description here]()
Ось X представляет Hue
в [0,180), ось y1 представляет Saturation
в [0,255], ось y2 представляет S = 255
, а V = 255
.
Чтобы найти цвет, обычно просто найдите диапазон H
и S
и установите v в диапазоне (20, 255).
Чтобы найти оранжевый цвет, мы ищем карту и находим лучший диапазон: H :[10, 25], S: [100, 255], and V: [20, 255]
. Таким образом, маска является cv2.inRange(hsv,(10, 100, 20), (25, 255, 255) )
Затем мы используем найденный диапазон для поиска оранжевого цвета, это результат:
![enter image description here]()
Метод прост, но распространен для использования:
#!/usr/bin/python3
# 2018.01.21 20:46:41 CST
import cv2
img = cv2.imread("test.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv,(10, 100, 20), (25, 255, 255) )
cv2.imshow("orange", mask);cv2.waitKey();cv2.destroyAllWindows()
Похожие ответы:
-
Как определить пороговое значение для обнаружения только объектов зеленого цвета в изображении: Opencv
-
Выбор правильных значений HSV для порога OpenCV с помощью InRangeS
Ответ 4
Диапазон OpenVV HSV:
H: от 0 до 179
S: от 0 до 255
V: от 0 до 255
В Gimp (или другой манипуляции с фотографиями sw) диапазон оттенков от 0 до 360, так как opencv помещает информацию о цвете в один байт, максимальное числовое значение в одном байте равно 255, поэтому значения openCV Hue эквивалентны значениям оттенка от gimp разделен на 2.
Я обнаружил, что при попытке обнаружения объекта на основе цветового пространства HSV диапазон 5 (диапазон opencv) был достаточным для фильтрации определенного цвета. Я бы посоветовал вам использовать цветное неба HSV, чтобы выяснить диапазон, который лучше всего подходит для вашего приложения.
![Цветовое небо HSV с обнаружением цвета в пространстве HSV]()
Ответ 5
Чтобы найти значение HSV для Green, попробуйте следующие команды в терминале Python
green = np.uint8([[[0,255,0 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print hsv_green
[[[ 60 255 255]]]