【OpenCV】影像變換(四-2)霍夫變換圓檢測

王大偉啊發表於2015-04-27

在上篇的博文中,我們重點討論了霍夫變換的線段檢測的數學原理,以及怎樣在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;
}

相關文章