OpenCV26HoughCircles 霍夫圆变换原理及圆检测

这篇具有很好参考价值的文章主要介绍了OpenCV26HoughCircles 霍夫圆变换原理及圆检测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

霍夫圆变换的基本原理与霍夫线变换大体类似

对直线来说,一条直线能由极径极角(r,θ)表示,而对于圆来说,我们需要三个参数:圆心(a,b),半径 r

霍夫变换检测圆原理,OpenCV,Powered by 金山文档

笛卡尔坐标系中圆的方程为:

(x-a)2 + (y-b)2 = r2

化简便可得到:

a = x - r·cosθ

b = y - r·sinθ

  • 对于(x0,y0),我们可以将通过这一点的所有圆统一定义为:

a = x0 - r·cosθ

b = y0 - r·sinθ

这就意味着每一组(a,b,r)代表一个通过点(x0,y0)的圆。

  • 对于一个给定点(x0,y0),我们可以在三维直角坐标系中,绘出所有通过它的圆。最终我们将得到一条三维的曲线。

  • 我们可以对图像中所有的点进行上述操作.。如果两个不同点进行上述操作后得到的曲线在空间 a - b - r 相交, 即它们有一组公共的(a,b,r),这就意味着它们在同一个圆上。

  • 越多曲线交于一点,也就意味着这个交点表示的圆由更多的点组成。我们可以设置一个阈值,来决定多少条曲线交于一点我们才认为检测到了一个圆。

  • 这就是霍夫圆变换要做的.。它追踪图像中每个点对应曲线间的交点.。如果交于一点的曲线的数量超过了阈值, 那么可以认为这个交点所代表的参数(a,b,r)在原图像中为一个圆。

以上是标准霍夫圆变换实现算法。问题是它的累加面(绘制三维曲线的空间)是一个三维的空间,意味着比霍夫线变换需要更多的计算消耗。OpenCV 霍夫圆变换对标准霍夫圆变换做了运算上的优化。它采用的是 “霍夫梯度法”。

霍夫梯度法的原理

  • 估计圆心

1.把原图做一次 Canny 边缘检测,得到边缘检测的二值图。

2.对原始图像执行一次 Sobel 算子,计算出所有像素的邻域梯度值。

3.初始化圆心空间 N(a,b),令所有的 N(a,b)=0。

4.遍历 Canny 边缘二值图中的所有非零像素点,沿着梯度方向 ( 切线的垂直方向 )画线,将线段经过的所有累加器中的点 (a,b) 的 N(a,b)+=1。

霍夫变换检测圆原理,OpenCV,Powered by 金山文档

5.统计排序 N(a,b),得到可能的圆心(N(a,b) 越大,越有可能是圆心)

  • 估计半径(针对某一个圆心 (a,b))

1.计算 Canny 图中所有非 0 点距离圆心的距离。

2.距离从小到大排序,根据阈值,选取合适的可能半径(比如 3 和 3.5 都被划为半径值 3 中)。

3.初始化半径空间 r, N(r)=0。

4.遍历 Canny 图中的非 0 点,N( 距离 )+=1。

5.统计得到可能的半径值(N(r) 越大,说明这个距离值出现次数越多,越有可能是半径值)。

霍夫梯度法缺点

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

2.在边缘图像中的整个非0像素集被看做每个中心的候选部分。因此,如果把累加器的阈值设置偏低,算法将要消耗比较长的时间。

3.因为每一个中心只选择一个圆,如果有同心圆,就只能选择其中的一个。

4.因为中心是按照其关联的累加器值的升序排列的,并且如果新的中心过于接近之前已经接受的中心的话,就不会被保留下来。且当有许多同心圆或者是近似的同心圆时,霍夫梯度法的倾向是保留最大的一个圆。可以说这是一种比较极端的做法,因为在这里默认Sobel导数会产生噪声,若是对于无穷分辨率的平滑图像而言的话,这才是必须的。

霍夫圆变换:HoughCircles 函数

HoughCircles 函数可以利用霍夫变换算法检测出灰度图中的圆。它相比之前的 HoughLines 和HoughLinesP,比较明显的一个区别是不需要源图像是二值的,而 HoughLines 和HoughLinesP 都需要源图像是二值图像。

void HoughCircles(InputArray image, OutputArray circles, int method, double dp, double minDist, double param1 = 100, double param2 = 100, int minRadius = 0, int maxRadius = 0);
  • image,输入图像,即源图像,需要为 8 位的灰度单通道图像。

  • circles,调用 HoughCircles 函数后此参数存储了检测到的圆的输出矢量,每个矢量由包含了 3 个元素的浮点矢量(x,y,radius)表示。

  • method,使用的检测方法,目前 OpenCV 中就霍夫梯度法一种可以使用,标识符为 HOUGH_GRADIENT。

  • dp,累加面分辨率(大小) = 原始图像分辨率(大小) × 1/dp。默认 dp = 1 时,两者分辨率相同。

  • minDist,两个圆心之间的最小距离。若两圆心距离 < minDist,则认为是同一个圆。

  • param1,Canny 边缘检测的高阈值,低阈值被自动置为高阈值的一半,默认为 100。

  • param2,累加平面某点是否是圆心的判定阈值。它越大,能通过检测的圆就更接近完美的圆形,默认为 100。

  • minRadius,圆半径的最小值。默认为 0。

  • maxRadius,圆半径的最大值,默认为 0。

