2012-06-08 8 views
48

Ho un'immagine di una lattina di caffè con una posizione del coperchio arancione di cui voglio trovare. Ecco image.Scelta dei limiti HSV superiore e inferiore corretti per il rilevamento del colore con `cv :: inRange` (OpenCV)

L'utilità gcolor2 mostra HSV al centro del coperchio (22, 59, 100). La domanda è come scegliere i limiti del colore allora? Ho provato min = (18, 40, 90) e max = (27, 255, 255), ma hanno ottenuto inaspettata result

Ecco il codice 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

ho controllato i valori (22, 59, 100) come HSV, e non sembrano corrispondere al qualsiasi colore simile a quelle di il coperchio. Ma come BGR, hanno senso. Come hai recuperato questi valori? – karlphillip

+0

Ecco uno screenshot con gcolor2 http://imageshack.us/photo/my-images/23/rgb2hsv.png/. Ho quindi controllato il numero di colore # FFA069 su http: //www.yafla.com/yaflaColor/ColorRGBHSL.aspx? RGB = & Colors = ,,,,,,,,, e la conversione è la stessa. –

+2

Ciò è probabilmente dovuto a diversi intervalli HSV in OpenCV, cioè H: 0 - 180, S: 0 - 255, V: 0 - 255. –

risposta

101

Problema 1: Different le applicazioni utilizzano diverse scale per HSV. Ad esempio, gimp utilizza H = 0-360, S = 0-100 and V = 0-100. Ma OpenCV utilizza H: 0 - 180, S: 0 - 255, V: 0 - 255. Qui ho un valore di tonalità di 22 in GIMP. Quindi ne ho preso la metà, l'11, e ho definito il range per quello. cioè (5,50,50) - (15,255,255).

Problema 2: E inoltre, OpenCV utilizza il formato BGR, non RGB. Quindi modificare il codice che converte RGB in HSV come segue:

cv.CvtColor(frame, frameHSV, cv.CV_BGR2HSV) 

Ora eseguirlo. Ho ottenuto un output come segue:

enter image description here

speranza che è quello che si voleva. Ci sono dei falsi rilevamenti, ma sono piccoli, quindi puoi scegliere il contorno più grande che è il tuo coperchio.

EDIT:

Come Karl Philip ha detto nel suo commento, sarebbe bene aggiungere nuovo codice. Ma c'è il cambiamento di una sola linea. Quindi, vorrei aggiungere lo stesso codice implementato nel nuovo modulo cv2, in modo che gli utenti possano confrontare la facilità e la flessibilità del nuovo modulo 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) 

Dà lo stesso risultato di cui sopra. Ma il codice è molto più semplice.

+0

+1 Eccellente, ancora una volta. Se potessi aggiungere il codice sorgente completo con le tue modifiche sarebbe fantastico. – karlphillip

+0

Grazie. Ma non credo che qui ci sia molta eccellenza :) (OK, lo farò) –

+1

@karlphillip: modificato la risposta –

17

Ho creato questo semplice programma per ottenere i codici di HSV in tempo reale

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, avevo scritto lo stesso codice con la stampa dei valori HSV finali utilizzati https://github.com/saurabheights/ImageProcessingExperimentScripts/blob/master/AnalyzeHSV/hsvThresholder.py – saurabheights

1

OpenCV gamma HSV è: H: da 0 a 179 S: 0 a 255 V: da 0 a 255

On Gimp (o altri metodi di manipolazione delle foto) Intervallo di tonalità da 0 a 360, poiché opencv inserisce le informazioni sul colore in un singolo byte, il valore numerico massimo in un singolo byte è 255 quindi i valori di openCV Hue sono equivalenti ai valori di tonalità da gimp diviso per 2.

L'ho trovato quando ho provato a eseguire il rilevamento di oggetti in base allo spazio colore HSV che un intervallo di 5 (intervallo opencv) era sufficiente per filtrare un colore specifico. Ti consiglierei di usare un palato di colori HSV per capire la gamma che funziona meglio per la tua applicazione.

HSV color palate with color detection in HSV space

2

Ok, trovare il colore in HSV spazio è un vecchio ma comune domanda.Ho fatto un hsv-colormap per cercare velocemente un colore speciale. Qui è:

enter image description here

L'asse x rappresenta Hue in [0,180), il y-axis1 rappresenta Saturation in [0255], y-axis2 rappresenta S = 255, mentre conservazione V = 255.

Per trovare un colore, in genere è sufficiente cercare l'intervallo di H e S e impostare v nell'intervallo (20, 255).

Per trovare il colore arancione, cerchiamo la mappa e troviamo la migliore gamma: H :[10, 25], S: [100, 255], and V: [20, 255]. Quindi la maschera è cv2.inRange(hsv,(10, 100, 20), (25, 255, 255))

Poi usiamo la gamma trovato a cercare il colore arancione, questo è il risultato:

enter image description here


Il metodo è semplice, ma comune l'uso:

#!/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() 

risposte simili:

  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

Problemi correlati