1. 程式人生 > >python opencv之 Hough圓變換

python opencv之 Hough圓變換

原部落格地址: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()