我們用和霍夫直線偵測同樣的概念,進行霍夫圓形偵測,圓方程式為(x-a)2 + (y-b)2 = r2,其中(a,b)為圓心座標,r為圓的半徑,用這個三維數據組,讓(a,b)在影像座標內不斷改變位置,找出所有可能的半徑r,最後當這三維數據組的點數,超過我們定的閾值時就判斷為圓。
因為傳統的霍夫圓偵測是三維空間上的計數,基於效率上的考量,而且維度變多,精確定位局部峰值變得困難,OpenCV的霍夫圓偵測使用以下兩個步驟:
- 圓周上點的梯度指向圓心位置,對於每個點,只有沿著梯度方向才增加計數,而範圍為預定的半徑最大與最小值,超過閾值即判斷此點為圓心。
- 對圓心和點的距離進行計數,最大值就是此圓的半徑。
OpenCV 偵測圓
void HoughCircles(InputArray image, OutputArray circles, int method, double dp, double minDist, double param1=100, doubleparam2=100, int minRadius=0, int maxRadius=0)
- image:輸入圖,8位元單通道圖。
- circles:以vector< Vec3f >記錄所有圓的資訊,每個Vec3f紀錄一個圓的資訊,包含3個浮點數資料,分別表示x、y、radius。
- method:偵測圓的方法,目前只能使用CV_HOUGH_GRADIENT。
- dp:偵測解析度倒數比例,假設dp=1,偵測圖和輸入圖尺寸相同,假設dp=2,偵測圖長和寬皆為輸入圖的一半。
- minDist:圓彼此間的最短距離,太小的話可能會把鄰近的幾個圓視為一個,太大的話可能會錯過某些圓。
- param1:圓偵測內部會呼叫Canny()尋找邊界,param1就是Canny()的高閾值,低閾值自動設為此值的一半。
- param2:計數閾值,超過此值的圓才會存入circles。
- minRadius:最小的圓半徑。
- maxRadius:最大的圓半徑。
以下我們示範如何HoughCircles()找影像中的圓,並用自行撰寫的drawCircle()將找到的圓畫出: