2014-04-04 14 views
6

Tôi đã làm việc trong một dự án thú cưng một chút về cách tìm một bóng rổ đơn giản trong một hình ảnh. Tôi đã thử một loạt hoán vị của việc sử dụng hough.circles và biến đổi, vv trong vài tuần qua nhưng tôi không thể dường như đến bất cứ nơi nào gần cô lập bóng rổ với các ví dụ mã và tinkering của riêng tôi.Làm thế nào tôi có thể pythonically chúng tôi opencv để tìm một bóng rổ trong một hình ảnh?

Dưới đây là một ví dụ ảnh: boy with a basketball Và đây là kết quả sau khi một phiên bản đơn giản của vòng tròn tìm mã tôi đã mày mò với: houghcircle transform circle finding

Bất cứ ai có bất cứ ý tưởng nơi tôi đã đi sai và làm thế nào Tôi có thể làm đúng không?

Dưới đây là đoạn code tôi đang loay hoay với:

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

Thay vì tải tệp dưới dạng ảnh thang độ xám, cách tải tệp dưới dạng hình ảnh màu và thực hiện một số tiền xử lý để nhấn mạnh màu cam của bóng trước khi làm phẳng hình ảnh và chuyển nó vào bộ lọc Canny? –

Trả lời

3

Tôi đồng ý với các áp phích khác, sử dụng màu của bóng rổ là một cách tiếp cận tốt. Dưới đây là một số mã đơn giản nào đó:

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) 

kết quả:

enter image description here

tôi cho rằng:

  1. Luôn một và chỉ một bóng rổ có mặt
  2. Các bóng rổ là mục màu cam chính trong cảnh

Với những giả định này, nếu chúng ta tìm thấy bất kỳ màu nào chính xác, chúng ta có thể giả sử quả bóng của nó và phù hợp với một vòng tròn với nó. Bằng cách này, chúng tôi không thực hiện bất kỳ phát hiện vòng kết nối nào cả.

Như bạn có thể thấy trong hình trên, có một số yếu tố orangey nhỏ hơn (từ quần short) sẽ làm hỏng ước tính bán kính bóng của chúng tôi. Mã sử ​​dụng hoạt động opening (erosion, sau đó là dilation) để xóa các mã này. Điều này hoạt động tốt cho hình ảnh ví dụ của bạn. Nhưng đối với các hình ảnh khác, một phương pháp khác có thể tốt hơn: sử dụng phát hiện vòng tròn quá, hoặc hình dạng đường viền, kích thước hoặc nếu chúng ta đang xử lý video, chúng tôi có thể theo dõi vị trí bóng.

Tôi đã chạy mã này (chỉ được sửa đổi cho video) trên một video bóng rổ ngắn ngẫu nhiên, và nó hoạt động đáng ngạc nhiên ok (không tuyệt vời .. nhưng ok).

+0

cảm ơn bạn đã dành thời gian để chơi với điều này và chia sẻ một số mã để thử nghiệm và giải thích logic đằng sau giải quyết nó, đó là một cách cơ bản tuyệt vời để giải quyết vấn đề trước khi mã hóa. –

1

Một vài suy nghĩ:

  1. Lọc theo màu đầu tiên để đơn giản hóa hình ảnh. Nếu bạn đang tìm kiếm đặc biệt cho một bóng rổ màu da cam, bạn có thể loại bỏ rất nhiều màu sắc khác. Tôi khuyên bạn nên sử dụng không gian màu HSI thay vì RGB, nhưng trong mọi trường hợp, bạn sẽ có thể loại trừ các màu có khoảng cách màu trong không gian 3 màu từ màu bóng rổ được đào tạo của bạn.
  2. Hãy thử thay thế Sobel hoặc một bộ dò cạnh dựa trên hạt nhân khác mà không dựa vào thông số thủ công. Hiển thị hình ảnh cạnh để xem hình ảnh có "đúng" cho bạn hay không.
  3. Cho phép các cạnh yếu hơn. Trong hình ảnh thang độ xám, độ tương phản giữa bóng rổ và áo bóng tối của người chơi không lớn bằng sự khác biệt giữa áo lót màu trắng và áo đen.
  4. Hough có thể mang lại kết quả không mong muốn nếu đối tượng chỉ là hình tròn danh nghĩa ở mặt cắt ngang, nhưng thực sự bị thuôn dài hoặc có các cạnh nhiễu trong hình ảnh thực tế. Tôi thường viết thuật toán Hough của riêng mình và chưa chạm vào triển khai OpenCV, vì vậy tôi không chắc chắn thông số nào sẽ thay đổi, nhưng hãy xem liệu bạn có thể cho phép các cạnh mờ hơn không.
  5. Có thể loại bỏ hoạt động trơn tru. Trong mọi trường hợp, hãy thử trơn tru trước khi tìm các cạnh thay vì theo cách khác.
  6. Cố gắng viết thuật toán Hough thô của riêng bạn. Mặc dù việc triển khai quickie có thể không linh hoạt như việc triển khai OpenCV, bằng cách dơ tay bạn, bạn có thể vấp ngã nguồn gốc của vấn đề.
Các vấn đề liên quan