文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

目标

在这个教程中你将学习如何:

原理

霍夫圆变换

  • 霍夫圆变换的工作原理与前面教程中解释的霍夫线变换大致 相似。

  • 在霍夫线检测时,通过两个参数 (r, \theta)定义线。 在霍夫圆的情况下,我们需要三个参数来定义一个圆:

    C : ( x_{center}, y_{center}, r )

    这里的 (x_{center}, y_{center}) 表示圆心的位置 (下图中的绿点) 而 r 表示半径, 这样我们就能唯一的定义一个圆了, 见下图:

    Result of detecting circles with Hough Transform
  • 出于对运算效率的考虑, OpenCV实现的是一个比标准霍夫圆变换更为灵活的检测方法: 霍夫梯度法。获取更多详细信息,请查看学习OpenCV一书或您最喜欢的计算机视觉参考书

第 1 段(可获 2 积分)

代码

  1. 这个程序是做什么的?
    • 加载图片并进行模糊化以降低噪点
    • 使用 Hough 霍夫圆转换为模糊图片.
    • 在窗口中显示检测到的圆.
  2. 示例代码可从这里 下载. 一个稍微漂亮点的版本(值此标准和可变阈值的霍夫算法)可从这里 下载.
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

using namespace cv;

/** @function main */
int main(int argc, char** argv)
{
  Mat src, src_gray;

  /// Read the image
  src = imread( argv[1], 1 );

  if( !src.data )
    { return -1; }

  /// Convert it to gray
  cvtColor( src, src_gray, CV_BGR2GRAY );

  /// Reduce the noise so we avoid false circle detection
  GaussianBlur( src_gray, src_gray, Size(9, 9), 2, 2 );

  vector<Vec3f> circles;

  /// Apply the Hough Transform to find the circles
  HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows/8, 200, 100, 0, 0 );

  /// Draw the circles detected
  for( size_t i = 0; i < circles.size(); i++ )
  {
      Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
      int radius = cvRound(circles[i][2]);
      // circle center
      circle( src, center, 3, Scalar(0,255,0), -1, 8, 0 );
      // circle outline
      circle( src, center, radius, Scalar(0,0,255), 3, 8, 0 );
   }

  /// Show your results
  namedWindow( "Hough Circle Transform Demo", CV_WINDOW_AUTOSIZE );
  imshow( "Hough Circle Transform Demo", src );

  waitKey(0);
  return 0;
}
第 2 段(可获 2 积分)

说明

  1. 加载一幅图像

    src = imread( argv[1], 1 );
    
    if( !src.data )
      { return -1; }
    
  2. 转成灰度图:

    cvtColor( src, src_gray, CV_BGR2GRAY );
    
  3. 应用高斯模糊以减少噪声并避免假圆检测:

    GaussianBlur( src_gray, src_gray, Size(9, 9), 2, 2 );
    
  4. 执行霍夫圆变换:

    vector<Vec3f> circles;
    
    HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows/8, 200, 100, 0, 0 );
    

    有以下自变量:

    • src_gray: 输入图像 (灰度图)
    • circles: 存储下面三个参数: x_{c}, y_{c}, r 集合的容器来表示每个检测到的圆.
    • CV_HOUGH_GRADIENT: 指定检测方法. 现在OpenCV中只有霍夫梯度法
    • dp = 1: 分辨率的反比
    • min_dist = src_gray.rows/8: 检测到圆心之间的最小距离
    • param_1 = 200: Canny边缘检测器的上限阈值
    • param_2 = 100*: 圆心检测阈值.
    • min_radius = 0: 能检测到的最小圆半径, 默认为0.
    • max_radius = 0: 能检测到的最大圆半径, 默认为0
  5. 绘出检测到的圆:

    for( size_t i = 0; i < circles.size(); i++ )
    {
       Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
       int radius = cvRound(circles[i][2]);
       // circle center
       circle( src, center, 3, Scalar(0,255,0), -1, 8, 0 );
       // circle outline
       circle( src, center, radius, Scalar(0,0,255), 3, 8, 0 );
     }
    

    你将会看到圆用红色绘出而圆心用小绿点表示

  6. 显示检测到的圆:

    namedWindow( "Hough Circle Transform Demo", CV_WINDOW_AUTOSIZE );
    imshow( "Hough Circle Transform Demo", src );
    
  7. 等待用户按键结束程序

    waitKey(0);
    

结果

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

Result of detecting circles with Hough Transform

第 3 段(可获 2 积分)

文章评论