霍夫变换圆检测原理及 OpenCV API 应用

痛定思痛。 2022-12-25 03:54 260阅读 0赞

霍夫变换圆检测原理及 OpenCV API 应用

1. 霍夫圆变换

霍夫圆检测和霍夫直线检测的原理类似。建议先理解霍夫直线检测的原理,再来看霍夫圆检测。

圆在极坐标下的数学表达式如下:
{ x = a + r ⋅ c o s θ y = b + r ⋅ s i n θ \left\{ \begin{aligned} x = a + r\cdot cos\theta \\ y = b + r\cdot sin\theta \\ \end{aligned} \right. { x=a+r⋅cosθy=b+r⋅sinθ
其中 a , b a, b a,b 是圆心的坐标, r r r 是半径。上面的表达式如果转换到霍夫空间( a b r abr abr三维坐标)上,一个点就可以表示一个圆。所以在abr组成的三维坐标系中,一个点可以唯一确定一个圆。
{ a = x − r ⋅ c o s θ b = y − r ⋅ s i n θ r = r \left\{ \begin{aligned} a = &x - r\cdot cos\theta \\ b = &y - r\cdot sin\theta \\ r = &r \end{aligned} \right. ⎩⎪⎨⎪⎧a=b=r=x−r⋅cosθy−r⋅sinθr
上面是标准霍夫圆变换的原理,和霍夫直线变换相比,最大的区别是霍夫空间变成了三维空间,这就给统计效率带来了挑战。2-1霍夫变换(21HT)是对标准霍夫变换的改进,把霍夫变换分为两个阶段,从而减小了霍夫空间的维数。第一阶段用于检测圆心,第二阶段从圆心推导出圆半径。该算法有一个不足之处就是由于圆半径的检测完全取决于圆心的检测,因此如果圆心检测出现偏差,那么圆半径的检测肯定也是错误的。OpenCV 中的霍夫变换圆是基于 21HT 实现的。更多关于霍夫圆变换的原理介绍可以参考 霍夫圆变换。

2. OpenCV API

  • C++:`voidHoughCircles`(InputArray image, OutputArray circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0, int maxRadius=0 )









































Para Disc.
image 输入图像 ,必须是8位的单通道灰度图像
circles 输出结果,发现的圆信息,也是向量数组vector
method 目前只有 HOUGH_GRADIENT,通过梯度来寻找
dp dp = 1:在原图上寻找;dp = 2, 原图宽高减半
mindist 如果两个圆的圆心距离小于 mindist 则认为是同一个圆
param1 Canny 检测时的 高阈值,低阈值是 param1 的一半
param2 中心点累加器阈值,小于该阈值的会被忽略
minradius,maxradius 搜寻半径范围

3. OpenCV API 应用

由于 对噪声比较敏感,所以一般需要先进行去噪操作,比如 GaussianBlur(), 或者 medianBlur 等。

  1. #include <opencv2/imgproc.hpp>
  2. #include <opencv2/highgui.hpp>
  3. #include <math.h>
  4. #include <vector>
  5. using namespace cv;
  6. using namespace std;
  7. int main(int argc, char** argv)
  8. {
  9. Mat img, gray;
  10. img = imread("D:\\Code\\test\\image\\c.jpg", 1); // color image
  11. cvtColor(img, gray, COLOR_BGR2GRAY);
  12. // smooth it, otherwise a lot of false circles may be detected
  13. GaussianBlur(gray, gray, Size(9, 9), 2, 2);
  14. vector<Vec3f> circles;
  15. HoughCircles(gray, circles, HOUGH_GRADIENT, 2, gray.rows / 4, 200, 100);
  16. for (size_t i = 0; i < circles.size(); i++)
  17. {
  18. Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
  19. int radius = cvRound(circles[i][2]);
  20. // draw the circle center
  21. circle(img, center, 3, Scalar(0, 255, 0), -1, 8, 0);
  22. // draw the circle outline
  23. circle(img, center, radius, Scalar(0, 0, 255), 3, 8, 0);
  24. }
  25. namedWindow("circles", 1);
  26. imshow("circles", img);
  27. waitKey(0);
  28. return 0;
  29. }

在这里插入图片描述

参考

-霍夫圆检测

-霍夫圆检测

-OpenCV霍夫变换系列(中篇)-霍夫圆变换

发表评论

表情:
评论列表 (有 0 条评论,260人围观)

还没有评论,来说两句吧...

相关阅读