天天看點

【OpenCv 4 Python 3.7】圓檢測

圓檢測技術:

圓檢測技術目前用處還是特别的廣泛的,鍋爐、管道等類似的情況,我們不能切開或者打孔去測試流量,溫度等參數。這是我們可以在管道上畫一個圓,用錄影機去檢測圓中心,進而測試出我們需要的資訊。

對于一個圓,就需要用三個參數來确定。使用Hough梯度法的依據是圓心一定出現在圓上的每個點的模向量上,圓上點的模向量的交點就是圓心的所在位置。Hough梯度法的第一步就是找到這些圓心,這樣三維的累加平面就轉化為二維累加平面。第二步就是根據所有候選中心的邊緣非零像素對其的支援程度來确定半徑。

【OpenCv 4 Python 3.7】圓檢測

 從平面坐标到極坐标轉換三個參數C(x0 , y0 , r)其中x0 , y0是圓心

 假設平面坐标的任意一個圓上的點,轉換到極坐标中:C(x0 ,y0 , r)處有最大值,霍夫變換正是利用這個原理實作圓的檢測。

現實考量:

 因為霍夫圓檢測對噪聲比較敏感,是以首先要對圖

像做中值濾波。

 基于效率考慮,Opencv中實作的霍夫變換圓檢測

是基于圖像梯度的實作,分為兩步:

  1. 檢測邊緣,發現可能的圓心
  2. 基于第一步的基礎上從候選圓心開始計算最佳半

    徑大小

HoughCircles 函數參數:

1.image:輸入圖像 (灰階圖)

2.method:指定檢測方法. 現在OpenCV中隻有霍夫梯度法

3.dp:累加器圖像的反比分辨=1即可預設

4.minDist = src_gray.rows/8: 檢測到圓心之間的最小距離,這是一個經驗值。這個大了,那麼多個圓就是被認為一個圓。

5.param_1 = 200: Canny邊緣函數的高門檻值

6.param_2 = 100: 圓心檢測門檻值.根據你的圖像中的圓大小設定,當這張圖檔中的圓越小,那麼此值就設定應該被設定越小。當設定的越小,那麼檢測出的圓越多,在檢測較大的圓時則會産生很多噪聲。是以要根據檢測圓的大小變化。

7.min_radius = 0: 能檢測到的最小圓半徑, 預設為0.

8.max_radius = 0: 能檢測到的最大圓半徑, 預設為0

代碼實作:

import cv2 as cv
import numpy as np

#圓檢測
def detect_circles_demo(image):
    # 高斯雙邊模糊,不太好調節,霍夫噪聲敏感,是以要先消除噪聲
    # dst = cv.bilateralFilter(image, 0, 150, 5)

    # 使用高斯模糊,修改卷積核ksize也可以檢測出來
    #dst = cv.GaussianBlur(image, (13, 15), 15)

    #均值遷移,EPT邊緣保留濾波,霍夫噪聲敏感,是以要先消除噪聲
    dst = cv.pyrMeanShiftFiltering(image, 10, 100)
    cimage = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)
    #cv.HOUGH_GRADIENT 基于梯度
    circles = cv.HoughCircles(cimage, cv.HOUGH_GRADIENT, 1, 20, param1=50, param2=30, minRadius=0, maxRadius=0)
    # around對資料四舍五入,為整數
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]
        #畫圓
        cv.circle(image, (i[0], i[1]), i[2], (0, 0, 255), 2)#2;線寬
        #畫圓心
        cv.circle(image, (i[0], i[1]), 2, (255, 0, 0), 2)
    cv.imshow("circles", image)


print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("D:/vcprojects/images/xingxing.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
detect_circles_demo(src)
cv.waitKey(0)

cv.destroyAllWindows()
           

結果:

【OpenCv 4 Python 3.7】圓檢測