霍夫檢測圓:霍夫梯度法
承接上篇博文,在基本搞懂霍夫檢測直線是怎麼進化到檢測圓後,開始(痴心妄想)自己寫程式碼了!雖說最後的效果不是很好,但是重要的是在碼程式碼過程中發現和解決的一些問題(不一定有共性,但兄弟萌可以避免下這些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 Android | 基本特徵檢測之 霍夫圓檢計算機視覺OpenCVAndroid特徵
- OpenCvSharp手繪ROI區域+模板匹配+霍夫變換檢測圓的邊界OpenCV
- 用霍夫變換&SCNN碼一個車道追蹤器CNN
- 霍納法則
- 軟體開發定律:霍夫施塔特定律,為什麼專案交付總是會延期?
- 農夫漁夫
- 霍格沃茨
- 哈夫曼樹
- 關於量子霍爾效應與你
- 高爾夫禮儀
- 約瑟夫問題
- 哈夫曼編碼
- 漢斯·霍萊因:萬物皆建築
- 約瑟夫環(約瑟夫問題)求最後出列的人數
- 模擬高爾夫快速發展,揮杆高爾夫模擬器讓普通人加入高爾夫運動
- 資料結構與演算法——赫夫曼樹(哈夫曼樹)資料結構演算法
- 隨時隨地體驗快節奏高爾夫對決,《決戰高爾夫》內測正式啟動!
- 約瑟夫環(超好的程式碼存檔)--19--約瑟夫環--LeetCode面試題62(圓圈最後剩下的數字)LeetCode面試題
- 有趣的赫夫曼樹
- 約瑟夫環遊戲遊戲
- 約瑟夫環問題
- Hopfield Network 霍普菲爾德網路入門
- 穀粒joycon霍爾電磁搖桿釋出
- 2022-05-17-馬爾科夫鏈之傳統馬爾可夫鏈馬爾科夫馬爾可夫
- 《什麼是高爾夫?》:萬物皆可高爾夫的瘋狂遊戲遊戲
- Go 武林外傳 - 一夫當關萬夫莫開之 Micro API GatewayGoAPIGateway
- 笨辦法學C 練習23:認識達夫裝置
- PAT-B 1037 在霍格沃茨找零錢
- 《霍格沃茨之遺》關卡設計淺析
- 全方位的測試解決方案服務商——霍格沃茲測試開發學社
- 再見,平井一夫!
- 哈夫曼樹及其編碼
- Java 樹結構實際應用 二(哈夫曼樹和哈夫曼編碼)Java
- 來自塔科夫的愛:專訪《逃離塔科夫》出品方BSG工作室
- ML-隱馬爾可夫模型隱馬爾可夫模型
- 巴什博奕和威佐夫博弈