使用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像。而霍夫圆变换则只要输入灰度图像即可,因为在霍夫圆变换的过程中已经用到了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变换检测圆
----------------------------------------------------------------------------
/* Finds circles in the image */
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; }
测试原图:
运行结果:
本文系原创,转载请注明!