使用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像。而霍夫圆变换则只要输入灰度图像即可,因为在霍夫圆变换的过程中已经用到了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;
}
在使用时参数的调整是关键,一定要知道各参数的调整才能调出合适的参数。
测试原图:
运行结果:
本文系原创,转载请注明!