python opencv之 Hough圓變換
阿新 • • 發佈:2018-11-11
原部落格地址:https://blog.csdn.net/tengfei461807914/article/details/77507820
https://blog.csdn.net/Tina_Wei/article/details/78202694
內容來自OpenCV-Python Tutorials 自己翻譯整理
目標:
使用霍夫變換在影象中尋找圓
使用函式cv2.HoughCircles()
原理:
圓形的表示式為(x−xcenter)2+(y−ycenter)2=r2(x−xcenter)2+(y−ycenter)2=r2,一個圓環的確定需要三個引數。那麼霍夫變換的累加器必須是三維的,但是這樣的計算效率很低。
這裡opencv中使用霍夫梯度的方法,這裡利用了邊界的梯度資訊。
首先對影象進行canny邊緣檢測,對邊緣中的每一個非0點,通過Sobel演算法計算區域性梯度。那麼計算得到的梯度方向,實際上就是圓切線的法線。三條法線即可確定一個圓心,同理在累加器中對圓心通過的法線進行累加,就得到了圓環的判定。
cv2.HoughCircles函式的引數
cv2.HoughCircles(image, method, dp, minDist, circles, param1, param2, minRadius, maxRadius)
- dp,用來檢測圓心的累加器影象的解析度於輸入影象之比的倒數,且此引數允許建立一個比輸入影象解析度低的累加器。上述文字不好理解的話,來看例子吧。例如,如果dp= 1時,累加器和輸入影象具有相同的解析度。如果dp=2,累加器便有輸入影象一半那麼大的寬度和高度。
- minDist,為霍夫變換檢測到的圓的圓心之間的最小距離,即讓我們的演算法能明顯區分的兩個不同圓之間的最小距離。這個引數如果太小的話,多個相鄰的圓可能被錯誤地檢測成了一個重合的圓。反之,這個引數設定太大的話,某些圓就不能被檢測出來了。
- param1,有預設值100。它是method設定的檢測方法的對應的引數。對當前唯一的方法霍夫梯度法,它表示傳遞給canny邊緣檢測運算元的高閾值,而低閾值為高閾值的一半。
- param2,也有預設值100。它是method設定的檢測方法的對應的引數。對當前唯一的方法霍夫梯度法,它表示在檢測階段圓心的累加器閾值。它越小的話,就可以檢測到更多根本不存在的圓,而它越大的話,能通過檢測的圓就更加接近完美的圓形了。
- minRadius,預設值0,表示圓半徑的最小值。
- maxRadius,也有預設值0,表示圓半徑的最大值。
原始碼
import cv2
import numpy as np
img = cv2.imread('image/1.jpg', 0)
img = cv2.medianBlur(img, 5)
cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 100,
param1=100, param2=30, minRadius=40, maxRadius=70)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(cimg, (i[0], i[1]), i[2], (0, 255, 0), 2)
print('圓心座標:', i[0], i[1])
print('圓半徑:', i[2])
# draw the center of the circle
cv2.circle(cimg, (i[0], i[1]), 2, (0, 0, 255), 3)
cv2.imshow('detected circles', cimg)
cv2.imwrite('image/ceshi.jpg', cimg)
cv2.waitKey(0)
cv2.destroyAllWindows()
在給一個使用攝像頭進行尋找圓 的程式碼
import cv2
import numpy as np
def circle(image):
img = cv2.medianBlur(image, 5)
cimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print('the shape of cimg: ', cimg.shape)
# circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,100,
# param1=100,param2=30,minRadius=40, maxRadius=70)
circles = cv2.HoughCircles(cimg, cv2.HOUGH_GRADIENT, 1, 100,
param1=100, param2=30, minRadius=40, maxRadius=100)
# print('circles: ', circles)
if circles is None:
return image
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
image1 = cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
print('圓心座標:', i[0], i[1])
print('圓心半徑:', i[2])
# draw the center of the circle
images = cv2.circle(image1, (i[0], i[1]), 2, (0, 0, 255), 3)
return images
if __name__ == '__main__':
cap = cv2.VideoCapture(0)
cap.set(3, 960)
cap.set(4, 960)
while(1):
# get a frame
ret, frame = cap.read()
if not ret:
print('video read error')
frame = circle(frame)
# show a frame
cv2.imshow("capture", frame)
print('hi')
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()