快速而稳健的方式来检测反射球

时间:2017-03-09 21:47:53

标签: c++ opencv image-processing

我的图像中有一个高反光球,看起来像这样:

enter image description here

什么是实时检测球的稳健方法? (5-10 FPS)

我尝试了几种分割算法,但它们无法将球与背景分开,而是将球切成碎片,因为球本身有许多不同的区域。

由于反射特性,简单的圆形霍夫变换不能很好地工作。任何简单的treshhold或形态操作都是如此。

您对处理反光表面有什么建议吗?

1 个答案:

答案 0 :(得分:2)

HoughCircles建议很棒,只要您大致了解球在框架中的移动方式,并因此大致知道您所考虑的最小,最大半径:

import numpy as np
import cv2
import cv2.cv as cv

img = cv2.imread('wcEXm.jpg',0)


#Method 1: Hough Circles
img = cv2.medianBlur(img,5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)

# HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])
circles = cv2.HoughCircles(img,cv.CV_HOUGH_GRADIENT,dp=1,minDist=50,param1=127,param2=30,minRadius=50,maxRadius=150)

circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    # draw the outer circle
    cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
    # draw the center of the circle
    cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)

cv2.imshow('detected circles',cimg)

Hough Circles

另一种选择是使用findContours()。使用正确的选项和过滤位(例如dilate()erode()),您可以从背景中分割球,宽度和高度之间的比例(更接近正方形)将有所帮助。

dilated and eroded threshold

然而,如果你对球的大小不感兴趣,只知道它在哪里,那么可以用一个简洁的小东西来简化这个。 你的球是反光的,甚至开始发现你需要一个光源,因此,即使颜色/环境看起来不同,球也会有一个亮点。假设光源不在画面中,你的反光球可能会成为场景中下一个最亮的东西:

import cv2

img = cv2.imread('wcEXm.jpg',0)

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(img)
cv2.circle(img, maxLoc, 20, (0,192,0),10)

minMaxLoc

就RaspberryPi的性能而言,我建议如下:

  1. 使用Adrian的tutorial on using PiCam with OpenCV in Python
  2. 如果您打算使用minMaxLoc()或其他适用于灰度图像的功能,您可以使用'yuv'色彩空间,只需使用Y(亮度)通道即可节省一些时间而不需要从RGB转换为lumma / grayscale
  3. 使用较小的分辨率(例如320x240或160x120)。如果您需要将球的x,y位置映射到其他位置,则可以将结果缩放回来。
  4. <强>更新 另一件可能有用的事情是Canny edge detection,因为场景很简单,球会突出:

    edges = cv2.Canny(img,100,200)
    

    Canny Edge Detection

    Canny Edge Contours