霍夫圆变换原理
霍夫圆变换的基本原理与霍夫线变换(https://www.cnblogs.com/bjxqmy/p/12331656.html)大体类似。
笛卡尔坐标系中圆的方程为:
化简便可得到:
a = x0 - r·cosθ
b = y0 - r·sinθ
这就意味着每一组(a,b,r)代表一个通过点 的圆。
对于一个给定点 ,我们可以在三维直角坐标系中,绘出所有通过它的圆。最终我们将得到一条三维的曲线:
以上是标准霍夫圆变换实现算法。问题是它的累加面(绘制三维曲线的空间)是一个三维的空间,意味着比霍夫线变换需要更多的计算消耗。OpenCV 霍夫圆变换对标准霍夫圆变换做了运算上的优化。它采用的是 “霍夫梯度法”。
霍夫梯度法的原理
霍夫梯度法缺点
霍夫圆变换: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);
此函数可以很容易地检测出圆心,但是可能找不到合适地圆半径。我们可以通过 minRadius 和 maxRadius 两个参数指定最大和最小圆半径,来辅助圆检测的结果。或者可以直接忽略返回半径,让二者均为默认值,只用 HoughCircles 函数检测出圆心,用额外步骤进一步确定半径。
代码示例
#include
#include
using namespace std;
using namespace cv;
int hough_value = 55;
Mat src, gray;
void hough_change(int, void*) {
vectorcircles; //minDist 和 param2 数值的设定是关键
HoughCircles(gray, circles, HOUGH_GRADIENT, 1, 10, 110, hough_value, 0, 0);
Mat show = src.clone();
for (int i = 0; i < circles.size(); i++) {
circle(show, Point(circles[i][0], circles[i][1]), circles[i][2], Scalar(0, 0, 255), 2);
}
imshow("show", show);
}
int main() {
src = imread("C:/Users/齐明洋/Desktop/1.jpg");
GaussianBlur(src, src, Size(3, 3), 0, 0);
imshow("src", src);
cvtColor(src, gray, COLOR_BGR2GRAY);
namedWindow("show");
createTrackbar("hough_value", "show", &hough_value, 200, hough_change);
hough_change(0, 0);
waitKey(0);
}
效果演示:
借鉴博客:https://www.cnblogs.com/yzl050819/p/7967526.html
https://www.cnblogs.com/lancer2015/p/6852488.html
https://blog.csdn.net/weixin_41049188/article/details/92422241?utm_source=distribute.pc_relevant.none-task