2012-06-08 8 views
48

Mam obraz puszki po kawie z pomarańczową pozycją pokrywki, którą chcę znaleźć. Tutaj jest to image.Wybieranie prawidłowych górnych i dolnych granic HSV do wykrywania kolorów za pomocą `cv :: inRange` (OpenCV)

Narzędzie gcolor2 pokazuje HSV w środku pokrywy (22, 59, 100). Pytanie brzmi, jak wybrać granice koloru, a następnie? I próbuje min = (18, 40, 90), i Max = (27, 255, 255), ale posiadają nieoczekiwane result

Oto kod Pythonie

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

Sprawdziłem wartości (22, 59, 100) HSV, i nie wydaje się, aby dopasować dowolny kolor podobny do tych z pokrywa. Ale jako BGR mają sens. W jaki sposób odzyskałeś te wartości? – karlphillip

+0

Oto zrzut ekranu z gcolor2 http://imageshack.us/photo/my-images/23/rgb2hsv.png/. Następnie sprawdziłem numer koloru # FFA069 na http: //www.yafla.com/yaflaColor/ColorRGBHSL.aspx? RGB = & Kolory = ,,,,,,,,, i konwersja jest taka sama. –

+2

Jest to prawdopodobnie spowodowane różnymi zakresami HSV w OpenCV, a mianowicie H: 0 - 180, S: 0 - 255, V: 0 - 255. –

Odpowiedz

101

Zadanie 1: Różne aplikacje używają różnych skal dla HSV. Na przykład gimp używa H = 0-360, S = 0-100 and V = 0-100. Ale OpenCV używa H: 0 - 180, S: 0 - 255, V: 0 - 255. Tutaj mam wartość odcień 22 w gimp. Więc wziąłem połowę tego, 11, i zdefiniowałem dla tego zakres. tj. (5,50,50) - (15,255,255).

Problem 2: A także, OpenCV używa formatu BGR, a nie RGB. Zmień kod, który konwertuje RGB na HSV w następujący sposób:

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

Teraz uruchom. Mam wyjście następująco:

enter image description here

nadzieję, że jest to, czego chciał. Jest kilka fałszywych detekcji, ale są one małe, więc możesz wybrać największy kontur, który jest twoją pokrywką.

EDIT:

Jak powiedział Karl Philip w swoim komentarzu, że byłoby dobrze, aby dodać nowy kod. Ale zmienia się tylko jedna linia. Chciałbym dodać ten sam kod zaimplementowany w nowym module cv2, aby użytkownicy mogli porównać łatwość i elastyczność nowego modułu 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) 

Daje taki sam wynik jak powyżej. Ale kod jest znacznie prostszy.

+0

+1 Doskonały, jeszcze raz. Gdybyś mógł dodać pełny kod źródłowy ze swoimi modyfikacjami, byłby świetny. – karlphillip

+0

Dziękuję. Ale nie sądzę, że tu jest dużo ekscelencji. :) (OK, zrobię to) –

+1

@karlphillip: edytował odpowiedź –

17

Stworzyłem ten prosty program, aby uzyskać kody HSV w czasie rzeczywistym

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, napisałem ten sam kod przy drukowaniu ostatecznych wartości HSV używanych https://github.com/saurabheights/ImageProcessingExperimentScripts/blob/master/AnalyzeHSV/hsvThresholder.py – saurabheights

1

OpenCV zakres HSV jest: H: 0 do 179 S: 0 do 255 V: 0 do 255

On Gimp (lub inna operacja manipulowania zdjęciami) Zakres odcienia od 0 do 360, ponieważ opencv umieszcza informacje o kolorze w jednym bajcie, maksymalna wartość liczbowa w pojedynczym bajcie wynosi 255 dlatego wartości odcienia openCV są równoważne wartościom odcieni z gimp podzielonym przez 2.

Znalazłem podczas próby wykrywania obiektów na podstawie przestrzeni kolorów HSV, że zakres 5 (zakres opencv) był wystarczający do odfiltrowania określonego koloru. Radzę użyć kolorowego podniebienia HSV, aby znaleźć zakres, który najlepiej pasuje do twojej aplikacji.

HSV color palate with color detection in HSV space

2

Ok, znaleźć kolor w HSV przestrzeni jest stary, ale częste pytanie.Zrobiłem hsv-colormap, aby szybko wyszukać specjalny kolor. Tutaj jest on:

enter image description here

Oś x oznacza Hue w [0,180), Y oznacza Saturation oś1 w [0,255], y-oś2 oznacza S = 255, a zachować V = 255.

Aby znaleźć kolor, należy po prostu sprawdzić zakres H i S i ustawić wartość v w zakresie (20, 255).

Aby znaleźć kolor pomarańczowy, wyszukujemy mapę i znajdujemy najlepszy zakres: H :[10, 25], S: [100, 255], and V: [20, 255]. Więc maska ​​jest cv2.inRange(hsv,(10, 100, 20), (25, 255, 255))

Następnie używamy znaleziony zakres szukać pomarańczowy kolor, jest to wynik:

enter image description here


Metoda jest prosta, ale powszechne w użyciu:

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

podobne odpowiedzi:

  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

Powiązane problemy