Как я могу pythonically us opencv найти aa баскетбол в изображении?

Я много работал над домашним проектом, чтобы найти простой баскетбол в изображении. Я пробовал кучу перестановок использования hough.circles и transform и т. Д. В течение последних нескольких недель, но я, похоже, не прихожу нигде близко к изоляции баскетбола с примерами кода и моим собственным мастерингом.

Вот пример фото: мальчик с баскетболом И вот результат после простой версии кода поиска круга, с которой я занимался: поиск окружности

Кто-нибудь знает, где я поступил неправильно и как я могу это исправить?

Вот код, в котором я играю:

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) 

Я согласен с другими плакатами, что использование цвета баскетбола – хороший подход. Вот какой простой код, который делает это:

 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) 

результат:

введите описание изображения здесь

Я предполагаю, что:

  1. Всегда один и только один баскетбол присутствует
  2. Баскетбол – главный оранжевый предмет на сцене

С этими предположениями, если мы найдем что-либо в правильном цвете, мы можем принять его шар и установить ему круг. Таким образом, мы вообще не делаем никакого обнаружения круга.

Как вы можете видеть на верхнем изображении, есть некоторые более мелкие оранжевые элементы (из шорт), которые могут испортить нашу оценку радиуса мяча. В коде используется операция opening ( erosion последующим dilation ), чтобы удалить их. Это хорошо работает для вашего примера изображения. Но для других изображений может быть лучше другой метод: с использованием обнаружения круга или формы контура, размера или если мы имеем дело с видео, мы могли бы отслеживать положение мяча.

Я запускал этот код (только для видео), на случайном коротком баскетбольном видео, и он работал на удивление хорошо (не здорово .. но хорошо).

Несколько мыслей:

  1. Сначала фильтруйте по цвету, чтобы упростить изображение. Если вы ищете специально для оранжевого баскетбола, вы можете устранить множество других цветов. Я бы рекомендовал использовать цветное пространство HSI вместо RGB, но в любом случае вы должны быть в состоянии исключить цвета, которые находятся на некотором расстоянии в цвете 3-х мест от вашего обученного цвета баскетбола.
  2. Попробуйте заменить Sobel или какой-либо другой детектор на основе ядра, который не полагается на ручные параметры. Отобразите изображение края, чтобы увидеть, правильно ли оно отображается.
  3. Разрешить более слабые края. В изображении в оттенках серого контраст между баскетболом и темной майкой игрока не так велик, как разница между белой майкой и черной майкой.
  4. Hough может дать неожиданные результаты, если объект только номинально круговым в поперечном сечении, но на самом деле удлинен или имеет шумные края в реальном изображении. Я обычно пишу свой собственный алгоритм Hough и не касался реализации OpenCV, поэтому я не уверен, какой параметр изменить, но посмотрите, можете ли вы разрешить появление более сумасшедших ребер.
  5. Возможно, устранить гладкую работу. В любом случае, попробуйте сгладить, прежде чем находить края, а не наоборот.
  6. Попробуйте написать свой собственный алгоритм Hough. Хотя реализация quickie может быть не такой гибкой, как реализация OpenCV, за счет загрязнения ваших рук вы можете наткнуться на источник проблемы.