python - 用OpenCV检测银球和反光球

标签 python opencv hough-transform

我正在尝试使用 OpenCV 检测反射(reflect)环境的银球: a silver ball

用黑球,我通过检测圆圈成功做到了:

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)

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

查看程序计算出的边缘时,球的边缘非常锋利。但是代码不识别任何球。

edges of a silver ball

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

非常感谢您的帮助。

最佳答案

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

根据上面的图片,代码

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()

产生结果

不同参数的含义是什么?

函数签名定义为

cv.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])

imagecircles 是不言自明的,将被跳过。

方法

指定内部使用的 hough 算法的变体。如 documentation 中所述,只有 HOUGH_GRADIENT 支持 atm。此方法利用 21HT (p.2, THE 2-1 HOUGH TRANSFORM)算法。这种变体的主要优点在于减少内存使用。使用霍夫变换检测圆的标准方法需要在 3D 霍夫空间(x、y 和半径)中进行搜索。然而,使用 21HT,你的 hough 空间被减少到只有 2 个维度,这减少了相当数量的内存消耗。

dp

dp 参数设置逆累加器分辨率。可以找到很好的解释here .请注意,此说明使用标准霍夫变换作为示例。但是对于21HT效果是一样的。 21HT 的蓄能器与标准 HT 的蓄能器略有不同。

最小距离

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

参数1

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

参数2

这一段可能应该由更熟悉 opencv 源代码的人验证。 param2 指定累加器阈值。该值决定了圆必须完整的程度才能算作有效圆。我不确定给出参数的单位是什么。但是(再次扫描源代码)看起来是一个绝对的投票阈值(意思是直接受不同半径的影响)。 下图显示了不同的圆圈(或可以识别为圆圈的东西)。您越往右走,检测到该圆圈所需的阈值就越低。

Accumulator threshold

最小半径和最大半径

只是将圆搜索限制在[minRadius, maxRadius]范围内的半径。如果您可以估计(或知道)要搜索的圆圈的大小,这将很有用(并且可以提高性能)。

关于python - 用OpenCV检测银球和反光球,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49650772/

相关文章:

python - 使用 houghCircles (OpenCV) 检测小圆圈

python - OpenCV+python : HoughLines accumulator access since 3. 4.2

python - 使用pyaudio进行录音

python - 将字典列表转换为列表

Python线程: Queue workers - hang the program

python - 在 Python 中规范化后验分布时遇到问题

python - 导入错误 : No module named 'cv2' Python3

opencv - 减色后的颜色数

opencv - 使用立体相机的距离结果不佳

opencv - 改善Opencv HoughLinesP中的行提取