opencv中實現霍夫圓變換是通過霍夫梯度法。該原理是:首先對圖像應用邊沿檢測(cvCanny)。然後,對邊緣圖像中每一個非0點,考慮其局部梯度(Sobel()函數計算X、Y方向的sobel一階導數得到梯度)。利用得到的梯度,由斜率指定的直線上的每一個點在累加器唄累計,這裏斜率是從一個指定的最小值到指定的最大值的距離。同時表姐邊緣圖像中的每一個非零像素的位置。然後從二維累加器中這些點中選擇候選中心,這些中心大於給定閾值並且大於其所有近鄰。候選中心在累加器中式降序排列的,以便於最支持像素中心的首先出現。接下來對每一箇中心,考慮所有非零像素與中心的距離,選擇最支持的一條半徑。
opencv中霍夫圓檢測函數:
CvSeq * cvHoughCircles (
CvArr *image,
void * Circle_storage,
int method,
double dp,
double min_dist,
double param1 = 100,
double param2 = 300,
int min_radius = 0,
int max_radius = 0,
);
circle_strorage 可以是CV_32FC3的單列數組,三個通道分別存儲圓的位置和半徑。或者內存存儲器(memory storage),圓將變成一個序列CvSeq,由cvHoughCircle()返回一個指向這個序列的指針,同時將method 參數設爲:CV_HOUGH_GRADIENT.
dp 是累加器圖像的分辨率,如果爲1 ,則分辨率是相同的,如果設置更大的值(例如2),累加器的分辨率受此影響會變小(此情況爲一半)。dp值大於等於1.
min_dist可以區分兩個不同圓之間的最小距離。
param1,param2是邊緣閾值、累加器閾值。
實驗代碼:
#include <stdio.h>
#include <cv.h>
#include "highgui.h"
int main()
{
cvNamedWindow("grayimg",1);
//cvNamedWindow("edges",1);
cvNamedWindow("hough",1);
cvMoveWindow("grayimg",0,0);
//cvMoveWindow("edges",300,60);
cvMoveWindow("hough",30,0);
IplImage * img = cvLoadImage("e:/circle.jpg");
IplImage * gray = NULL,*edges = NULL, *circleimg = NULL;
CvSize size;
size.width = img->width;
size.height = img->height;
CvMemStorage * storage = cvCreateMemStorage(0);
CvSeq *result = 0;
gray = cvCreateImage(size,img->depth,1);
edges = cvCreateImage(size,img->depth,1);
circleimg = cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
cvCvtColor(img,gray,CV_RGB2GRAY);
//cvCanny(gray,edges,50,100,3);
cvCopy(img,circleimg);
result = cvHoughCircles(gray,storage, CV_HOUGH_GRADIENT, 2, gray->width/10 );
int index; // index 爲直線索引
for (index = 0; index < result->total; index ++)
{
float *p = (float *)cvGetSeqElem(result,index);
CvPoint pt = cvPoint(cvRound( p[0]), cvRound(p[1]));
cvCircle(circleimg, pt, cvRound(p[2]), CV_RGB(255,0,0));
}
cvShowImage("grayimg",gray);
cvShowImage("edges",edges);
cvShowImage("circleimg",circleimg);
cvWaitKey();
cvDestroyAllWindows();
cvReleaseImage( &gray );
cvReleaseImage(&img);
//cvReleaseImage( &edges );
system("pause");
return 0;
}
result: