OpenCV 霍夫圓檢測 HoughCircles


霍夫圓變換

解釋:

霍夫圓變換的基本思路是認為圖像上每一個非零像素點都有可能是一個潛在的圓上的一點,跟霍夫線變換一樣,也是通過投票,生成累積坐標平面,設置一個累積權重來定位圓。

在笛卡爾坐標系中圓的方程為:

 

其中(a,b)是圓心,r是半徑,也可以表述為:

所以在abr組成的三維坐標系中,一個點可以唯一確定一個圓。

而在笛卡爾的xy坐標系中經過某一點的所有圓映射到abr坐標系中就是一條三維的曲線:

經過xy坐標系中所有的非零像素點的所有圓就構成了abr坐標系中很多條三維的曲線。

在xy坐標系中同一個圓上的所有點的圓方程是一樣的,它們映射到abr坐標系中的是同一個點,所以在abr坐標系中該點就應該有圓的總像素N0個曲線相交。通過判斷abr中每一點的相交(累積)數量,大於一定閾值的點就認為是圓。

以上是標准霍夫圓變換實現算法,問題是它的累加面試一個三維的空間,意味着比霍夫線變換需要更多的計算消耗。Opencv霍夫圓變換對標准霍夫圓變換做了運算上的優化。它采用的是“霍夫梯度法”。它的檢測思路是去遍歷累加所有非零點對應的圓心,對圓心進行考量。如何定位圓心呢?圓心一定是在圓上的每個點的模向量上,即在垂直於該點並且經過該點的切線的垂直線上,這些圓上的模向量的交點就是圓心。

霍夫梯度法就是要去查找這些圓心,根據該“圓心”上模向量相交數量的多少,根據閾值進行最終的判斷。


api

1 void HoughCircles( InputArray image, OutputArray circles, 2                                int method, double dp, double minDist, 3                                double param1=100, double param2=100, 4                                int minRadius=0, int maxRadius=0 );
第一個參數image是輸入圖像矩陣,要求是灰度圖像; 第二個參數 circles是一個包含檢測到的圓的信息的向量,向量內第一個元素是圓的橫坐標,第二個是縱坐標,第三個是半徑大小; 第三個參數 methodmethod是所使用的圓檢測算法,目前只有CV_HOUGH_GRADIENT一個可選; 第四個參數 dp是累加面與原始圖像相比的分辨率的反比參數,dp=2時累計面分辨率是元素圖像的一半,寬高都縮減為原來的一半,dp=1時,兩者相同。(關於這個分辨率的概念沒有理解透,按道理低分辨率應該意味着更快的檢測速度,然而實測恰恰相反) 第五個參數 minDist定義了兩個圓心之間的最小距離; 第六個參數param1是Canny邊緣檢測的高閾值,低閾值被自動置為高閾值的一半; 第七個參數param2是累加平面對是否是圓的判定閾值; 第八和第九個參數定義了檢測到的圓的半徑的最大值和最小值;

代碼演示:

 1 #include<iostream>
 2 #include<opencv2/opencv.hpp>
 3 using namespace std;  4 using namespace cv;  5 Mat src1, gray_src, src2, dst;  6 int main()  7 {  8     src1 = imread("C:\\Users\\馬迎偉\\Desktop\\yuan2.jpg");  9     if (src1.empty()) 10  { 11         cout << "could not find src1" << endl; 12         return -1; 13  } 14     //namedWindow("input", CV_WINDOW_AUTOSIZE); 15     //imshow("input", src1); 16     //霍夫圓檢測 (中值去椒鹽)濾波 --> cvtcolor轉灰度 --> Houghcircle邊緣檢測
17     medianBlur(src1,src2,3); 18  cvtColor(src2,gray_src,CV_BGR2GRAY); 19     vector<Vec3f>pcircles; 20     HoughCircles(gray_src,pcircles,CV_HOUGH_GRADIENT,1,100,200,200,100,1000,); 21  src1.copyTo(dst); 22     for (size_t i = 0; i < pcircles.size(); i++) 23  { 24         Vec3f circles = pcircles[i]; 25         circle(dst,Point(circles[0],circles[1]),circles[2],Scalar(0,0,255),1,LINE_AA); 26  } 27     imshow("output", dst); 28     waitKey(0); 29     return 0; 30 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM