detector - Elegir los límites HSV superior e inferior correctos para la detección de color con`cv:: inRange`(OpenCV)
opencv python change color space (4)
Creé este sencillo programa para obtener códigos HSV en tiempo real
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()
Tengo una imagen de una lata de café con una posición de tapa naranja que quiero encontrar. Aquí es .
La utilidad gcolor2 muestra que el HSV en el centro de la tapa es (22, 59, 100). La pregunta es cómo elegir los límites del color, entonces? Intenté min = (18, 40, 90) y max = (27, 255, 255), pero tengo inesperado
Aquí está el código de 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()
El rango OpenCV HSV es: H: 0 a 179 S: 0 a 255 V: 0 a 255
En Gimp (u otro sw manipulación de fotos) Hue rango de 0 a 360, ya que opencv pone información de color en un solo byte, el valor máximo en un solo byte es 255, por lo tanto, los valores de Hue de openCV son equivalentes a los valores Hue de gimp dividido por 2 .
Al intentar hacer la detección de objetos basada en el espacio de color HSV, encontré que un rango de 5 (rango de OpenCV) era suficiente para filtrar un color específico. Te aconsejo que uses un paladar de color HSV para descubrir el rango que mejor funciona para tu aplicación.
Ok, encontrar color en el espacio HSV
es una pregunta antigua pero común. Hice un hsv-colormap
para buscar rápidamente un color especial. Aquí está:
El eje x representa Hue
en [0,180), el eje y1 representa Saturation
en [0,255], el eje y2 representa S = 255
, mientras que mantenga V = 255
.
Para encontrar un color, generalmente solo busca el rango de H
y S
, y establece v en el rango (20, 255).
Para encontrar el color naranja, buscamos el mapa y buscamos el mejor rango: H :[10, 25], S: [100, 255], and V: [20, 255]
. Entonces la máscara es cv2.inRange(hsv,(10, 100, 20), (25, 255, 255) )
Luego usamos el rango encontrado para buscar el color naranja, este es el resultado:
El método es simple pero común de usar:
#!/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()
Respuestas similares:
Problema 1: Diferentes aplicaciones usan diferentes escalas para HSV. Por ejemplo, gimp usa H = 0-360, S = 0-100 and V = 0-100
. Pero OpenCV usa H: 0 - 180, S: 0 - 255, V: 0 - 255
. Aquí obtuve un valor de tono de 22 en gimp. Así que tomé la mitad, 11, y el rango definido para eso. es decir (5,50,50) - (15,255,255)
.
Problema 2: Y también, OpenCV usa formato BGR, no RGB. Así que cambie su código que convierte RGB a HSV de la siguiente manera:
cv.CvtColor(frame, frameHSV, cv.CV_BGR2HSV)
Ahora ejecútalo. Obtuve un resultado de la siguiente manera:
Espero que sea eso lo que querías. Hay algunas detecciones falsas, pero son pequeñas, por lo que puedes elegir el contorno más grande que sea tu tapa.
EDITAR:
Como dijo Karl Philip en su comentario, sería bueno agregar un nuevo código. Pero hay cambio de una sola línea. Entonces, me gustaría agregar el mismo código implementado en el nuevo módulo cv2
, para que los usuarios puedan comparar la facilidad y flexibilidad del nuevo módulo 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)
Da el mismo resultado que arriba. Pero el código es mucho más simple.