天天看点

图像变换-使用Hough变换检测圆

使用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像。而霍夫圆变换则只要输入灰度图像即可,因为在霍夫圆变换的过程中已经用到了canny边缘检测。

Hough变换的原理可以参考下面两篇文章:

http://blog.163.com/yuyang_tech/blog/static/21605008320130233343990

http://www.cfanz.cn/index.php?c=article&a=read&id=133338

关于用Hough变换检测圆的原理,在下面这篇论文中有提到:

http://wenku.baidu.com/link?url=Y0kc37_nSMzSObToFmwR3dutksaPXWM0BCfA861sLX0E9N1ZM5RNBz2vLp-mc9pDNhZ0Svg0DAcYjrfQavaQB3mAU4Rkp8s6t09aMUzieZW

本文着重讲解怎样是opencv中使用hough变换检测圆

----------------------------------------------------------------------------

CVAPI(CvSeq*) cvHoughCircles( CvArr* image, void* circle_storage,

                              int method, double dp, double min_dist,

                              double param1 CV_DEFAULT(100),

                              double param2 CV_DEFAULT(100),

                              int min_radius CV_DEFAULT(0),

                              int max_radius CV_DEFAULT(0));

image :输入 8-比特、单通道 (二值) 图像

circle_storage :输出圆心坐标(x、y),和半径r

method : Hough 变换方式,目前只支持CV_HOUGH_GRADIENT

dp :累加器图像的分辨率。如果dp设置为1,则分辨率是相同的;如果设置为更大的值(比如2),累加器的分辨率受此影响会变小(此情况下为一半)。dp的值不能比1小。

minDist :让算法能明显区分的两个不同圆之间的最小距离。

param1 :用于Canny的边缘阀值上限,下限被置为上限的一半。

param2 :累加器的阀值。

minRadius :最小圆半径

maxRadius :最大圆半径,默认为最大值 max(image_width, image_height)

--------------------------------------------------------------------------

#include<cv.h>
#include<highgui.h>

int main()
{
	IplImage* src = NULL;
	IplImage* dst = NULL;
	IplImage* color = NULL;

	src = cvLoadImage ("1.bmp", 1);
	dst = cvCreateImage (cvGetSize(src), IPL_DEPTH_8U, 1);
	if (src->nChannels == 1)
	{
		dst = cvCloneImage (src);
	}
	else
	{
		cvCvtColor (src, dst, CV_RGB2GRAY);
	}
	color = cvCreateImage (cvGetSize(src), IPL_DEPTH_8U, 3);
	cvCvtColor (dst, color, CV_GRAY2RGB);

	
	CvMemStorage* storage = cvCreateMemStorage (0);
	//cvSmooth (dst, dst, CV_GAUSSIAN, 5, 5);
	cvSmooth(dst,dst,CV_MEDIAN,11);
	
	CvSeq* circles = cvHoughCircles (dst, storage, CV_HOUGH_GRADIENT, 2, dst->width / 30, 50, 80, 10, 70);
	
	
	for (int i = 0; i < circles->total; i++)
	{
		float* p = (float*)cvGetSeqElem (circles, i);
		CvPoint pt = cvPoint (cvRound(p[0]), cvRound(p[1]));
		cvCircle (color, pt, cvRound(p[2]), CV_RGB(255, 0, 0), 3, 8, 0);
	}

	cvNamedWindow ("src", 1);
	cvShowImage ("src", src);
	cvNamedWindow ("circle", 1);
	cvShowImage ("circle", color);

	cvWaitKey (0);

	cvReleaseMemStorage (&storage);
	cvReleaseImage (&src);
	cvReleaseImage (&dst);
	cvReleaseImage (&color);

	return 0;
}
           

在使用时参数的调整是关键,一定要知道各参数的调整才能调出合适的参数。

测试原图:

图像变换-使用Hough变换检测圆

运行结果:

图像变换-使用Hough变换检测圆

本文系原创,转载请注明!