霍夫圆检测

  • 霍夫圆检测原理
  • API


霍夫圆检测原理

霍夫圆变换的基本原理和霍夫线变换类似, 只是点对应的二维极径极角空间被三维的圆心点x, y还有半径r空间取代;
对直线来说, 一条直线能由参数极径极角 (r, \theta) 表示,而对圆来说, 我们需要三个参数来表示一个圆, 如上文所说现在原图像的边缘图像的任意点对应的经过这个点的所有可能圆是在三维空间有下面这三个参数来表示了,其对应一条三维空间的曲线. 那么与二维的霍夫线变换同样的道理, 对于多个边缘点越多这些点对应的三维空间曲线交于一点那么他们经过的共同圆上的点就越多,类似的我们也就可以用同样的阈值的方法来判断一个圆是否被检测到, 这就是标准霍夫圆变换的原理, 但也正是在三维空间的计算量大大增加的原因, 标准霍夫圆变化很难被应用到实际中。
出于上面提到的对运算效率的考虑, OpenCV实现的是一个比标准霍夫圆变换更为灵活的检测方法: 霍夫梯度法, 也叫2-1霍夫变换(21HT), 它的原理依据是圆心一定是在圆上的每个点的模向量上, 这些圆上点模向量的交点就是圆心, 霍夫梯度法的第一步就是找到这些圆心, 这样三维的累加平面就又转化为二维累加平面

java霍夫圆检测 霍夫圆检测原理_OpenCV


java霍夫圆检测 霍夫圆检测原理_OpenCV_02

API

  • HoughCircles
CV_EXPORTS_W void HoughCircles( InputArray image, //输入图像(灰度图)
							   OutputArray circles,//存储下面三个参数: x_{c}, y_{c}, r 集合的容器来表示每个检测到的圆.
                               int method, //指定检测方法. 现在OpenCV中只有霍夫梯度法 HOUGH_GRADIENT
                               double dp,//累加器图像的反比分辨率
                               double minDist,//检测到圆心之间的最小距离 src_gray.rows/8:
                               double param1 = 100, //Canny边缘提取,高阈值
                               double param2 = 100,//圆心检测阈值
                               int minRadius = 0, //能检测到的最小圆半径, 默认为0
                               int maxRadius = 0 );//能检测到的最大圆半径, 默认为0

PS:霍夫检测对噪声比较敏感,因此在这之前适当进行滤波处理,对于函数中的每一个参数都要什么敏感,这样才能进行灵活调参,以达到最好的处理效果!例如,我们对于这张硬币图中,通过调参使得检测出所有霍夫圆!!!

Mat src = imread("F:/code/images/coins.jpg");
	imshow("input", src);
	Mat gray;
	cvtColor(src, gray, COLOR_RGB2GRAY);
	GaussianBlur(gray, gray, Size(3, 3), 2, 2);
	imshow("gray", gray);
	
	vector<Vec3f> circles;
	double minDist = 25;
	double min_radius = 20;
	double max_radius = 100;
	HoughCircles(gray, circles, HOUGH_GRADIENT, 1, minDist, 70, 80, min_radius, max_radius);
	for (size_t t = 0; t < circles.size(); t++) {
		Point center(circles[t][0],circles[t][1]);
		int radius = round(circles[t][2]);
		circle(src, center, radius, Scalar(0, 0, 255), 2, 8, 0);
		circle(src, center, 3, Scalar(255, 0, 0), 2, 8, 0);
	}
	imshow("hough circle demo", src);

java霍夫圆检测 霍夫圆检测原理_ci_03