《Open CV3编程入门》学习笔记14

霍夫圆变化:对于直线由r,θ表示,而对于圆来说,由圆心坐标和半径表示。
具体由“霍夫梯度法”的方法来实现:
1.转化为单通道图像(如灰度图像)后,进行边缘检测,通常使用canny边缘检测;
2.对边缘图像中的每个非零点,计算其局部梯度,即用Sobel()函数计算x和y方向的Sobel一阶导数得到梯度;
3.利用梯度方向和该点坐标得一线段(梯度方向为圆弧的法线方向,即半径方向),线段的起点与长度由半径长度决定。将线段经过的点在累加器中累加;
4.从累加器中选择候选的中心,这些中心都大于给定阈值并且大于其所有近邻。这些候选的中心按照累加值降序排列;
5.计算所有边界图中的非0点离圆心的距离,并从小到大排序,从小半径r开始,距离相差在一个小量范围内的点,都认为是同一个圆,记数属于该半径r的非0点数,记为n;
6.尝试放大半径,同样记数改半径的点数,判断两个半径孰优孰劣的依据——点的线密度(点数n/半径r),密度越高,半径的可信度越大;
7.重复以上步骤,直至半径超过参数允许的范围,从而得到最优半径;
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main( )
{
	//【1】载入原始图、Mat变量定义   
	Mat srcImage = imread("10.bmp");  //工程目录下应该有一张名为10.jpg的素材图
	Mat midImage,dstImage;//临时变量和目标图的定义

	//【2】显示原始图
	imshow("【原始图】", srcImage);  

	//【3】转为灰度图并进行图像平滑
	cvtColor(srcImage,midImage, CV_BGR2GRAY);//转化边缘检测后的图为灰度图
	GaussianBlur( midImage, midImage, Size(9, 9), 2, 2 );

	//【4】进行霍夫圆变换
	vector<Vec3f> circles;//圆心坐标以及半径
	HoughCircles( midImage, circles, CV_HOUGH_GRADIENT,1.5, 10, 150, 100, 0, 0 );
	/*该算子包含了canny等一系列过程;
	第一个参数:InputArray类型的image,输入图像,即源图像,需为8位的灰度单通道图像,可以不是二值图而霍夫直线变化需要为二值图;
    第二个参数:InputArray类型的circles,经过调用HoughCircles函数后此参数存储了检测到的圆的输出矢量,每个矢量由包含了3个元素的浮点矢量(x, y, radius)表示;
    第三个参数:int类型的method,即使用的检测方法,目前OpenCV中就霍夫梯度法一种可以使用,它的标识符为CV_HOUGH_GRADIENT,在此参数处填这个标识符即可;
    第四个参数:double类型的dp,用来检测圆心的累加器图像的分辨率于输入图像之比的倒数,累加器图像的分辨率。这个参数允许创建一个比输入图像分辨率低的累加器。(这样做是因为有理由认为图像中存在的圆会自然降低到与图像宽高相同数量的范畴)。
               如果dp设置为1,则分辨率是相同的;如果设置为更大的值(比如2),累加器的分辨率受此影响会变小(此情况下为一半),dp的值不能比1小;
    第五个参数:double类型的minDist,为霍夫变换检测到的圆的圆心之间的最小距离,即让我们的算法能明显区分的两个不同圆之间的最小距离。这个参数如果太小的话,多个相邻的圆可能被错误地检测成了一个重合的圆。反之,这个参数设置太大的话,某些圆就不能被检测出来了。
	第六个参数:double类型的param1,有默认值100。它是第三个参数method设置的检测方法的对应的参数。对当前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示传递给canny边缘检测算子的高阈值,而低阈值为高阈值的一半。
	第七个参数:double类型的param2,也有默认值100。它是第三个参数method设置的检测方法的对应的参数。对当前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示在检测阶段圆心的累加器阈值。它越小的话,就可以检测到更多根本不存在的圆,而它越大的话,能通过检测的圆就更加接近完美的圆形了。
	第八个参数:int类型的minRadius,有默认值0,表示圆半径的最小值。
	第九个参数:int类型的maxRadius,也有默认值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( srcImage, center, 3, Scalar(0,255,0), -1, 8, 0 );
		//绘制圆轮廓
		circle( srcImage, center, radius, Scalar(155,50,255), 3, 8, 0 );
	}

	//【6】显示效果图  
	imshow("【效果图】", srcImage);  

	waitKey(0);  

	return 0;  
}



参考:http://blog.csdn.net/hhyh612/article/details/54947205

缺点:同心圆或近似同心圆无法保留,且一般保留最大的一个圆;累加器阈值过低时,计算时间过长;产生噪声(错误的结果)。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值