參考文章:https://blog.csdn.net/dcrmg/article/details/52506538
https://blog.csdn.net/zhaocj/article/details/50454847 (有用!!)
霍夫圓變換的基本思路是認為圖像上每一個非零像素點都有可能是一個潛在的圓上的一點,
跟霍夫線變換一樣,也是通過投票,生成累積坐標平面,設置一個累積權重來定位圓。
在笛卡爾坐標系中圓的方程為:
其中(a,b)是圓心,r是半徑,也可以表述為:
即
在笛卡爾的xy坐標系中經過某一點的所有圓映射到abr坐標系中就是一條三維的曲線:
經過xy坐標系中所有的非零像素點的所有圓就構成了abr坐標系中很多條三維的曲線。
在xy坐標系中同一個圓上的所有點的圓方程是一樣的,它們映射到abr坐標系中的是同一個點,所以在abr坐標系中該點就應該有圓的總像素N0個曲線相交。
通過判斷abr中每一點的相交(累積)數量,大於一定閾值的點就認為是圓。
以上是標准霍夫圓變換實現算法。
問題是它的累加到一個三維的空間,意味着比霍夫線變換需要更多的計算消耗。
Opencv霍夫圓變換對標准霍夫圓變換做了運算上的優化。
它采用的是“霍夫梯度法”。它的檢測思路是去遍歷累加所有非零點對應的圓心,對圓心進行考量。
如何定位圓心呢?圓心一定是在圓上的每個點的模向量上,即在垂直於該點並且經過該點的切線的垂直線上,這些圓上的模向量的交點就是圓心。
霍夫梯度法就是要去查找這些圓心,根據該“圓心”上模向量相交數量的多少,根據閾值進行最終的判斷。
bilibili:
代碼實現:
import cv2 as cv
import numpy as np
planets = cv.imread("planet_glow.jpg")
gay_img = cv.cvtColor(planets, cv.COLOR_BGRA2GRAY)
img = cv.medianBlur(gay_img, 7) # 進行中值模糊,去噪點
cimg = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT, 1, 50, param1=100, param2=30, minRadius=0, maxRadius=0)
circles = np.uint16(np.around(circles))
print(circles)
for i in circles[0, :]: # 遍歷矩陣每一行的數據
cv.circle(planets, (i[0], i[1]), i[2], (0, 255, 0), 2)
cv.circle(planets, (i[0], i[1]), 2, (0, 0, 255), 3)
cv.imshow("gay_img", planets)
cv.waitKey(0)
cv.destroyAllWindows()