当前位置: 首页 > 面试题库 >

环形霍夫变换错过了圈子

韩英锐
2023-03-14
问题内容

我已经阅读了很多有关Stack Overflow上的Round
Hough变换的信息,但似乎缺少了一些东西。我编写了一个程序,该程序应该能够检测“靶心”目标的圆圈。但是,即使在使用了参数之后,该算法也非常糟糕-
它忽略了大多数圆圈,有一次它找到了一个圆圈,但似乎在“徘徊”。我什至尝试应用“不清晰的蒙版”都无济于事。我已经添加了代码,我开始使用的图像和输出。我希望有人能指出我正确的方向。

import cv2
import cv2.cv as cv
import numpy as np
import math
# Load Image
img = cv2.imread('circles1.png',0)
# Apply Unsharp Mask
tmp = cv2.medianBlur(img,5)
img = cv2.addWeighted(img,1.5,tmp,-0.5,0)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)

# Hough Transform
circles = cv2.HoughCircles(img,cv.CV_HOUGH_GRADIENT,1,5,
                            param1=100,param2=100,minRadius=0,maxRadius=0)

circles = np.uint16(np.around(circles))

# Go over circles, eliminating the ones that are not cocentric enough
height, width = img.shape
center = (width/2,height/2)
for i in circles[0,:]:
    # draw the outer circle
    if math.sqrt((center[0]-i[0])**2 + (center[1]-i[1])**2) < 15:
        cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),1)
        # draw the center of the circle
        cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)

cv2.imshow('detected circles',cimg)

cv2.waitKey(0)
cv2.destroyAllWindows()

快速说明:我加载图像,应用“锐化蒙版”,使用“霍夫变换”来检测圆,然后绘制靠近中心的圆(我发现其他圆是假圆)。

我尝试使用参数,这是我得到的最好的结果。我觉得这是一个非常简单的问题,使我感到震惊。我寻求任何帮助。


问题答案:

正如我在评论中提到的那样,您需要cv2.HoughCircles针对不同的半径范围运行的连续迭代,以确保获得所有圆。通过圆形霍夫变换的工作方式,指定范围很大的最小和最大半径将是不准确的,而且也会很慢。他们没有在文档中告诉您这一点,但是为了使环形霍夫变换成功运行,需要确保以下两点正确:

maxRadius < 3*minRadius
maxRadius - minRadius < 100

使用上述方法,盲目地使最小半径非常小而最大半径却不会给您带来很好的效果。因此,您可以做的是从…说…开始radius=1,然后以radius=30020的步长迭代。在20的每个块之间,运行cv2.HoughCircles并使用这些轮廓更新图像。

这样做几乎不需要修改您的代码。顺便说一句,我删除了模糊的蒙版,因为我得到的效果不佳。我还cv2.HoughCircles稍微更改了几个参数,以根据您的情况使此参数尽可能地发挥作用:

import cv2
import cv2.cv as cv
import numpy as np
import math
# Load Image
img = cv2.imread('circles1.png',0)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)

# Specify different radii
radii = np.arange(0,310,10)

# For each pair of radii...
for idx in range(len(radii)-1):
    # Get the minimum and maximum radius
    # Note you need to add 1 to each minimum
    # as the maximum of the previous pair covers this new minimum
    minRadius = radii[idx]+1
    maxRadius = radii[idx+1]

    # Hough Transform - Change here
    circles = cv2.HoughCircles(img,cv.CV_HOUGH_GRADIENT,1,5,
                               param1=25,param2=75,minRadius=minRadius,maxRadius=maxRadius)

    # Skip if no circles are detected - Change here
    if circles is None:
        continue

    circles = np.uint16(np.around(circles))

    # Go over circles, eliminating the ones that are not cocentric enough
    height, width = img.shape
    center = (width/2,height/2)
    for i in circles[0,:]:
        # draw the outer circle
        if math.sqrt((center[0]-i[0])**2 + (center[1]-i[1])**2) < 15:
            cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),1)
            # draw the center of the circle
            cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)

cv2.imshow('detected circles',cimg)

cv2.waitKey(0)
cv2.destroyAllWindows()

不幸的是,它并不完美,因为它无法检测到所有圈子。您必须使用该cv2.HoughCircles功能,直到获得良好的结果。

但是,我不建议cv2.HoughCircles在这里使用。我可以建议cv2.findContours改用吗?这会找到图像中的所有轮廓。在这种情况下,这些将是黑色圆圈。但是,您需要反转图像,因为cv2.findContours假定非零像素是对象像素,因此我们可以从图像中减去255,并假设np.uint8类型为:

# Make copy of original image
cimg2 = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

# Find contours
contours,_ = cv2.findContours(255 - img, cv2.RETR_LIST, cv.CV_CHAIN_APPROX_NONE)

# Draw all detected contours on image in green with a thickness of 1 pixel
cv2.drawContours(cimg2, contours, -1, color=(0,255,0), thickness=1)

# Show the image
cv2.imshow('detected circles', cimg2)
cv2.waitKey(0)
cv2.destroyAllWindows()


 类似资料:
  • 学习目标 在本章中, 我们将学习使用霍夫变换来查找图像中的圆。 我们将看到以下函数:cv.HoughCircles() 理论 圆在数学上表示为$(x-x{center})^2+(y-y{center})^2 = r^2$,其中$(x{center},y{center})$是圆的中心,$r$是圆的半径。从等式中,我们可以看到我们有3个参数,因此我们需要3D累加器进行霍夫变换,这将非常低效。因此,Op

  • 可以通过使用类的方法应用霍夫变换技术来检测给定图像的形状。以下是此方法的语法。 该方法接受以下参数 - image - 表示此操作的源(输入图像)的对象。 lines - 类的一个对象,用于存储存储线的参数的向量。 rho - 类型为的变量,以像素为单位表示参数的分辨率。 theta - 类型为的变量,表示以弧度表示的参数的分辨率。 threshold - 一个整数类型的变量,表示“检测”一条直线

  • 目标 在这一章当中, 我们将学习使用霍夫变换来查找图像中的圆。 我们将看到这些函数:cv2.HoughCircles() 理论基础 一个圆在数学上可以表示为 $(x-x{center})^2 + (y - y{center})^2 = r^2$ 其中 $(x{center},y{center})$ 是圆的中心,$ r $ 是圆的半径。从等式中可以看出我们有3个参数,所以我们需要一个三维累加器来进行

  • 目标 在这一章当中, 我们将了解霍夫变换的概念。 我们将看到如何使用它来检测图像中的线条。 我们将看到以下函数:cv.HoughLines(),cv.HoughLinesP() 理论 如果可以用数学形式表示形状,则霍夫变换是一种检测任何形状的流行技术。即使形状有些破损或变形,也可以检测出形状。我们将看到它如何作用于一条线。 一条线可以表示为$y = mx + c$或以参数形式表示为$\rho=xc

  • 目标 我们将理解霍夫变换的概念。 我们将看到如何使用它来检测图像中的线条。 我们将看到以下函数:cv2.HoughLines(),cv2.HoughLinesP() 理论基础 霍夫变换是一种用来检测形状的流行的技术,如果你能以数学形式来表示这种形状的话。它可以检测到形状,即使它被破坏或扭曲了一点。我们将看到它是如何检测出一条线。 一条线可以表示为 $y = mx+c$,或以参数方程表示,$\rho

  • 本文向大家介绍霍夫曼编码算法,包括了霍夫曼编码算法的使用技巧和注意事项,需要的朋友参考一下 霍夫曼编码是一种无损数据压缩算法。在该算法中,分配了可变长度代码以输入不同的字符。代码长度与字符使用频率有关。最常见的字符具有最小的代码,较长的代码具有最不频繁的字符。 主要有两个部分。第一个创建霍夫曼树,另一个遍历该树以查找代码。 例如,考虑一些字符串“ YYYZXXYYX”,字符Y的频率大于X,字符Z的