opencv內部提供了乙個基於hough變換理論的找圓演算法,houghcircle與一般的擬合圓演算法比起來,各有優勢:優勢:houghcircle對雜訊點不怎麼敏感,並且可以在同乙個圖中找出多個圓;反觀擬合圓演算法,單純的擬合結果容易受雜訊點的影響,且不支援乙個輸入中找多個圓
opencv內的houghcircles對基礎的hough變換找圓做了一定的優化來提高速度,它不再是在引數空間畫出乙個完整的圓來進行投票,而只是計算輪廓點處的梯度向量,然後根據搜尋的半徑r在該梯度方向距離輪廓點距離r的兩邊各投一點,最後根據投票結果圖確定圓心位置,其示意圖如圖1
不過在這種思想優化下,也存在致命的缺陷,如圖2:
實際情況是該點算出的梯度方向其實總是有誤差的,有時因為影象原因或結構原因,偏差甚至超過30度;圖2中由於梯度方向不精確,7點基本沒有獲得投票,反而不如abc點。因此實際使用中houghcircle的效果並沒有想象中的理想,情況往往如下列所述:
(參與投票的輪廓點如圖3的右圖,噪點非常多,比想要查詢的輪廓本身還多,而且斷斷續續的,顯然這種情況擬合法不適用)
1、半徑範圍限定不好時,如圖3,可能找到的圓非常多且雜亂無章
2、在此情況下,如果只輸出乙個圓(opencv的houghcircle會預設按照投票結果的累加值排序
),最好的圓是這樣的,竟然差這麼多
3、假設我們找的東西的半徑我們是知道的,變化不大(+-8%),現在限定下半徑
。。。找出的排的靠前的圓是這樣的;再看下預設最好的圓。。。
4、常規來說,使用該函式的時候,為避免找到太多的幾乎重合的圓,找圓的最小距離都設在乙個比較合理的值(比如大於半徑1/5),這樣在找多個圓的時候,就不會找出太多重合的圓了;不過這裡我試下
不限制最小距離,如下
,預設排序下得分最高的幾個圓如左圖:
很多初次使用該函式的看到這,或許就就覺得houghcircles效果不咋地。。。本人剛開始使用時也感覺opencv提供的這個演算法太不穩定了,只能對某乙個圖調出相對好一點的效果,換乙個圖或者只改動其中某乙個引數,找出來的圓就不知道跑哪去了,而且變化太大了。。。
觀察細心的可能發現了,第4步中的左圖找出的眾多圓其實已經比前面找出的圓靠譜很多了,而且這麼多圓必定有乙個圓就是我想要找的圓,只是按照投票分數排序下,最好的圓偏差較大。
但究其演算法優化本身,輪廓梯度定位出來的圓心投票本來精度就低(如圖2),自然找出來的圓會有很多是錯誤的,但如果輪廓點足夠多,找出的正確的圓必定也是存在的,只是按照票數方法來評價可能排序會比較靠後,但畢竟也是出現了的;此處只需做個小小的優化,改下評價方法,優化下排序,結果就很接近了
找出來的圓中與實際輪廓重合度最高的圓一般就是我們要找的圓;因此我們可以通過houghcircles來找出一批差不多的圓(如步驟4),然後畫出這些圓,和實際輪廓比對一下,按實際重合畫素的總數排序,這時分數最高的圓就如上面的結果圖!houghcircles優化一下還是很給力的!
參考:
霍夫檢測圓 霍夫梯度法
承接上篇博文,在基本搞懂霍夫檢測直線是怎麼進化到檢測圓後,開始 痴心妄想 自己寫 了!雖說最後的效果不是很好,但是重要的是在碼 過程中發現和解決的一些問題 不一定有共性,但兄弟萌可以避免下這些bug 上篇博文已經闡述了我們是如何從三維計數 轉到霍夫梯度法的,該演算法主要分為兩步,先找圓心疑似點,再對...
霍夫梯度法找圓
opencv內部提供了乙個基於hough變換理論的找圓演算法,houghcircle與一般的擬合圓演算法比起來,各有優勢 優勢 houghcircle對雜訊點不怎麼敏感,並且可以在同乙個圖中找出多個圓 反觀擬合圓演算法,單純的擬合結果容易受雜訊點的影響,且不支援乙個輸入中找多個圓 opencv內的h...
OpenCV霍夫梯度找圓演算法
opencv使用霍夫梯度演算法檢測影象中的圓。演算法步驟如下 尋找圓心 用canny演算法進行邊緣檢測,得到邊界二值圖 用sobel運算元計算原圖的梯度 遍歷邊緣二值圖中的非0點,沿著梯度方向和反方向畫線段 梯度方向為圓弧的法線方向,即半徑方向 線段的起點和長度由引數允許的半徑區間決定。將線段經過的...