【问题标题】:detecting small circles using houghCircles (OpenCV)使用 houghCircles (OpenCV) 检测小圆圈
【发布时间】:2017-05-08 15:50:34
【问题描述】:

我正在尝试使用 houghcircles() 检测此裁剪图像中的小圆圈。我试图改变它的参数,但是当我将 param2 增加到 50 以上时它会出错,当它的值小于 100 时 maxRadius 也会出错。现在它运行但性能很差 这是原始图像:

这是结果图像:

这是我的代码:

from imutils.perspective import four_point_transform
from imutils import contours
import numpy as np
import argparse
import imutils
import cv2

im = cv2.imread('crop.png')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray, 200, 255,cv2.THRESH_BINARY)
cimg = cv2.cvtColor(thresh,cv2.COLOR_GRAY2BGR)

c = cv2.HoughCircles(thresh, cv2.HOUGH_GRADIENT, 0.5, 41, param1=70, 
param2=30, minRadius=10,maxRadius=175)
c = np.uint16(np.around(c))

for i in c[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.namedWindow('img',cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 800,800)
cv2.imshow('img',cimg)
cv2.waitKey(0)
cv2.destroyAllWindows()

请问,我应该如何更改参数?

【问题讨论】:

    标签: python opencv image-processing hough-transform


    【解决方案1】:

    如果您在不了解参数的作用的情况下尝试更改参数,则需要很长时间才能解决此问题。

    此说明来自here

    minDist:检测到的圆的中心 (x, y) 坐标之间的最小距离。如果 minDist 太小,则在 可能(错误地)检测到与原始邻域相同的邻域。如果 minDist 太大,可能根本检测不到某些圆圈。

    param1:Yuen 等人用于处理边缘检测的梯度值。方法。

    param2:cv2.HOUGH_GRADIENT 方法的累加器阈值。阈值越小,圈数越多 检测到(包括假圆圈)。阈值越大, 可能会返回更多圈子。

    minRadius:半径的最小尺寸(以像素为单位)。

    ma​​xRadius:半径的最大尺寸(以像素为单位)。

    您可以清楚地看到图像中的圆圈具有固定的半径,并且它们之间的距离最小。如果你设置这两个,你可以提高你的结果。所以阅读文档很重要。

    关于您的问题,如果您有特殊需要使用 Houghcircles,请继续进行微调。您可以做的改进是,使用 gaussianblur 进行预处理,使用自适应阈值而不仅仅是阈值。

    如果没有必要使用霍夫圆,我建议您改用轮廓。因为它更健壮并且可以很好地泛化到不同的图像。这是我使用轮廓得到的结果。圆圈看起来更小,因为我使用了 6 次迭代的侵蚀和 3 次迭代的膨胀。

    这是我使用的代码。

    import numpy as np
    import cv2
    
    image_color= cv2.imread("Ye3gs.png")
    image_ori = cv2.cvtColor(image_color,cv2.COLOR_BGR2GRAY)
    
    lower_bound = np.array([0,0,10])
    upper_bound = np.array([255,255,195])
    
    image = image_color
    
    mask = cv2.inRange(image_color, lower_bound, upper_bound)
    
    # mask = cv2.adaptiveThreshold(image_ori,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
    #             cv2.THRESH_BINARY_INV,33,2)
    
    kernel = np.ones((3, 3), np.uint8)
    
    #Use erosion and dilation combination to eliminate false positives. 
    #In this case the text Q0X could be identified as circles but it is not.
    mask = cv2.erode(mask, kernel, iterations=6)
    mask = cv2.dilate(mask, kernel, iterations=3)
    
    closing = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
    
    contours = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
            cv2.CHAIN_APPROX_SIMPLE)[0]
    contours.sort(key=lambda x:cv2.boundingRect(x)[0])
    
    array = []
    ii = 1
    print len(contours)
    for c in contours:
        (x,y),r = cv2.minEnclosingCircle(c)
        center = (int(x),int(y))
        r = int(r)
        if r >= 6 and r<=10:
            cv2.circle(image,center,r,(0,255,0),2)
            array.append(center)
    
    cv2.imshow("preprocessed", image_color)
    cv2.waitKey(0)
    

    希望这会有所帮助:)

    【讨论】:

    • 感谢您的帮助,但它给了我一个错误:contours.sort(key=lambda x:cv2.boundingRect(x)[0]) TypeError: 'key' is an invalid keyword argument for this function
    • 非常感谢它在我添加此功能时为我工作def get_contour_precedence(contour, cols): tolerance_factor = 10 origin = cv2.boundingRect(contour) return ((origin[1] // tolerance_factor) * tolerance_factor) * cols + origin[0]
    • 我建议使用contours + minEnclosureCircle函数,然后将圆形边界/区域与检测到的轮廓进行比较,过滤掉非圆形轮廓
    • @LilyBaker 你能解释一下你是如何修复 TypeError 的吗?我得到了同样的东西。
    【解决方案2】:

    在 OpenCV 3 中,findContours 的签名已更改。 要获得返回的轮廓,您需要更改此行:

    contours = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
    

    到这里

    contours = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[1]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多