在上篇的博文中,我們重點討論了霍夫變換的線段檢測的數學原理,以及怎樣在OpenCV中去實現線段的檢測。在這篇博文中,關於圓的檢測的數學理論,我們不做重點介紹。我們將簡要介紹下OpenCV中自帶的基於霍夫變換的圓檢測函數cvHoughCircles()。
CvSeq* cvHoughCircles(
CvArr* image,//8位的圖像,不過不需要是二值圖像,可以是灰度圖
void* circle_storage,//存儲結果的存儲器
int method,//這個參數必須設置爲CV_HOUGH_GRADIENT
double dp,//累加器圖像的分辨率,可設置爲1或2,但是不能比1小
double min_dist,//讓算法能明顯區分的兩個不同圓之間的最小距離
double param1=100,//邊緣閾值
double param2=300,//累加器閾值
int min_radius=0,
int max_radius=0//發現圓半徑的最小值和最大值
)
下面給出個程序的示例:
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
int main()
{
const char *pSrcWindow = "原圖";
const char *pDstWindow = "Hough圓檢測圖";
IplImage *pSrcImage = cvLoadImage("1.png", CV_LOAD_IMAGE_UNCHANGED);
IplImage *pGrayImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 1);
//轉化爲灰度圖
cvCvtColor(pSrcImage, pGrayImage, CV_BGR2GRAY);
//構建個存儲器,爲後面的函數cvHoughCircles()傳參
CvMemStorage *circle_storage = cvCreateMemStorage();
double min_dst = pGrayImage->height / 10;
//調用cvHoughCircles()函數,函數返回的是個序列
CvSeq* results = cvHoughCircles(pGrayImage, circle_storage, CV_HOUGH_GRADIENT, 1, min_dst);
IplImage *pColorImage = cvCreateImage(cvGetSize(pSrcImage), IPL_DEPTH_8U, 3);
cvCvtColor(pGrayImage, pColorImage, CV_GRAY2BGR);
//將函數cvHoughCircles()檢測得到的結果,遍歷輸出,並且畫圖
for (int i = 0; i < results->total; ++i)
{
float *p = (float*)cvGetSeqElem(results, i);
cvCircle(pColorImage, cvPoint(cvRound(p[0]), cvRound(p[1])), cvRound(p[2]), CV_RGB(255, 0, 0), 2);
}
cvNamedWindow(pSrcWindow, CV_WINDOW_AUTOSIZE);
cvNamedWindow(pDstWindow, CV_WINDOW_AUTOSIZE);
cvShowImage(pSrcWindow, pSrcImage);
cvShowImage(pDstWindow, pColorImage);
cvWaitKey();
cvReleaseImage(&pSrcImage);
cvReleaseImage(&pGrayImage);
cvReleaseImage(&pColorImage);
cvReleaseMemStorage(&circle_storage);
cvDestroyWindow(pSrcWindow);
cvDestroyWindow(pDstWindow);
return 0;
}