Opencv 开发之霍夫变换检测圆的基本原理:其实检测圆形和检测直线的原理差别不大,只不过直线是在二维空间,因为 y=kx+b,只有 k 和 b 两个自由度。而圆形的一般性方程表示为 (x-a)2+(y-b)2=r2。那么就有三个自由度圆心坐标 a,b, 和半径 r。这就意味着需要更多的计算量,而 OpenCV 中提供的 cvHoughCircle() 函数里面可以设定半径 r 的取值范围,相当于有一个先验设定,在每一个 r 来说,在二维空间内寻找 a 和 b 就可以了,能够减少计算量。
具体步骤如下:
1. 对输入图像进行边缘检测,获取边界点,即前景点。
2. 假如图像中存在圆形,那么其轮廓必定属于前景点(此时请忽略边缘提取的准确性)。
3. 同霍夫变换检测直线一样,将圆形的一般性方程换一种方式表示,进行坐标变换。由 x-y 坐标系转换到 a-b 坐标系。写成如下形式 (a-x)2+(b-y)2=r2。那么 x-y 坐标系中圆形边界上的一点对应到 a-b 坐标系中即为一个圆。
4. 那 x-y 坐标系中一个圆形边界上有很多个点,对应到 a-b 坐标系中就会有很多个圆。由于原图像中这些点都在同一个圆形上,那么转换后 a,b 必定也满足 a-b 坐标系下的所有圆形的方程式。直观表现为这许多点对应的圆都会相交于一个点,那么这个交点就可能是圆心 (a, b)。
5. 统计局部交点处圆的个数,取每一个局部最大值,就可以获得原图像中对应的圆形的圆心坐标 (a,b)。一旦在某一个 r 下面检测到圆,那么 r 的值也就随之确定。
以下面的图片为例,调用 OpenCV 中的 cvHoughCircles() 进行圆形的检测,左边为原图,右边为检测结果,圆形都被圈出。
代码:
- #include "cv.h"#include "highgui.h"#includeusing namespace cv;
- void main() {
- IplImage * srcImg = cvLoadImage("img.jpg", CV_LOAD_IMAGE_GRAYSCALE);
- CvMemStorage * storage = cvCreateMemStorage(0);
- cvSmooth(srcImg, srcImg, CV_GAUSSIAN, 5, 5); //函数范围值为指向图像序列的指针CvSeq* results=cvHoughCircles(srcImg, storage, CV_HOUGH_GRADIENT, 2,srcImg->width/10);for (int i=0; itotal; i++){float* p=(float*) cvGetSeqElem(results, i); //依次获取图像序列中的图像数据CvPoint pt=cvPoint(cvRound(p[0]), cvRound(p[1])); //获取圆心坐标cvCircle(srcImg, pt, cvRound(p[2]), CV_RGB(0xff, 0xff, 0xff), 3, 8); //在图片中将圆形画出来}cvNamedWindow("Img", 1);cvShowImage("Img", srcImg);cvWaitKey(-1);cvReleaseImage(&srcImg);cvDestroyAllWindows();}
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/04-14/20447775.html