Выбор правильной верхней и нижней границ ВПГ для определения цвета с помощью `cv::inRange` (OpenCV)
У меня есть изображение кофейной банки с оранжевой крышкой, положение которой я хочу найти. Вот ,
Утилита gcolor2 показывает HSV в центре крышки (22, 59, 100). Вопрос в том, как выбрать пределы цвета? Я пробовал min = (18, 40, 90) и max = (27, 255, 255), но получил неожиданное
Вот код 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()
10 ответов
Проблема 1: Различные приложения используют разные шкалы для HSV. Например, GIMP использует H = 0-360, S = 0-100 and V = 0-100
, Но OpenCV использует H: 0 - 180, 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)
Теперь запустите это. Я получил вывод следующим образом:
Надеюсь, это то, что вы хотели. Есть несколько ложных обнаружений, но они маленькие, поэтому вы можете выбрать самый большой контур, которым является ваша крышка.
РЕДАКТИРОВАТЬ:
Как сказал в своем комментарии Карл Филипп, было бы неплохо добавить новый код. Но есть изменение только одной строки. Итак, я хотел бы добавить тот же код, реализованный в новом 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)
Это дает тот же результат, что и выше. Но код намного проще.
Ок, найди цвет в HSV
Пространство это старый, но общий вопрос. я сделал hsv-colormap
быстро искать специальный цвет. Вот:
Ось X представляет Hue
в [0,180), ось Y представляет 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) )
Затем мы используем найденный диапазон для поиска оранжевого цвета, это результат:
Метод прост, но распространен в использовании:
#!/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()
Подобные ответы:
Вот простой скрипт порогового значения цвета HSV для определения нижнего / верхнего цветовых диапазонов с помощью полос прокрутки для любого изображения на диске. Просто измените путь к изображению вcv2.imread()
ht tps:https://stackru.com/images/fd6e0780c7bbf930971ecafdda6f052e041e8ac0.png
import cv2
import numpy as np
def nothing(x):
pass
# Load image
image = cv2.imread('1.jpg')
# Create a window
cv2.namedWindow('image')
# Create trackbars for color change
# Hue is from 0-179 for Opencv
cv2.createTrackbar('HMin', 'image', 0, 179, nothing)
cv2.createTrackbar('SMin', 'image', 0, 255, nothing)
cv2.createTrackbar('VMin', 'image', 0, 255, nothing)
cv2.createTrackbar('HMax', 'image', 0, 179, nothing)
cv2.createTrackbar('SMax', 'image', 0, 255, nothing)
cv2.createTrackbar('VMax', 'image', 0, 255, nothing)
# Set default value for Max HSV trackbars
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)
# Initialize HSV min/max values
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0
while(1):
# Get current positions of all trackbars
hMin = cv2.getTrackbarPos('HMin', 'image')
sMin = cv2.getTrackbarPos('SMin', 'image')
vMin = cv2.getTrackbarPos('VMin', 'image')
hMax = cv2.getTrackbarPos('HMax', 'image')
sMax = cv2.getTrackbarPos('SMax', 'image')
vMax = cv2.getTrackbarPos('VMax', 'image')
# Set minimum and maximum HSV values to display
lower = np.array([hMin, sMin, vMin])
upper = np.array([hMax, sMax, vMax])
# Convert to HSV format and color threshold
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower, upper)
result = cv2.bitwise_and(image, image, mask=mask)
# Print if there is a change in HSV value
if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
phMin = hMin
psMin = sMin
pvMin = vMin
phMax = hMax
psMax = sMax
pvMax = vMax
# Display result image
cv2.imshow('image', result)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
Я создал эту простую программу, чтобы получить коды 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's 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()
Для этой цели я создал простой (более правильный) инструмент, используя opencv-python. Подумал, что это будет полезно для кого-то, кто наткнулся здесь, как я в начале этого года.
Поскольку сам инструмент написан с использованием python cv2, он гарантированно будет использовать тот же диапазон. Также есть ползунок для
erode
и
dilate
так как обычно проект компьютерного зрения нуждается в этих двух функциях
Вы можете клонировать инструмент отсюда https://github.com/hariangr/HsvRangeTool .
Диапазон OpenCV HSV: H: от 0 до 179 S: от 0 до 255 В: от 0 до 255
На цветовой гамме Gimp (или другой фотомонтажной программе) диапазон оттенков от 0 до 360, поскольку opencv помещает информацию о цвете в один байт, максимальное числовое значение в одном байте равно 255, поэтому значения оттенков openCV эквивалентны значениям оттенков от gimp, деленным на 2,
При обнаружении объекта на основе цветового пространства HSV я обнаружил, что диапазон 5 (диапазон opencv) достаточен для фильтрации определенного цвета. Я бы посоветовал вам использовать цветовой вкус HSV, чтобы определить диапазон, который лучше всего подходит для вашего применения.
Чтобы найти значение HSV для Green, попробуйте следующие команды в терминале Python
green = np.uint8([[[0,255,0 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print hsv_green
[[[ 60 255 255]]]
Вы можете использовать GIMP или PaintDotNet, чтобы получить точный диапазон HSV. Но проблема в том, что диапазон HSV в графическом программном обеспечении отличается от того же диапазона в OpenCV, поэтому вам нужна функция, чтобы исправить это за вас. Для этого вы можете использовать следующую функцию.
def fixHSVRange(h, s, v):
# Normal H,S,V: (0-360,0-100%,0-100%)
# OpenCV H,S,V: (0-180,0-255 ,0-255)
return (180 * h / 360, 255 * s / 100, 255 * v / 100)
Например, вы можете использовать это примерно так:
im=cv2.imread("image.jpg",1)
im_hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
color1 = fixHSVRange(h=10, s=20, v=0)
color2 = fixHSVRange(h=30, s=70, v=100)
mask = cv2.inRange(im_hsv, color1, color2)
cv2.imwrite("mask.jpg",mask)
Я также изо всех сил пытался найти, какие значения HSV выбрать (чтобы в конечном итоге выбрать регионы). Немного погуглив, я создал этот небольшой скрипт для проверки значений HSV на моем изображении.
Он открывает ваше изображение (отрегулируйте путь в
import cv2
def on_mouse(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
print("HSV values at ({}, {}): {}".format(x, y, hsv[y, x]))
img = cv2.imread(‘\path\to\your\image\piccie.png’)
cv2.namedWindow("image")
cv2.setMouseCallback("image", on_mouse)
while True:
cv2.imshow("image", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
Большинство методов, упомянутых выше, обычно требуют некоторого знания цветового диапазона для определенного цвета с последующим методом проб и ошибок, чтобы получить правильный диапазон. Но официальная документация OpenCV предлагает лучший способ найти нижнюю и верхнюю границы HSV даже для цветов, которые не очень распространены.
Как найти значения HSV для отслеживания?
Это распространенный вопрос, который можно найти на stackoverflow.com. Это очень просто, и вы можете использовать ту же функцию cv.cvtColor(). Вместо передачи изображения вы просто передаете нужные значения BGR. Например, чтобы найти значение HSV для Green, попробуйте выполнить следующие команды в терминале Python:
Вы можете найти точные значения пикселей (BGR) требуемого объекта и использовать их, например, зеленый (0, 255, 0)
green = np.uint8([[[0,255,0 ]]])
hsv_green = cv.cvtColor(green,cv.COLOR_BGR2HSV)
print(hsv_green)
[[[60 255 255]]]
Теперь вы берете [H-10, 100,100] и [H+10, 255, 255] в качестве нижней и верхней границ соответственно. Помимо этого метода, вы можете использовать любые инструменты редактирования изображений, такие как GIMP или любые онлайн-конвертеры, чтобы найти эти значения, но не забудьте настроить диапазоны HSV.
Источник:
Цветовые пространства OpenCV и отслеживание объектов
GIMP — инструмент для управления изображениями