• OpenCV 实现霍夫圆变换


    返回:OpenCV系列文章目录(持续更新中......)

    上一篇:OpenCV实现霍夫变换
    下一篇:OpenCV 实现重新映射

    目标

    在本教程中,您将学习如何:

    • 使用 OpenCV 函数 HoughCircles()检测图像中的圆圈。

    理论

    Hough 圆变换

    • Hough Circle 变换的工作方式与上一教程中介绍的 Hough Line 变换大致相似。
    • 在线路检测情况下,一条线路由两个参数 (r,Q)定义。在圆的情况下,我们需要三个参数来定义一个圆:

      其中 (xcenter,ycenter)定义中心位置(绿点,),r是半径,这让我们可以完全定义一个圆,如下图所示:

    • 为了提高效率,OpenCV 实现了一种比标准 Hough 变换稍微棘手的检测方法:Hough 梯度方法,它由两个主要阶段组成。第一阶段涉及边缘检测和查找可能的圆心,第二阶段为每个候选中心找到最佳半径。有关更多详细信息,请查看《学习 OpenCV》一书或您最喜欢的计算机视觉参考书目
    • 这个程序是做什么的?

    • 加载图像并对其进行模糊处理以减少噪点
    • 将 Hough Circle 变换应用于模糊图像。
    • 在窗口中显示检测到的圆圈。

    C++代码

    我们将要解释的示例代码可以从这里下载。可以在此处找到一个稍微花哨的版本(显示用于更改阈值的跟踪栏)。

    1. #include "opencv2/imgcodecs.hpp"
    2. #include "opencv2/highgui.hpp"
    3. #include "opencv2/imgproc.hpp"
    4. using namespace cv;
    5. using namespace std;
    6. int main(int argc, char** argv)
    7. {
    8. const char* filename = argc >=2 ? argv[1] : "smarties.png";
    9. // Loads an image
    10. Mat src = imread( samples::findFile( filename ), IMREAD_COLOR );
    11. // Check if image is loaded fine
    12. if(src.empty()){
    13. printf(" Error opening image\n");
    14. printf(" Program Arguments: [image_name -- default %s] \n", filename);
    15. return EXIT_FAILURE;
    16. }
    17. Mat gray;
    18. cvtColor(src, gray, COLOR_BGR2GRAY);
    19. medianBlur(gray, gray, 5);
    20. vector circles;
    21. HoughCircles(gray, circles, HOUGH_GRADIENT, 1,
    22. gray.rows/16, // change this value to detect circles with different distances to each other
    23. 100, 30, 1, 30 // change the last two parameters
    24. // (min_radius & max_radius) to detect larger circles
    25. );
    26. for( size_t i = 0; i < circles.size(); i++ )
    27. {
    28. Vec3i c = circles[i];
    29. Point center = Point(c[0], c[1]);
    30. // circle center
    31. circle( src, center, 1, Scalar(0,100,100), 3, LINE_AA);
    32. // circle outline
    33. int radius = c[2];
    34. circle( src, center, radius, Scalar(255,0,255), 3, LINE_AA);
    35. }
    36. imshow("detected circles", src);
    37. waitKey();
    38. return EXIT_SUCCESS;
    39. }

    解释

    我们使用的图像可以在这里找到

    加载图像:

    1. const char* filename = argc >=2 ? argv[1] : "smarties.png";
    2. // Loads an image
    3. Mat src = imread( samples::findFile( filename ), IMREAD_COLOR );
    4. // Check if image is loaded fine
    5. if(src.empty()){
    6. printf(" Error opening image\n");
    7. printf(" Program Arguments: [image_name -- default %s] \n", filename);
    8. return EXIT_FAILURE;
    9. }

    将其转换为灰度:

    1. Mat gray;
    2. cvtColor(src, gray, COLOR_BGR2GRAY);

    应用中值模糊以减少噪点并避免误圆检测:

     medianBlur(gray, gray, 5);

    继续应用 Hough Circle 变换:

    1. vector circles;
    2. HoughCircles(gray, circles, HOUGH_GRADIENT, 1,
    3. gray.rows/16, // change this value to detect circles with different distances to each other
    4. 100, 30, 1, 30 // change the last two parameters
    5. // (min_radius & max_radius) to detect larger circles
    6. );
    • 带有参数:
      • 灰色:输入图像(灰度)。
      • circles:存储 3 个值集的向量:xc1,yc1 对于每个检测到的圆。
      • HOUGH_GRADIENT:定义检测方法。目前,这是 OpenCV 中唯一可用的。
      • dp = 1:分辨率的倒比。
      • min_dist = gray.rows/16:检测到的中心之间的最小距离。
      • param_1 = 200:内部 Canny 边缘检测器的上限阈值。
      • param_2 = 100*:中心检测的阈值。
      • min_radius = 0:要检测的最小半径。如果未知,则将零作为默认值。
      • max_radius = 0:要检测的最大半径。如果未知,则将零作为默认值。

    绘制检测到的圆圈:

    1. for( size_t i = 0; i < circles.size(); i++ )
    2. {
    3. Vec3i c = circles[i];
    4. Point center = Point(c[0], c[1]);
    5. // circle center
    6. circle( src, center, 1, Scalar(0,100,100), 3, LINE_AA);
    7. // circle outline
    8. int radius = c[2];
    9. circle( src, center, radius, Scalar(255,0,255), 3, LINE_AA);
    10. }

    你可以看到,我们将用红色画圆圈,用一个小绿点画中心

    显示检测到的圆圈并等待用户退出程序:

    1. imshow("detected circles", src);
    2. waitKey();

    结果

    使用测试图像运行上述代码的结果如下所示:


    参考文献:

    1、《Hough Circle Transform》------Ana Huamán

  • 相关阅读:
    高效阅读JDK源码,保姆级JDK源码笔记真香
    ip子网的划分方法
    C++ 中的 typeid 运算符和示例
    电脑重装系统后Win11扬声器无插座信息如何解决?
    xml 解析bean工具类
    [航海协会]树
    Mysql 数据恢复逻辑 基于binlog redolog undolog
    C语言-指针相关使用
    泊松随机变量的分解与求和
    05.深入理解JMM和Happens-Before
  • 原文地址:https://blog.csdn.net/2301_78348935/article/details/138174783