2012-06-08 23 views
48

Tengo una imagen de una lata de café con una posición de tapa naranja que quiero encontrar. Aquí está, image.Elegir los límites HSV superior e inferior correctos para detección de color con`cv :: inRange` (OpenCV)

La utilidad gcolor2 muestra HSV en el centro de la tapa (22, 59, 100). La pregunta es cómo elegir los límites del color, entonces? Probé min = (18, 40, 90) y max = (27, 255, 255), pero han conseguido inesperado result

Aquí está el código 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() 
+0

I comprueban los valores (22, 59, 100) como HSV, y que no parecen coincidir con el de cualquier color similar a los de la tapa. Pero como BGR, tienen sentido. ¿Cómo recuperaste estos valores? – karlphillip

+0

Aquí está la captura de pantalla con gcolor2 http://imageshack.us/photo/my-images/23/rgb2hsv.png/. Luego revisé el número de color # FFA069 en http: //www.yafla.com/yaflaColor/ColorRGBHSL.aspx? RGB = & Colors = ,,,,,,,,, y la conversión es la misma. –

+2

Esto es probablemente debido a diferentes rangos HSV en OpenCV, es decir, H: 0 - 180, S: 0 - 255, V: 0 - 255. –

Respuesta

101

Problema 1: Different las 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 utiliza el 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útelo. Tengo una salida de la siguiente manera:

enter image description here

esperanza de que es lo deseado. Hay algunas detecciones falsas, pero son pequeñas, por lo que puedes elegir el contorno más grande que sea tu tapa.

EDIT:

Como Karl Philip dijo en su comentario, sería bueno agregar nuevo código. Pero hay cambio de solo una línea. Por lo tanto, 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 el anterior. Pero el código es mucho más simple.

+0

+1 Excelente, una vez más. Si pudieras agregar el código fuente completo con tus modificaciones, sería increíble. – karlphillip

+0

Gracias. Pero no creo que haya mucha excelencia aquí. :) (OK, lo haré) –

+1

@karlphillip: editó la respuesta –

17

creé este programa simple para obtener los códigos de 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() 
+3

LOL, escribí el mismo código para imprimir los valores finales de HSV utilizados https://github.com/saurabheights/ImageProcessingExperimentScripts/blob/master/AnalyzeHSV/hsvThresholder.py – saurabheights

1

OpenCV gama 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.

Encontré al intentar hacer la detección de objetos basada en el espacio de color HSV que un rango de 5 (rango de OpenCV) fue 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.

HSV color palate with color detection in HSV space

2

Ok, encontrar el color en HSV espacio es un viejo pero es común que se trate.Hice un hsv-colormap para buscar rápidamente un color especial. Aquí está:

enter image description here

El eje x representa Hue en [0180), la y-eje1 representa Saturation en [0255], la y-axis2 representa S = 255, mientras que mantener V = 255.

Para encontrar un color, generalmente solo busque el rango de H y S, y configure v en el rango (20, 255).

Para encontrar el color naranja, buscamos el mapa y buscamos la mejor gama: H :[10, 25], S: [100, 255], and V: [20, 255]. Por lo que 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:

enter image description here


El método es simple pero común el uso de:

#!/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:

  1. How to define a threshold value to detect only green colour objects in an image :Opencv

  2. Choosing correct HSV values for OpenCV thresholding with InRangeS

Cuestiones relacionadas