Одной из важных задач машинного зрения является детектирование объекта. В общем случае решение найти очень проблематично или почти невозможно, поэтому часто прибегают к вспомогательным возможностям. Например раскрашивают объект в определенный цвет. Это позволяет очень простыми методами подсветить область, в которой находится предполагаемый объект. Так функция
cv2.inRange(src, lowerb, upperb[, dst])
позволяет выделить маску области. Однако резко встает вопрос корректного определения верхней и нижней границы (lowerb и upperb). А в этом как раз и прелесть и сложность пространства HSV. Кодировка цвета в модели HSV расшифровывается так: H — цветовой тон, S — насыщенность, V — яркость. Поэтому для выделения по цвету, достаточно указать диапазон H, а насыщенность и яркость будет сильно варьироваться (из-за разной освещенности, углов скоса объекта и.т.д.) На практике обычно делают примерно так: если H соcтавляющая 80 (зеленый цвет), берут нижнюю границу H=80-10 [70, 50, 50], а верхнюю H=80+10 [90,255,255]. Кажется что вот, все просто, посмотрим HSV цвет в фотошопе или пейнте и установим нужную границу… Но, в отличии от цветовой модели RGB, диапазон значений H в разных программах может задаваться по разному и его необходимо пересчитывать. Чтобы облегчить и на лету определять HSV цвет в OpenCV написал следующий небольшой скрипт:
import cv2 import cv2.cv as cv cap = cv2.VideoCapture(0) #set camera width and height CAM_WIDTH = 640 CAM_HEIGHT = 480 cap.set(cv.CV_CAP_PROP_FRAME_WIDTH, CAM_WIDTH) cap.set(cv.CV_CAP_PROP_FRAME_HEIGHT, CAM_HEIGHT) selected_color = None image_origin = None def onmouse(event, x, y, flags, param): global image_origin, selected_color if flags & cv2.EVENT_FLAG_LBUTTON: #taking squire cur 4x4 and scale it to 1x1 cut = image_origin[y-1:y+2, x-1:x+2] cut = cv2.pyrDown(cut) cut = cv2.pyrDown(cut) selected_color = (int(cut[0][0][0]), int(cut[0][0][1]), int(cut[0][0][2])) #conveting to HSV and printing result selected_color_HSV = cv2.cvtColor(cut, cv2.COLOR_BGR2HSV) print(selected_color_HSV) while(1): # Take each frame _, frame = cap.read() image_origin = frame.copy() #drawing selected colors if selected_color is not None: cv2.circle(frame, (CAM_WIDTH-20,20), 20, selected_color, -1) #show image and set callback cv2.imshow('img', frame) cv2.setMouseCallback('img', onmouse) k = cv2.waitKey(5) & 0xFF if k == 27: break cv2.destroyAllWindows()
В данном пример изображение берется из видео-потока. Идея состоит в том, что после клика по видео изображению, выделяется квадрат 4 на 4, этот квадрат уменьшаем до размера 1 на 1 (усредняем значения цвета) и с помощью функции cv2.cvtColor(img, cv2.COLOR_BGR2HSV) переводим изображение в режим HSV.
Надеюсь этот скрипт поможет вам для работы в приложениях с OpenCV.