霍夫檢測圓:霍夫梯度法
承接上篇博文,在基本搞懂霍夫檢測直線是怎麼進化到檢測圓後,開始(痴心妄想)自己寫程式碼了!雖說最後的效果不是很好,但是重要的是在碼程式碼過程中發現和解決的一些問題(不一定有共性,但兄弟萌可以避免下這些bug)。
霍夫梯度法
演算法步驟
上篇博文已經闡述了我們是如何從三維計數表格轉到霍夫梯度法的,該演算法主要分為兩步,先找圓心疑似點,再對疑似點進行半徑確定:
假設已經得到影像的邊緣資訊(包含角度和梯度值)
1.利用邊緣點的梯度資訊,沿著梯度方向畫線,將將線段經過的所有累加器中的點(a,b)的Hough(h,w)+=1。
此步原理是:圓上的點沿著梯度方向畫線,這些線會交於圓心。
2.統計排序霍夫累加器中的投票時,得票是越高,說明更多得邊緣梯度線經過該點,是圓心的可能性就更大。
3.針對某個圓心計算所有邊緣點到其的距離,認為頻數較大的距離為可能半徑值。(個人的簡化做法)
問題
1.如何沿著邊緣點的梯度方向畫線?
博主採用的斜截式來表示梯度線(即為邊緣的法線),首先我們獲得的梯度方向角為:
theta = np.arctan2(I2,(I1+0.0000000000001))*180/np.pi
帶著這個賊小的數是為了不出現分母為零的情況!這裡排除了k=inf的情況,但是還是會出現k值比較大的情況,為了畫線方便做了這樣一步操作:
#篩選k值(即把小於0.05或者超過50的k值剔除)
index = []
for i in range(len(k)):
if abs(k[i])<0.05 or abs(k[i])>50:
index.append(i)
new_k = np.delete(k,index)
new_location = np.delete(location,index,axis=0)
在影像中畫直線時其經過的不是質點而是畫素點(有物理長寬),所以本文先求取了各個邊緣點梯度線的k和b值,因此經過邊緣點(x0,y0)的直線可表示為:y0=k*x0+b,以一個畫素為單位不斷增加x值,利用直線方程求取對應的y值,以此來求得直線經過的所有畫素點。
2.對k值進行分類處理
第一問已經剔除了難以利用的k值及其對應的邊緣點座標,接下來要對k值進行分類。由第一問已經知道博文求取梯度線經過的畫素點的方法是步進法(自己胡謅的名字),會出現一個新的問題,是在x軸上步進好還是在y軸上步進好呢?這就是為什麼要對k值進行一個分類。
當k的絕對值小於1時,意味著每增加一個畫素值,y的增加(或減少)不超過一個畫素值,是可以遍歷該直線經過的所有畫素的。但如果是增加y值,那麼x會增加幾個畫素值,這樣會跳過好幾畫素塊,故博主將k小於1的分出來,對於分出來的邊緣點,進行x軸上的遞進。(本處偷了懶~其實按照原理也可以對k=0或k=inf的邊緣點進行操作的)
3.在尋找一些需要注意的問題:
博主初步畫梯度直線時,針對的是canny識別出來的邊緣進行操作的,但是識別的圓心不準。改為對梯度幅值不為零的所有畫素點畫梯度方向直線後發現效果好了很多,即從上面的程式碼改為下面的:
location = np.argwhere(edge==255)
location = np.argwhere(G)
對比:
4.半徑求取的辦法:
博主用了最簡單的思路,求取所有的邊緣點到可能圓心的距離,認為半徑值是距離的眾數字。
d = np.sqrt((location[:,0]-h[0])**2+(location[:,1]-w[0])**2)
d = d.astype(int)
c = []
for i in d:
if i not in c:
c.append(i)
#進行統計,生成二維列表
a = {}
for i in d:
if i in a:
a[i] = a[i] + 1
else:
a[i] = 1
# 使用sorted對字典進行排序
b = sorted(a.items(),key=lambda item:item[1],reverse=True)
r = b[0][0]
最後效果圖:
可以看到其實最後的結果不太理想,反思問題可能是中間只對k值小於一的邊緣點進行了處理,而且在演算法中我直接認定投票值最多的畫素點為圓心,沒有進行下一步處理,在獲取半徑時候也只是簡單取了眾數,總而言之還有很多紕漏沒解決啦~僅作參考哈,多有不足望大家指出。
相關文章
- 霍夫變換檢測圓
- 霍夫變換圓檢測原理及 OpenCV API 應用OpenCVAPI
- 【OpenCV】影像變換(四-2)霍夫變換圓檢測OpenCV
- 計算機視覺 OpenCV Android | 基本特徵檢測之 霍夫圓檢計算機視覺OpenCVAndroid特徵
- 【OpenCV】影像變換(四-1)-霍夫變換線段檢測OpenCV
- OpenCvSharp手繪ROI區域+模板匹配+霍夫變換檢測圓的邊界OpenCV
- 關於霍夫找圓演算法cvHoughCircles的引數演算法
- 霍夫斯坦德的國家文化模型(轉載)模型
- 用霍夫變換&SCNN碼一個車道追蹤器CNN
- OpenCV-Python教程(9)(10)(11): 使用霍夫變換檢測直線 直方圖均衡化 輪廓檢測OpenCVPython直方圖
- 軟體開發定律:霍夫施塔特定律,為什麼專案交付總是會延期?
- 霍納規則(C/C++,Scheme)C++Scheme
- 漢斯·霍萊因:萬物皆建築
- 約瑟夫環遊戲遊戲
- 哈夫曼樹
- [網路文摘] 霍小柏-因為你是男人
- Markov Model 馬可夫模型 & Hidden Markov Model 隱馬可夫模型模型
- 約瑟夫環(超好的程式碼存檔)--19--約瑟夫環--LeetCode面試題62(圓圈最後剩下的數字)LeetCode面試題
- 《什麼是高爾夫?》:萬物皆可高爾夫的瘋狂遊戲遊戲
- 資料結構與演算法——赫夫曼樹(哈夫曼樹)資料結構演算法
- 【筆記】哈夫曼樹筆記
- 約瑟夫問題pascal程式
- 隱馬爾可夫模型隱馬爾可夫模型
- 約瑟夫出圈演算法演算法
- Go 武林外傳 - 一夫當關萬夫莫開之 Micro API GatewayGoAPIGateway
- 霍炬:程式設計師愛寫指令碼是種病程式設計師指令碼
- 約瑟夫環(vector類解決)
- 約瑟夫環(陣列實現)陣列
- MCMC(二)馬爾科夫鏈馬爾科夫
- HMM隱馬爾可夫模型HMM隱馬爾可夫模型
- 【HMM】隱馬爾科夫模型HMM馬爾科夫模型
- Java 樹結構實際應用 二(哈夫曼樹和哈夫曼編碼)Java
- SmartGolfBall智慧高爾夫球:這是顆能當教練的高爾夫球Go
- 2022-05-17-馬爾科夫鏈之傳統馬爾可夫鏈馬爾科夫馬爾可夫
- 簡單前端——圓與圓碰撞檢測前端
- 隱馬爾可夫模型詳解隱馬爾可夫模型
- 10_隱馬爾可夫模型隱馬爾可夫模型
- ML-隱馬爾可夫模型隱馬爾可夫模型