霍夫圆变换与直线变换大体上是类似的,但是累加平面会被三维累加容器代替,(x,y,r),x,y确定圆心,r确定半径,但这意味着需要大量内存速度较慢,OpenCV通过一个比较灵活的霍夫梯度法来解决圆变换问题,利用到cvSobel。累加器概念不是很明白??
-------------------------------------------------------------------------------------------------
霍夫圆变换的函数为:
利用 Hough 变换在灰度图像中找圆
CvSeq* cvHoughCircles( CvArr* image, void* circle_storage, int method, double dp, double min_dist, double param1=100, double param2=100, int min_radius=0, int max_radius=0 );
. 每个圆由三个浮点数表示:圆心坐标(x,y)和半径.
Resolution of the accumulator used to detect centers of the circles. For example, if it is 1, the accumulator will have the same resolution as the input image, if it is 2 - accumulator will have twice smaller width and height, etc.
Minimum distance between centers of the detected circles. If the parameter is too small, multiple neighbor circles may be falsely detected in addition to a true one. If it is too large, some circles may be missed.
The first method-specific parameter. In case of CV_HOUGH_GRADIENT it is the higher threshold of the two passed to Canny edge detector (the lower one will be twice smaller).
The second method-specific parameter. In case of CV_HOUGH_GRADIENT it is accumulator threshold at the center detection stage. The smaller it is, the more false circles may be detected. Circles, corresponding to the larger accumulator values, will be returned first.
Minimal radius of the circles to search for.
Maximal radius of the circles to search for. By default the maximal radius is set to max(image_width, image_height).
The function cvHoughCircles finds circles in grayscale image using some modification of Hough transform.
-------------------------------------------------------------------------------------------------/*code*/
利用cvHoughCircles在灰度图中找到圆序列并返回。
#include
#include
#include
int main(int argc, char** argv)
{
IplImage* src = cvLoadImage( argv[1], 0 );
IplImage* dst = cvLoadImage( argv[1], 0 );
CvMemStorage* storage = cvCreateMemStorage(0);
cvSmooth( src, dst, CV_GAUSSIAN, 5, 5 ); //降噪
CvSeq* results = cvHoughCircles( //cvHoughCircles函数需要估计每一个像素梯度的方向,
//因此会在内部自动调用cvSobel,而二值边缘图像的处理是比较难的
dst,
storage,
CV_HOUGH_GRADIENT,
2, //累加器图像的分辨率
image->width/10
);
for( int i = 0; i < results->total; i++ )
{
float* p = ( float* )cvGetSeqElem( results, i );
//霍夫圆变换
CvPoint pt = cvPoint( cvRound( p[0] ), cvRound( p[1] ) );
cvCircle(
dst,
pt, //确定圆心
cvRound( p[2] ), //确定半径
CV_RGB( 0xff, 0, 0 )
); //画圆函数
}
cvNamedWindow( "cvHoughCircles", 1 );
cvShowImage( "cvHoughCircles", dst );
cvWaitKey(0);
return 0;
}
-------------------------------------------------------------------------------------------------
/*result*/
Hough Circle