opencv 十一 霍夫圆检测原理及高级使用案例(含优化步骤)

这篇具有很好参考价值的文章主要介绍了opencv 十一 霍夫圆检测原理及高级使用案例(含优化步骤)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

霍夫圆检测能检测出目标图像中存在的圆,但在实际使用中,参数调节存在很大的困难,故在本博文中对霍夫圆检测的原理、参数列表、优化经验进行分析总结。详细的列出了各个参数的调节依据,实现了在复杂背景下的霍夫圆检测。

1. 原理介绍

1.1 基本原理

相关知识:
霍夫圆检测与霍夫变换密切相关,霍夫变换是基于极坐标系(是由半径与夹角所描述的一种坐标系)与笛卡尔坐标系(普通的平面坐标系)的相互转变而实现的。笛卡尔坐标系上的一个点,变换到极坐标系上就变成了一条线;反之亦然。
霍夫圆检测原理,opencv实战,opencv,人工智能,计算机视觉

然而,基于霍夫变换的霍夫圆检测方法计算量极大,不适合实际应用。在opencv的实现中,是使用霍夫梯度算法进行圆检测。
参考链接:https://www.cnblogs.com/bjxqmy/p/12333022.html

1.2 霍夫梯度法的原理

1.把原图做一次 Canny 边缘检测,得到边缘检测的二值图。
2.对原始图像执行一次 Sobel 算子,计算出所有像素的邻域梯度值。
3.初始化圆心空间 N(a,b),令所有的 N(a,b)=0。若要求圆心在图像中,则a,b值的范围分别对应图像的宽高,N(a,b)表示一共有a*b个。
4.遍历 Canny 边缘二值图中的所有非零像素点,沿着梯度方向 (切线的垂直方向,根据Sobel 算子计算出的垂直梯度及水平梯度得来)固定搜索半径范围画线,将线段经过的所有累加器中的点 (a,b) 的 N(a,b)+=1。
霍夫圆检测原理,opencv实战,opencv,人工智能,计算机视觉

5.统计排序 N(a,b),得到可能的圆心(N(a,b) 越大,越有可能是圆心)。
霍夫圆检测原理,opencv实战,opencv,人工智能,计算机视觉
参考链接:https://zhuanlan.zhihu.com/p/427270299

1.3 霍夫梯度法缺点

1.在霍夫梯度法中,使用 Sobel 导数来计算局部梯度,那么随之而来的假设是,其可以视作等同于一条基于几个局部点的切线,并这个不是一个数值稳定的做法。在大多数情况下,这样做会得到正确的结果,但或许会在输出中产生一些噪声。

2.在边缘图像中的整个非0像素集被看做每个中心的候选部分,若没有合理设置梯度方向的搜索半径范围,则会导致计算量巨大。

3.因为霍夫梯度算法通过圆弧切线的垂直线进行圆心累加检测,当存在同心圆时,会累加到同一个圆心,这导致只会选择到累加值最大的圆。

1.4 参数详情

霍夫圆检测的使用代码如下

method=cv2.HOUGH_GRADIENT
circles=cv2.HoughCircles(image, method, dp=1, minDist=10, param1=None, param2=None, minRadius=None, maxRadius=None)

其参数列表详情如下:

Circles:用来存储HoughCircles的结果,类型为list,list中对象格式为x,y,r;
image:输入图像,即源图像,8位单通道图像,如果使用彩色图像,需要先转换成灰度图像;
method:定义检测图像中圆的方法。目前唯一实现的方法是cv2.HOUGH_GRADIENT;
dp:图像像素分辨率与参数空间分辨率的比值(官方文档上写的是图像分辨率与累加器分辨率的比值,它把参数空间认为是一个累加器,毕竟里面存储的都是经过的像素点的数量),dp=1,则参数空间与图像像素空间(分辨率)一样大,dp=2,参数空间的分辨率只有像素空间的一半大;#通过设置dp可以减少计算量
minDist:检测到的圆中心(x,y)坐标之间的最小距离。如果minDist太小,则会保留大部分圆心相近的圆。如果minDist太大,则会将圆心相近的圆进行合并(若两圆心距离 < minDist,则认为是同一个圆)。
param1:canny 边缘检测的高阈值,低阈值被自动置为高阈值的一半,默认为 100。;
param2:累加平面某点是否是圆心的判定阈值。大于该阈值才判断为圆。当值设置的很小是,检测到的圆越多。默认值为 100;
minRadius:半径的最小大小(以像素为单位)默认为 0;
maxRadius:半径的最大大小(以像素为单位)默认为 0。

2. 实际应用

2.1 基本运行代码

以下代码,实现了读取图像进行霍夫圆检测,试图检测出下图车辆中的车轮。但其参数设置有待调整优化。

