houghcircles - 寻找参数

时间:2016-03-27 08:12:23

标签: python opencv image-processing hough-transform

是否有一种方法可以使圆检测无参数? - 为什么cv2.HoughCircles()中的参数有时会在更改后受到影响?我有一个for循环来改变参数,但它不会一直影响结果。

似乎Hough Circles需要用户进行大量的参数优化,如果用户想要以非常通用的方式使用系统,这是一个非常棘手的问题。因此,我试图创建一个算法来自动找到opencv的houghcirlces函数的最佳参数。 此时的houghcirlces函数将获得圆圈的最大和最小半径,它将在图像中找到,其中有一些阈值表示找到圆圈的匹配程度。

我希望将最小和最大半径的不同范围分开以在其中搜索,然后使用每个部分中找到的圆圈来确定我应该用于最终houghcircles变换的参数。 (如果有人有更好的方法,我很乐意听到它。)

然而我遇到了这个问题:

不会出现最小和最大半径参数,或Canny和Hough空间阈值受到尊重

例如,我们可以拍下这张图片:

circles

并运行以下代码:

import numpy as np
import cv2

file_path = '1.png'
img = cv2.imread(file_path)
gray = cv2.imread(file_path, cv2.IMREAD_GRAYSCALE)
# Begin using the largest dimesion of the image as the largest possible radius
largest_dimension = np.max([gray.shape[0], gray.shape[1]])
for i in range(1,100):
    # For the first iteration we use the largest possible radius
    if i == 1:
        maxRadius = largest_dimension
    # THe next iterations we use what the minimum radius was last iteration 
    else:
        maxRadius = minRadius
    # Reduce the size by 2 everytime
    minRadius = maxRadius/2
    dp = 1 # Inverse ratio of thresholded image resolution ?? Not sure what to do with this
    minDist = minRadius # Not likely to be much closer than the minimum radius...?
    param1 = 200 # Canny edge threshold - image OTSU threshold dependence ?? 
    param2 = 100 # Hough space threshold - radius dependance?  np.pi*maxRadius**2 ??
    circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp, minDist, param1, param2, minRadius, maxRadius)

    # Display some inforation about the results
    if circles is not None:
        img_copy = img.copy()
        radii = np.array([c[2] for c in circles[0]])
        num = len(circles[0])
        avg = np.mean(radii)
        print str(num) + ' found: avg radius: ' + str(avg)
        if any(radii < minRadius) or any(radii > maxRadius):
            print 'The minimum and maximum radii given are not being respected' 
        for c in circles[0]:
            cv2.circle(img_copy, (c[0],c[1]), c[2], (255,0,255),2)

        cv2.namedWindow('', cv2.WINDOW_NORMAL)
        cv2.imshow('',img_copy)
        cv2.waitKey(0)

我们将得到如下所示的输出,并且每次都不会被该函数遵守。此外,如果我们将param1和param2(Canny边缘检测和Hough空间阈值)从3更改为6000,几乎没有任何变化。

显然,下面显示的图像检测到的圆圈比任何人通常都要多,而且只会变得更糟。

cicrlces

我可能会提到,我希望将来使用此脚本的图像将显示为如下内容:

2 个答案:

答案 0 :(得分:0)

我有同样的问题,参数表现得很奇怪 - 你有

circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp, minDist, param1, param2, minRadius, maxRadius)

但功能签名实际上是

>>> import cv2
>>> print cv2.HoughCircles.__doc__
HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) -> circles

请注意参数列表中的circles -

我从某个地方复制了一些明确命名其余参数的代码,比如

circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)

并且在某些时候我删除了名字。错误!

答案 1 :(得分:0)

为了更准确地检测圆圈并消除噪音,我实际上会在灰度图像上执行精确边缘检测器,然后再将其发送到HoughCircles()方法。通过这样做,您可以获得更高的边缘检测阈值精度,因为您可以完全控制两个参数而不仅仅是一个参数。

Canny(src_gray, src_gray, 300, 500, 3 );
HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 1, image.rows/2, 30, 30, 40, 1000 );

使用canny()方法的参数,特别是300和500,并为您的用例找到最佳位置。希望这有用!祝你好运