OpenCV笔记(十八)——使用霍夫变换检测圆圈
这些笔记的最初,我是以接近于源码分析的形式来梳理自己学习OpenCV的过程。
然而写下来,一是执行力,二是时间的问题,确实越写越马虎了。用我老师的话:观其大略了。
但是,暂时就这么写着吧。
在笔记《十七》中,我们简单地谈到了霍夫变换检测直线的原理,就是判断相邻像素点的值(x, y)对应的r-theta曲线是否能够相交,如果有足够多的相邻的像素点的曲线相交,我们就认为这些相邻的像素点构成一条直线。
圆圈亦然,只是把直线的方程替换成了圆的方程。除了极坐标的r,多了两个变量:Xcenter和Ycenter。
r就是像素所在的圆圈的半径,X-center和Y-center就是这个圆圈的圆心。
如果若干相邻的像素,他们对应的r、X-center、Y-center能够相交,就说明它们位于同一个圆圈的曲线上。
在OpenCV中,我们在使用霍夫变换检测之前,一般先对图像进行高斯平滑,去除噪声。
OpenCV中是这样定义HoughCircles函数的:
void HoughCircles(InputArray image, OutputArray circles, int method, double dp, double minDist, doubleparam1=100, double param2=100, int minRadius=0, int maxRadius=0 )
image需要8位单通道的灰度图像
circles一般为vector<Vec3f>
method一般为CV_HOUGH_GRADIENT
dp是输入图像和处理图像的比值,如果为1,则两者相同;如果为2,则处理的图像是输入图像的一半大小。
minDist是检测到的圆圈之间,它们的圆心的最小距离。
param1是传入canny()函数的higher threshold。默认lower threshold为higher threshold的一半。
param2暂时不了解。看示例代码吧。
OpenCV中关于HoughCircles的例子:
1 void HoughDetection(const Mat& src_gray, const Mat& src_display, int cannyThreshold, int accumulatorThreshold) 2 { 3 // will hold the results of the detection 4 std::vector<Vec3f> circles; 5 // runs the actual detection 6 HoughCircles( src_gray, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows/8, cannyThreshold, accumulatorThreshold, 0, 0 ); 7 8 // clone the colour, input image for displaying purposes 9 Mat display = src_display.clone(); 10 for( size_t i = 0; i < circles.size(); i++ ) 11 { 12 Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); 13 int radius = cvRound(circles[i][2]); 14 // circle center 15 circle( display, center, 3, Scalar(0,255,0), -1, 8, 0 ); 16 // circle outline 17 circle( display, center, radius, Scalar(0,0,255), 3, 8, 0 ); 18 } 19 20 // shows the results 21 imshow( windowName, display); 22 } 23 }