Opencv學習筆記(十一)霍夫圓檢測

2021-10-24 04:55:51 字數 3047 閱讀 2947

霍夫圓變換的數學原理和霍夫直線變換的數學原理是一致的,都是要將要檢測的圖形從笛卡爾座標系轉換到霍夫空間。在笛卡爾座標系中某個特定的圓由三個引數(圓心座標及圓的半徑)所唯一確定:

( x−

x0)2

+(y−

y0)2

=r2(x-x_0)^2+(y-y_0)^2=r^2

(x−x0​

)2+(

y−y0

​)2=

r2如果要將其上的點轉換到霍夫空間的話,它將是乙個在以(x0

,y0,

r)(x_0,y_0,r)

(x0​,y

0​,r

)為基座標的平面的圓錐面:

即笛卡爾座標系中的乙個圓變換為了霍夫空間中的乙個點,而笛卡爾座標上某圓上的一點則變為了霍夫空間中的乙個圓錐面。在霍夫空間中:每個圓錐面代表乙個圓上的點,每個圓錐面上的點代表過該面對應笛卡爾座標系點的圓。

通過這一方式我們就可以將圓的檢測轉化為求霍夫空間中圓錐面交點的問題,通過某點的圓錐面越多,該點就越有可能對應乙個圓。

由於理論上的標準霍夫圓變換法將空間擴充套件到了三維,增加了很多的計算量,所以實際運用中我們並不採用這一方法,而是使用霍夫梯度法。霍夫梯度法的核心原理是圓上每一點的切線都過圓心,如果許多條這樣的切線交於某一點,該點就很有可能是圓心。這樣就又將圓的檢測問題轉化為了求點被多少條切線所經過的累加問題了。

其演算法實現過程如下:

對輸入的影象進行邊緣檢測;(這一步和霍夫直線檢測不同,直線檢測不自帶邊緣檢測,要求輸入影象為邊緣影象)

計算邊緣影象上每個非零點的梯度值(梯度的計算通過sobel運算元計算x,y方向一階差分求方和根實現),沿著梯度和梯度的反方向(實際在梯度的x方向分量和y方向分量上分別步進)上在minradius到maxradius的範圍內對經過的每乙個畫素,在累加器中進行累加;

對累加器中的候選圓心進行非極大抑制及閾值檢測,篩選出更有可能的圓心;

對於累加器中的每乙個候選圓心,先計算它到所有已確定圓心的距離,如果它和任意乙個已確定圓心的距離小於mindist,則捨去該圓心;然後再計算出它到邊緣圖中每乙個非零點的距離,挑選出其中最受非零點支援的距離作為待選半徑(支援的定義為:具有相同半徑的點數/該半徑最大,判斷半徑是否相同並不是直接判斷想等,而是判斷兩個距離的插值是否小於距離解析度dp),最後如果具有這一相同半徑的點數大於閾值rtesh的話,就認為找到了乙個圓心及其半徑,填入陣列;

由上述演算法介紹我們可以發現霍夫梯度法檢測圓形存在著幾個缺陷:首先由於對乙個候選圓心我們只會為其選擇乙個半徑,這樣使得當原圖中存在同心圓的時候,一般只會選出較大的圓而忽略小圓;其次由於對兩個圓圓心的距離要求不能小於mindist,容易忽略掉兩相鄰圓中的乙個。其他的缺陷則暫時無法從演算法分析中發現,可以參見參考文獻中的解釋。

opencv中給出了霍夫圓檢測的函式,其原型如下:

void

houghcircles

( inputarray image, outputarray circles,

int method,

double dp,

double mindist,

double param1 =

100,

double param2 =

100,

int minradius =0,

int maxradius =0)

;

第乙個引數為輸入影象,應該為8位單通道灰度影象,但是不再需要預先進行邊緣檢測;

第二個引數為輸出的圓陣列,通常設定為vector,以儲存(x,y,radius)資訊;

第三個引數為霍夫圓檢測的方法,實際上opencv並沒有提供更多的檢測方法,只有霍夫梯度法即hough_gradient;

第四個引數為原圖和累加器矩陣的長(寬)比值,即累加器矩陣的解析度,由於累加器矩陣實際上只是為了儲存待定圓心的,所以並不要求和原圖相同大小,但在程式中由於它牽扯到了最支援半徑的判定,所以該值越大,實際檢測出來的圓(可能非圓)會越多;

第五個引數為兩個圓圓心所能容忍的最小距離,該值越小可以檢測出越多的圓,但同時誤判的概率也會越高;

第六個引數為程式執行中canny邊緣檢測的高閾值,低閾值預設為高閾值的一半;

第七個引數為判斷某點是否為圓心時的閾值,該值越小可以檢測出越多的圓(可能非圓);

第八、九個引數為檢測出的圓半徑範圍,規定了其最小值和最大值;

示例**如下:

int

main()

cvtcolor

(src, gray, color_bgr2gray)

;//轉化邊緣檢測後的圖為灰度圖

gaussianblur

(gray,gray ,

size(9

,9),

2,2)

;houghcircles

(gray, rounds, hough_gradient,

1.5,50,

115,

100)

;//倒數第三個引數為圓心間最小距離,有助於檢測相鄰圓,倒數第二個為canny邊緣檢測時的高閾值

//倒數第乙個為圓心的累加器閾值,越小檢測出的圓越多

for(size_t i =

0;i < rounds.

size()

; i++

)imshow

("效果圖"

, src)

;waitkey(0);}

參考文獻opencv —— houghcircles 霍夫圓變換原理及圓檢測

opencv2.4.9原始碼分析——houghcircles

opencv霍夫變換系列(中篇)-霍夫圓變換

opencv 霍夫圓變換

參考 1 官方文件api 2 d6 d00 tutorial py root.html 官方英文教程 3 4 高階教程 5 官方英文教程 6 7 8 opencv論壇 9 官方github 10 注 安裝的版本 opencv python 3.3.0 cp36 cp36m win amd64.whl...

OpenCV 霍夫線變換 霍夫圓變換

關於霍夫變換在官方文件opencv249裡的描述如下 api如下 void houghlines inputarray image,outputarray lines,double rho,double theta,int threshold,double srn 0,double stn 0 vo...

OpenCV學習筆記(九)之霍夫圓檢測

老規矩 妹妹鎮樓 基於效率考慮,opencv中實現的霍夫變換圓檢測是基於影象梯度的實現,分為兩步 檢測邊緣,發現可能的圓心 在第一步的基礎上從候選圓心開始計算最佳半徑大小。cv houghcircles api分析 cv houghcircles inputarray image,輸入影象,必須是8...