import cv2
import numpy as np
import time
if __name__ == "__main__":
    name="test.jpg"
    img = cv2.imread(name)
    t1=time.time()
    GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    circles = cv2.HoughCircles(GrayImage, cv2.HOUGH_GRADIENT, 1, 40, param1=70, param2=30, minRadius=0,maxRadius=0)
    t2=time.time()
    print("运行时间:",t2-t1)

    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        x,y,r=i[0],i[1],i[2]
        #draw the outer circle
        cv2.circle(img,(x,y),r,(0,255,0),2)
        cv2.circle(img,(x,y),2,(0,0,255),3)
    cv2.imshow("img",img)
    cv2.waitKey()

原始图像内容如下:
霍夫圆检测原理,opencv实战,opencv,人工智能,计算机视觉

2.2 优化方案

在运行以上代码时,因计算量巨大,电脑直接卡死。(原因1:图像缺乏处理优化、原因2:霍夫圆参数不合理、)

2.2.1 图像优化

图像优化是为了减少霍夫圆检测过程中的干扰点,因为3个点就可以构成一个圆。

边缘噪声滤除

1、对图像进行中值|均值滤波优化,减少图像中存在的边缘噪声。
所增加的代码如下,在16s内终于出了结果

    #GrayImage= cv2.medianBlur(GrayImage,7)#中值滤波 滤除背景噪声
    GrayImage= cv2.blur(GrayImage,(7,7))#均值滤波 滤除背景噪声

霍夫圆检测原理,opencv实战,opencv,人工智能,计算机视觉

计算量削减

2、对图像size进行优化,因为进行霍夫圆检测时,图像size对检测精度影响不大。但对图像进行下采样(缩小后)可以大幅度减少计算量。
所增加的代码如下,在0.76s内出了结果,但也不是很准。若缩放到0.25倍,则可在0.06秒内跑出结果

    GrayImage=cv2.resize(GrayImage,None,fx=0.5,fy=0.5)

霍夫圆检测原理,opencv实战,opencv,人工智能,计算机视觉

正圆保持

此步骤非必须。
在某些特殊情况,如钢卷的圆心检测,由于重力作用,钢卷的侧面圆被压成了椭圆,需要对其y方向(垂直方向)进行拉伸。如以下代码,将图像在y方向拉伸了1.2倍,此时钢卷的侧面椭圆被拉伸成了正圆。
img=cv2.resize(img,None,fx=1,fy=1.2)

2.2.2 检测参数优化

检索半径优化

通过对上图分析,发现检测到的圆太多了,且初步预估车轮的像素半径范围为20-80(通过多次设置范围,确定车轮像素在20~80之间)。
此时的霍夫圆检测参数如下:minRadius=20,maxRadius=80

circles = cv2.HoughCircles(GrayImage, cv2.HOUGH_GRADIENT, 1, minDist=40, param1=70, param2=30, minRadius=20,maxRadius=80)

此时检测效果如下,代码仅在0.03秒内跑出结果(比原先快了20倍),因此限定了霍夫圆检索半径。
霍夫圆检测原理,opencv实战,opencv,人工智能,计算机视觉

圆心累加优化

经过上个步骤优化后,仍有实际中不存在的圆被检测出来。这是因为累加圆心(圆弧上的在圆心上的累加值,累加值超过该阈值则被认为是一个圆)设置不合理所导致的。
此时的霍夫圆检测参数如下:param2=50, minRadius=20,maxRadius=80

circles = cv2.HoughCircles(GrayImage, cv2.HOUGH_GRADIENT, 1, minDist=4, param1=70, param2=50, minRadius=20,maxRadius=80)

此时检测效果如下,仅在0.03秒内跑出结果(跟上一步骤相同),因此限定了霍夫圆检索半径
霍夫圆检测原理,opencv实战,opencv,人工智能,计算机视觉

圆心距离优化

通过上述步骤后,发现针对某些圆会检测出多个圆心距离很近的圆。原先的圆心距设置很合理,但为了出优化效果,故将上一步的圆心距离设置的很小。这是由于检测步骤中的最小圆心距离设置不合理所导致的。
此时的霍夫圆检测参数如下:minDist=20, param2=50, minRadius=20,maxRadius=80
此时检测效果如下,已经能较好的定位到车轮区域。
霍夫圆检测原理,opencv实战,opencv,人工智能,计算机视觉

最优完整代码

额外说明:若对检测到的圆效果存在疑惑时,可以自行对原图进行cany求边缘,以校验参数param1设置的是否合理,既根据cany运算的效果来调整param1的值(其为canny 边缘检测的高阈值),通常该值不需要进行调整,因为该值对效果影响不大。文章来源地址https://www.toymoban.com/news/detail-758165.html

import cv2
import numpy as np
import time
if __name__ == "__main__":
    name="test.jpg"
    img = cv2.imread(name)
    t1=time.time()
    img=cv2.resize(img,None,fx=0.5,fy=0.5)
    GrayImage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #GrayImage= cv2.medianBlur(GrayImage,7)#中值滤波 滤除背景噪声
    GrayImage= cv2.blur(GrayImage,(7,7))#均值滤波 滤除背景噪声
    circles = cv2.HoughCircles(GrayImage, cv2.HOUGH_GRADIENT, 1, minDist=20, param1=70, param2=50, minRadius=20,maxRadius=80)
    t2=time.time()
    print("运行时间:",t2-t1)#只统计霍夫圆检测时间
	
	#这里进行圆绘制
    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        x,y,r=i[0],i[1],i[2]
        #draw the outer circle
        cv2.circle(img,(x,y),r,(0,255,0),2)
        cv2.circle(img,(x,y),2,(0,0,255),3)
    cv2.imshow("img1",img)
    cv2.waitKey()

到了这里,关于opencv 十一 霍夫圆检测原理及高级使用案例(含优化步骤)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Opencv-霍夫圆检测-代码解析

    目录 目录 前言 一、霍夫圆检测代码 二、函数解析 1.cv2.HoughCircles函数 2.双边滤波:bilateralFilter() 函数 3.形态学操作-开运算  4.cv2.circle()-画圆 5.cv2.putText函数 6.opencv的RGB 颜色表 7.cv2.imshow和cv2.waitKey函数  ​编辑 8.霍夫圆思路 总结   刚入门opencv时,霍夫圆检测是一个很好的练

    2024年02月06日
    浏览(38)
  • 霍夫变换直线检测原理和应用

    今天我们将重点讨论霍夫变换,这是一种非常经典的线检测的算法,通过将图像中的点映射到参数空间中的线来实现。霍夫变换可以检测任何方向的线,并且可以在具有大量噪声的图像中很好地工作。 闲话少说,我们直接开始吧! 为了理解霍夫变换的工作原理,首先我们需

    2024年02月06日
    浏览(94)
  • 霍夫变换直线检测算法实现OpenCV(C++)

    一、原理 对于霍夫变换的原理这里就不进行描述啦,感兴趣的可以自行搜索。也可以看知乎上面的这篇贴文通俗易懂理解——霍夫变换原理。 二、算法代码 三、效果测试 测试代码 上述代码中的drawLine()函数是《OpenCV4快速入门》一书的代码清单 7-2中的原函数,只用于画线。

    2024年02月05日
    浏览(45)
  • OpenCV | 霍夫变换:以车道线检测为例

    霍夫变换 霍夫变换只能灰度图,彩色图会报错 lines = cv2.HoughLinesP(edge_img,1,np.pi/180,15,minLineLength=40,maxLineGap=20) 参数1:要检测的图片矩阵 参数2:距离r的精度,值越大,考虑越多的线 参数3:距离theta的精度,值越大,考虑越多的线 参数4:累加数阈值,值越小,考虑越多的线

    2024年02月04日
    浏览(39)
  • 【OpenCV】cv2.HoughLines()霍夫直线检测

    霍夫直线检测(Hough Line Transform)是一种在图像中检测直线的经典算法。它通过将二维图像空间中的点映射到极坐标空间中,将直线检测问题转化为在参数空间中找到交点的问题。 原理: 对于图像空间中的每个边缘点,计算其对应在极坐标空间中可能的直线。 极坐标空间中

    2024年02月05日
    浏览(55)
  • OPENCV C++(七)霍夫线检测+找出轮廓和外接矩形+改进旋转

    霍夫线检测  定义存放输出线的向量 此向量输出有距离,角度 因为检测的原理就是在变换霍夫空间里面去检测的,这里可以理解为极坐标 第3个参数是距离精度 第四个参数是角度精度,第五个是阈值,只有点超过90个才算一条线 在图中画线操作: 这里是画线操作  概率霍夫

    2024年02月13日
    浏览(47)
  • 【OpenCV-Python】——边缘和轮廓&Laplacian/Sobel/Canny边缘检测&查找/绘制轮廓及轮廓特征&霍夫直线/圆变换

    目录 前言: 1、边缘检测 1.1 Laplacian边缘检测  1.2 Sobel边缘检测  1.3 Canny边缘检测 2、图像轮廓 2.1 查找轮廓  2.2 绘制轮廓 2.3 轮廓特征 3、霍夫变换 3.1 霍夫直线变换  3.2 霍夫圆变换 总结: 图像的边缘是指图像中灰度值急剧变化的位置,边缘检测的目的是为了绘制边缘线条。

    2024年01月23日
    浏览(47)
  • [C++] opencv - HoughCircles(霍夫圆查找)函数介绍和使用场景

    HoughCircles函数用于在灰度图像中使用霍夫变换查找圆。 该函数通过修改霍夫变换来实现,通常可以很好地检测出圆的中心,但可能无法找到正确的半径。可以通过指定半径范围(minRadius和maxRadius)来协助该函数,或者在#HOUGH_GRADIENT方法中将maxRadius设置为负数以仅返回圆心而不进

    2024年02月03日
    浏览(41)
  • 基于Python OpenCV、使用霍夫变换的小车视觉循线识别

            近期在做一个小车视觉循线的项目。小车将沿着一条线行驶,并用自带的摄像头拍摄道路前方的道路,行驶过程会遇到钝角拐弯、弧线拐弯、直角拐弯这些特殊元素,小车需要在识别元素之后进行合理地转弯。         在网上看到大部分的循线方法主要是二值化

    2024年02月16日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包