OpenCV中的圆形检测

15

我在选择HoughCircles函数的正确参数方面遇到了问题。 我尝试从视频中检测圆圈。这些圆圈是我制作的,几乎具有相同的尺寸。 问题是相机在移动。

当我更改maxRadius时,它仍然以某种方式检测到更大的圆圈(请参见右图)。 我还尝试更改param1,param2,但仍没有成功。

左-原始图片,右-模糊和检测出的圆圈
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  blurred = cv2.medianBlur(gray, 25)#cv2.bilateralFilter(gray,10,50,50)


  minDist = 100
  param1 = 500
  param2 = 200#smaller value-> more false circles
  minRadius = 5
  maxRadius = 10
  circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist, param1, param2, minRadius, maxRadius)

  if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        cv2.circle(blurred,(i[0], i[1]), i[2], (0, 255, 0), 2) 

也许我使用的函数不正确?


为什么param1和param2太高了?尝试使用这些参数:param1=100,param2=30,minradius=1,maxradius=100 - Yunus Temurlenk
在你的图像中,minDist=100 有意义吗?尝试根据这些圆的实际距离减小 minDist。 - Micka
2个回答

12

无需使用cv2.HoughCircles来选择正确的参数,这里介绍了一种使用轮廓过滤的替代方法。其思路是通过Otsu二值化阈值获得二进制图像,然后进行形态学操作以分离出椭圆形状的轮廓。最后,我们使用查找轮廓并使用长宽比轮廓面积进行筛选。以下是结果:

enter image description here

import cv2
import numpy as np

# Load image, grayscale, median blur, Otsus threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray, 11)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

# Morph open 
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=3)

# Find contours and filter using contour area and aspect ratio
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.04 * peri, True)
    area = cv2.contourArea(c)
    if len(approx) > 5 and area > 1000 and area < 500000:
        ((x, y), r) = cv2.minEnclosingCircle(c)
        cv2.circle(image, (int(x), int(y)), int(r), (36, 255, 12), 2)

cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('image', image)
cv2.waitKey()     

12
你代码中的主要问题在于HoughCircles函数的第五个参数。
根据文档,参数列表是: cv2.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) → circles 这意味着第五个参数应用于circles(它提供了一种通过引用获取输出的选项,而不是使用返回值)。
因为你没有传递circles参数,所以必须为第四个参数后的所有参数传递命名参数(例如param1=param1param2=param2....)。
参数调整问题:
  • 降低param1的值。 param1是传递给Canny的高阈值。
    在你的情况下,该值应该约为30
  • 减小param2的值。文档并不是很清楚,但将值设置为约50即可。
  • 增加maxRadius的值-半径10远小于圆的半径。
  • import numpy as np
    import cv2
    
    img = cv2.imread('circles.png')
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    blurred = cv2.medianBlur(gray, 25) #cv2.bilateralFilter(gray,10,50,50)
    
    minDist = 100
    param1 = 30 #500
    param2 = 50 #200 #smaller value-> more false circles
    minRadius = 5
    maxRadius = 100 #10
    
    # docstring of HoughCircles: HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) -> circles
    circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)
    
    if circles is not None:
        circles = np.uint16(np.around(circles))
        for i in circles[0,:]:
            cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
    
    # Show result for testing:
    cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    结果:

    在此输入图片描述


    这是一个展示图片的代码段,点击链接可以查看图片。

1
谢谢,这正是我所需要的。你太棒了 :) - Toriam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接