霍夫變換是檢測直線或者圓的一種比較簡單的方法。霍夫變換檢測直線是比較簡單的沪袭,做完以后是一個二維平面上的許多曲線,通過統(tǒng)計平面上交點的個數(shù)樟氢,就可以得出哪些點事處于同一條直線上的冈绊。
霍夫圓變換是稍微難理解的。原理和霍夫直線變換原理大致是相同的埠啃,不過其每個點對應(yīng)的二維空間被3位空間所取代(圓心x,y以及半徑r)死宣,如果用完全相同的方法去映射的話,累加平面會被三維上的一個容器取代碴开,這樣不僅要消耗大量的內(nèi)存毅该,運算速度也很低。
opencv里是采用了一種叫做“霍夫梯度法”的方法來計算霍夫圓變換的問題潦牛。
具體算法分為以下幾個步驟:
1:邊緣檢測眶掌,這個比如opencv里霍夫變換用的是canny邊緣檢測。
2:對于邊緣圖像的非零點:考慮其局部梯度罢绽,用sobel函數(shù)來計算其梯度畏线,關(guān)注其方向。
3:利用得到的梯度良价,在梯度指定的直線上的每一個點都在累加器中被累加寝殴。
第三步是關(guān)鍵的一步,這一步的作用是找圓心明垢。比如下面這個圓是一個邊緣蚣常,我們把邊緣上的每一點的梯度方向所在直線上的點都累加(藍線)。這樣的話痊银,我們新建的累加平面和原圖的大小是一樣的(事實上opencv函數(shù)的第四個參數(shù)可以設(shè)置這個圖像的大小抵蚊,那里叫做累加器圖像的分辨率與原圖分辨率之比的倒數(shù),比如取2的話就表示累加圖分辨率是原圖分辨率的一半)溯革,這樣對于每一個邊緣點都進行操作之后贞绳,累加平面上值越大的地方就表示越可能是圓心,累加平面上值越大的地方表示了足夠多的半徑在這里相交致稀。我們把這些點作為圓心的候選點(從多至少)
4.對于每一個中心冈闭,考慮邊緣圖的每一個非零元素,按照距離遠近來排序抖单,從到最大半徑的最小半徑(這個可以手動設(shè)置萎攒,opencv里也有設(shè)置的值遇八,也可默認則在原圖中窮舉搜索)統(tǒng)計支持此中心的像素個數(shù),越多的像素落到某個半徑上耍休,則說明此處越有可能存在一個圓刃永。選擇支持像素最多的一個半徑來作為此圓心下的一個圓。
5:獲得圓心和半徑之后羊精,標(biāo)記出來即可斯够。
對于比較簡單的情況,這種方法的效率還算比較高的喧锦,但是對于復(fù)雜的圖像雳刺,漏檢率很高,效率也很低裸违,有一幅圖像跑了二十多分鐘才跑出來,而且對于參數(shù)設(shè)置也比較敏感供汛,圖像簡單時可以用下枪汪,若是比較復(fù)雜的圖像,不推薦采用這種法法怔昨。