2014-04-04 30 views
6

Pracowałem nad projektem dla zwierząt domowych, aby dowiedzieć się, jak znaleźć prostą koszykówkę na obrazie. Próbowałem wielu permutacji używania hough.circles i transform, itp. Przez ostatnie kilka tygodni, ale nie mogę wydawać się zbliżać do izolowania koszykówki z przykładami kodu i własnymi majsterkowaniem.Jak mogę pythonically nas opencv znaleźć koszykówkę w obrazie?

Oto przykład fot boy with a basketball A oto wynik po prostej wersji kręgu znalezienie kodu Byłem majstrować przy: houghcircle transform circle finding

ktoś ma jakiś pomysł, gdzie poszły źle i jak Mogę to naprawić?

Oto kod mam błahy z:

import cv2 
import cv2.cv as cv # here 
import numpy as np 

def draw_circles(storage, output): 
    circles = np.asarray(storage) 
    for circle in circles: 
     Radius, x, y = int(circle[0][3]), int(circle[0][0]), int(circle[0][4]) 
     cv.Circle(output, (x, y), 1, cv.CV_RGB(0, 255, 0), -1, 8, 0) 
     cv.Circle(output, (x, y), Radius, cv.CV_RGB(255, 0, 0), 3, 8, 0) 

orig = cv.LoadImage('basket.jpg') 
processed = cv.LoadImage('basket.jpg',cv.CV_LOAD_IMAGE_GRAYSCALE) 
storage = cv.CreateMat(orig.width, 1, cv.CV_32FC3) 
#use canny, as HoughCircles seems to prefer ring like circles to filled ones. 
cv.Canny(processed, processed, 5, 70, 3) 
#smooth to reduce noise a bit more 
cv.Smooth(processed, processed, cv.CV_GAUSSIAN, 7, 7) 

cv.HoughCircles(processed, storage, cv.CV_HOUGH_GRADIENT, 2, 32.0, 30, 550) 
draw_circles(storage, orig) 

cv.imwrite('found_basketball.jpg',orig) 
+1

Zamiast ładować plik jako obraz w skali szarości, a może załadować go jako obraz kolorowy i wykonać pewne wstępne przetwarzanie w celu podkreślenia pomarańczowego koloru kuli przed spłaszczeniem obrazu i przekazaniem go do filtra Canny? –

Odpowiedz

3

Zgadzam się z innymi plakatami, że używanie koloru koszykówki jest dobrym podejściem. Oto prosty kod, który to robi:

import cv2 
import numpy as np 

im = cv2.imread('../media/basketball.jpg') 

# convert to HSV space 
im_hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV) 
# take only the orange, highly saturated, and bright parts 
im_hsv = cv2.inRange(im_hsv, (7,180,180), (11,255,255)) 

# To show the detected orange parts: 
im_orange = im.copy() 
im_orange[im_hsv==0] = 0 
# cv2.imshow('im_orange',im_orange) 

# Perform opening to remove smaller elements 
element = np.ones((5,5)).astype(np.uint8) 
im_hsv = cv2.erode(im_hsv, element) 
im_hsv = cv2.dilate(im_hsv, element) 

points = np.dstack(np.where(im_hsv>0)).astype(np.float32) 
# fit a bounding circle to the orange points 
center, radius = cv2.minEnclosingCircle(points) 
# draw this circle 
cv2.circle(im, (int(center[1]), int(center[0])), int(radius), (255,0,0), thickness=3) 

out = np.vstack([im_orange,im]) 
cv2.imwrite('out.png',out) 

wynik:

enter image description here

Zakładam, że:

  1. zawsze jeden i tylko jeden koszykówka jest obecny
  2. koszykówki jest głównym pomarańczowym elementem sceny

Przy tych założeniach, jeśli znajdziemy cokolwiek odpowiedniego koloru, możemy założyć piłkę i dopasować do niej okrąg. W ten sposób w ogóle nie wykrywamy kółka.

Jak widać na górnym obrazku, istnieją mniejsze pomarańczowe elementy (spod szortów), które mogłyby zepsuć oszacowanie promienia kuli. Kod używa operacji opening (erosion, a następnie dilation), aby je usunąć. Działa to dobrze na przykładowym obrazie. Ale w przypadku innych obrazów inna metoda może być lepsza: za pomocą wykrywania okręgu, kształtu konturu, rozmiaru lub jeśli mamy do czynienia z wideo, możemy śledzić pozycję kulki.

Uruchomiłem ten kod (tylko zmodyfikowany dla wideo) na losowo krótkim wideo koszykówki, i zadziałało zaskakująco dobrze (nie wspaniale .. ale ok).

+0

dziękuję za poświęcenie czasu na zabawę i udostępnienie kodu do eksperymentowania i wyjaśnienia logiki stojącej za tym problemem, to świetny podstawowy sposób na rozwiązanie problemu przed kodowaniem. –

1

Kilka myśli:

  1. Filtr kolorem pierwszy uproszczenie obrazu. Jeśli szukasz specjalnie pomarańczowej koszykówki, możesz wyeliminować wiele innych kolorów. Zalecam używanie przestrzeni kolorów HSI zamiast RGB, ale w każdym przypadku powinieneś być w stanie wykluczyć kolory w odległości trzech kolorów od wyszkolonego koloru koszykówki.
  2. Spróbuj zastąpić Sobel lub inny detektor krawędzi oparty na jądrze, który nie opiera się na parametrach ręcznych. Wyświetl obraz krawędzi, aby zobaczyć, czy wygląda "dobrze" dla Ciebie.
  3. Zezwalaj na słabsze krawędzie. Na obrazie w skali szarości kontrast między koszykówką a ciemną koszulką gracza nie jest tak duży jak różnica między białym podkoszulkiem a czarną koszulką.
  4. Hough może przynieść nieoczekiwane rezultaty, jeśli obiekt ma tylko przekrój poprzeczny w kształcie nominalnym, ale jest rzeczywiście wydłużony lub ma zaszumione krawędzie w rzeczywistym obrazie. Zwykle piszę własny algorytm Hough i nie dotknąłem implementacji OpenCV, więc nie jestem pewien, jaki parametr zmienić, ale zobacz, czy możesz pozwolić na bardziej rozmyte krawędzie.
  5. Może wyeliminować płynną pracę. W każdym razie spróbuj gładko przed znalezieniem krawędzi, a nie odwrotnie.
  6. Spróbuj napisać własny, szorstki algorytm Hough'a. Mimo że implementacja szybkiego numerek może nie być tak elastyczna jak implementacja OpenCV, przez zabrudzenie rąk możesz natknąć się na źródło problemu.