我怎么能诡异地使用opencv在图像中找到一个篮球?

时间:2014-04-04 18:58:33

标签: python opencv image-processing numpy hough-transform

我一直在研究一个关于如何在图像中找到简单篮球的宠物项目。在过去的几周里,我尝试过使用hough.circles和变换等一系列的排列,但我似乎无法接近将代码示例和我自己的修补程序隔离开来。

以下是一张示例照片: boy with a basketball 这是一个简单版本的圆形查找代码之后的结果我一直在修补: houghcircle transform circle finding

任何人都知道我哪里出错了,我怎么能把它搞定?

以下是我正在摆弄的代码:

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)

2 个答案:

答案 0 :(得分:3)

我同意其他海报,使用篮球的颜色是一个很好的方法。这是一些简单的代码:

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)

结果:

enter image description here

我认为:

  1. 总是只有一个篮球存在
  2. 篮球是场景中的主要橙色项目
  3. 根据这些假设,如果我们发现任何正确的颜色,我们可以假设它的球并且适合它。这样我们就不会进行任何圆检测。

    正如您在上图所示,有一些较小的橙色元素(来自短裤)会弄乱我们的球半径估计值。该代码使用opening操作(erosion后跟dilation)来删除这些操作。这适用于您的示例图像。但对于其他图像,不同的方法可能更好:使用圆形检测,或轮廓形状,大小,或者如果我们正在处理视频,我们可以跟踪球的位置。

    我在一个随机的短篮球视频上运行了这段代码(仅针对视频进行了修改),它的效果非常好(不太好......但还可以。)

答案 1 :(得分:1)

一些想法:

  1. 首先按颜色过滤以简化图像。如果您正专心寻找橙色篮球,那么您可以消除许多其他颜色。我建议使用HSI色彩空间而不是RGB,但无论如何,你应该能够从训练有素的篮球颜色中排除颜色3空间距离的颜色。
  2. 尝试替换Sobel或其他一些不依赖于手动参数的基于内核的边缘检测器。显示边缘图像以查看其外观"右边"给你。
  3. 允许较弱的边缘。在灰度图像中,篮球和运动员的深色球衣之间的对比不如白色汗衫和黑色运动衫之间的差异。
  4. 如果物体的横截面仅为标称圆形,但实际图像中实际上是细长的或具有噪声边缘,则可能会产生意外结果。我通常编写自己的Hough算法并且没有触及OpenCV实现,因此我不确定要更改哪个参数,但看看是否可以允许更模糊的边缘。
  5. 也许消除了顺利的操作。在任何情况下,在找到边缘之前尝试平滑,而不是相反。
  6. 尝试编写自己的粗糙Hough算法。虽然快速实现可能不如OpenCV实现那么灵活,但是通过亲自动手,您可能会遇到问题的根源。