使用OpenCV检测银色和反射球

fec*_*avy 3 python opencv hough-transform

我试图通过OpenCV检测反映环境的银球: 一个银球 有了黑球,我通过检测圆圈成功地做到了:

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

gray = cv2.GaussianBlur(gray,(5,5),0);
gray = cv2.medianBlur(gray,5)

gray = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,3.5)

kernel = np.ones((3,3),np.uint8)

gray = cv2.erode(gray,kernel,iterations = 1)

gray = cv2.dilate(gray,kernel,iterations = 1)

circles = cv2.HoughCircles(gray, cv.CV_HOUGH_GRADIENT, 1, 260, \
                    param1=30, param2=65, minRadius=0, maxRadius=0)
Run Code Online (Sandbox Code Playgroud)

但是当使用带银球的程序时,我们没有得到任何结果.

当观察程序计算的边缘时,球的边缘非常清晰.但是守则并没有承认任何球.

银球的边缘

如何提高银球的检测率?我想到了两种方法: - 改善边缘计算 - 使圆检测接受边缘不清晰的图像这可能吗?这样做的最佳方法是什么?

非常感谢帮助.

Tim*_*imo 8

你必须调整你的参数.HoughCircles功能在检测圆圈方面做得很好(即使有间隙).请注意,HoughCircles使用canny边缘检测执行内部二值化.因此,您不必进行阈值处理.

鉴于上面的图片,代码

import cv2
from matplotlib import pyplot as plt
import numpy as np

PATH = 'path/to/the/image.jpg'    

img = cv2.imread(PATH, cv2.IMREAD_GRAYSCALE)
plt.imshow(img, cmap='gray')
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20, param1=130, param2=30, minRadius=0, maxRadius=0)
if circles is not None:
    for x, y, r in circles[0]:
        c = plt.Circle((x, y), r, fill=False, lw=3, ec='C1')
        plt.gca().add_patch(c)
plt.gcf().set_size_inches((12, 8))
plt.show()
Run Code Online (Sandbox Code Playgroud)

产生结果

不同的参数意味着什么?

函数签名定义为

cv.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])
Run Code Online (Sandbox Code Playgroud)

图像圆圈是自解释的,将被跳过.

方法

指定内部使用的霍夫算法的变体.如文档中所述,仅HOUGH_GRADIENT支持atm.该方法利用21HT(p.2,THE 2-1 HOUGH TRANSFORM)算法.这种变体的主要优点在于减少了内存使用量.使用霍夫变换检测圆的标准方法需要在3D霍夫空间(x,y和半径)中进行搜索.但是,使用21HT时,您的霍夫空间将减少到仅2维,这会大大降低内存消耗.

DP

DP参数设置反向累加器分辨率.这里可以找到一个很好的解释.请注意,此解释使用标准的霍夫变换作为示例.但是21HT的效果是一样的.21HT的累加器与标准HT略有不同.

minDist

只需指定圆心之间的最小距离即可.在上面的代码示例中,它设置为20,这意味着两个检测到的圆的中心必须彼此相距至少 20个像素.我不确定opencv是如何过滤掉圆圈的,但扫描源代码看起来像是较低匹配的圆圈会被抛弃.

参数1

指定传递给Canny Edge算法的阈值.基本上它被称为cv2.Canny(image, param1 / 2, param1).

参数2

本段应该由熟悉opencv源代码的人验证. param2指定累加器阈值.此值决定圆圈的完整程度,以便计为有效圆圈.我不确定参数是以哪个单位给出的.但是(再次扫描源代码)看起来它是一个绝对的投票门槛(意味着它直接受到不同半径的影响).下图显示了不同的圆圈(或可以识别为圆圈的内容).向右移动越远,阈值必须越低,以便检测到该圆圈.

累加器阈值

minRadius和maxRadius

只需限制半径范围[minRadius,maxRadius]中的圆搜索.如果您可以近似(或知道)要搜索的圆的大小,这很有用(并且可以提高性能).