此函数可以很容易地检测出圆心,但是可能找不到合适地圆半径。我们可以通过 minRadius 和 maxRadius 两个参数指定最大和最小圆半径,来辅助圆检测的结果。或者可以直接忽略返回半径,让二者均为默认值,只用 HoughCircles 函数检测出圆心,用额外步骤进一步确定半径。文章来源地址https://www.toymoban.com/news/detail-772920.html

霍夫变换检测圆原理,OpenCV,Powered by 金山文档
霍夫变换检测圆原理,OpenCV,Powered by 金山文档
霍夫变换检测圆原理,OpenCV,Powered by 金山文档
霍夫变换检测圆原理,OpenCV,Powered by 金山文档
霍夫变换检测圆原理,OpenCV,Powered by 金山文档
/*OpenCV26霍夫圆检测


*/

#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

Mat src;
Mat src2;
Mat dst;
char *output_name = "霍夫圆结果";

int main(int argc, char *argv[])
{
    //src = imread("e:\\pictures\\梁平柚.jpg");
   // src = imread("e:\\pictures\\多个圆.jpg");
    src = imread("e:\\pictures\\blk_bg_sample.jpg");
    //src = imread("e:\\pictures\\圆形.jpg");
    //src = imread("e:\\pictures\\球形图.jpg");
    
        
    
    if (!src.data)
    {
        printf("failed to load image");
        return -1;
    }
    namedWindow("原图",CV_WINDOW_AUTOSIZE);
    namedWindow(output_name,CV_WINDOW_AUTOSIZE);
    imshow("原图",src);
    

    Mat m_output;
    //中值滤波,去噪声
    medianBlur(src,m_output,3);
    //转灰度图像
    cvtColor(m_output,m_output,CV_BGR2GRAY);

    //霍夫圆检测
    vector<Vec3f> maybe_circles;//检测出有几个圆

    //30表示,达到30,可能是圆
    //HoughCircles(m_output,maybe_circles,CV_HOUGH_GRADIENT,1,10,100,30,5,50);//多个圆
           //    xx         xx              method           dp,minDist,p1 ,param2,   min,max(半径最大值,0是默认值)


           //minDist 和 param2 数值的设定是关键,第5,7个参数
    //HoughCircles(m_output, maybe_circles, CV_HOUGH_GRADIENT, 1, 100,    100, 80 ,0,  0 );//圆形,球形图
      HoughCircles(m_output, maybe_circles, CV_HOUGH_GRADIENT, 1, 100,     100, 28, 0, 0);//blk_bg_sample

    src.copyTo(dst);
    
    for (size_t i = 0; i < maybe_circles.size(); i++)
    {
        Vec3f cc = maybe_circles[i];
        circle(dst,Point(cc[0],cc[1]),cc[2],Scalar(0,0,255),2,LINE_AA);
        circle(dst, Point(cc[0], cc[1]), 2, Scalar(99, 23, 255), 2, LINE_AA);
    }
    imshow(output_name,dst);

    waitKey(0);



    return 0;
}

到了这里,关于OpenCV26HoughCircles 霍夫圆变换原理及圆检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 霍夫变换直线检测算法实现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日
    浏览(38)
  • [C++] opencv - HoughCircles(霍夫圆查找)函数介绍和使用场景

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

    2024年02月03日
    浏览(41)
  • 【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)
  • opencv 十一 霍夫圆检测原理及高级使用案例(含优化步骤)

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

    2024年02月04日
    浏览(62)
  • 【矩阵检测】Hough霍夫变换矩阵检测【含Matlab源码 3563期】

    获取代码方式1: 完整代码已上传我的资源:【矩阵检测】基于matlab Hough霍夫变换矩阵检测【含Matlab源码 3563期】 点击上面蓝色字体,直接付费下载,即可。 获取代码方式2: 付费专栏Matlab图像处理(初级版) 备注: 点击上面蓝色字体 付费专栏Matlab图像处理(初级版) ,扫

    2024年02月04日
    浏览(38)
  • Python-OpenCV中的图像处理-霍夫变换

    霍夫(Hough)变换在检测各种形状的技术中非常流行,如果要检测的形状可以用数学表达式描述,就可以是使用霍夫变换检测它。即使要检测的形状存在一点破坏或者扭曲也是可以使用。 Hough直线变换,可以检测一张图像中的直线 cv2.HoughLines(image, rho, theta, threshold) return:返回值

    2024年02月13日
    浏览(59)
  • OpenCV-Python中的图像处理-霍夫变换

    霍夫(Hough)变换在检测各种形状的技术中非常流行,如果要检测的形状可以用数学表达式描述,就可以是使用霍夫变换检测它。即使要检测的形状存在一点破坏或者扭曲也是可以使用。 Hough直线变换,可以检测一张图像中的直线 cv2.HoughLines(image, rho, theta, threshold) return:返回值

    2024年02月12日
    浏览(44)
  • 霍夫变换椭圆检测(matlab仿真与图像处理系列第2期)

    椭圆检测是图像处理中的一个重要问题,其目的是从图像中检测出可能存在的椭圆。在实际的应用中,椭圆常常被用来描述物体的形状或者得到物体的尺寸信息。 传统的椭圆检测方法通常采用二维Hough变换,在求解过程中需要处理大量的数据,并且计算复杂度高,导致速度较

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

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

    2024年02月16日
    浏览(44)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包