iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
自我挑戰組

數位影像處理系列 第 22

[Day 22]直線與圓形偵測

  • 分享至 

  • xImage
  •  

今天繼續討論直線偵測與圓形偵測技術


1.直線偵測

直線偵測(Line Detection)的技術,目標為偵測影像中的直線,簡單明瞭。最典型的直線偵測技術,稱為 **霍夫轉換(Hough Transform)**。

霍夫轉換是一種特徵擷取技術,主要是將數位影像的空間座標經過轉換成參數空間,這個參數空間稱為霍夫域(Hough Doamin)。由於霍夫轉換適合用來辨識物件的幾何特徵,例如:直線、圓形等,被廣泛應用於影像處理、影像分析與電腦視覺應用。

霍夫轉換直線偵測的演算法步驟如下:
(1) 使用邊緣偵測器偵測影像物件的邊緣
(2) 定義

https://ithelp.ithome.com.tw/upload/images/20220929/20152370dm0N0Pm0Wz.png,D為影像的最大距離
(3) 建立累積器,用來儲存(ρ,θ)參數空間的量化值。
(4) 根據每個邊緣點,計算(ρ,θ)值,並於累積器中進行累加
(5) 累積器的局部最大值,即是對應偵測直線的(ρ,θ)值

程式碼如下:
import numpy as np
import cv2
import math

img1 = cv2.imread("D:\Desktop\IThome\line.bmp", -1)
img2 = img1.copy()
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 200)
lines = cv2.HoughLines(edges, 1, math.pi / 180.0, 120)

if lines is not None:
    a, b, c = lines.shape
    for i in range(a):
        rho = lines[i][0][0]
        theta = lines[i][0][1]
        a = math.cos(theta)
        b = math.sin(theta)
        x0, y0 = a * rho, b * rho
        pt1 = (int(x0 + 1000 * (-b)), int(y0 + 1000 * a))
        pt2 = (int(x0 - 1000 * (-b)), int(y0 - 1000 * a))
        cv2.line(img2, pt1, pt2, (255, 0, 0), 1, cv2.LINE_AA)

cv2.imshow("Original", img1)
cv2.imshow("Canny", edges)
cv2.imshow("After", img2)
cv2.waitKey()
cv2.destroyAllWindows()

在此,採用Canny邊緣偵測用來偵測可能的邊緣點。霍夫轉換後,需決定局部最大值的門檻值(本範例門檻設為120,表示值線長度須超過120個像素)。

結果如下:
https://ithelp.ithome.com.tw/upload/images/20220929/20152370CXKgyY2IEa.png


2.圓形偵測

除了直線偵測外,霍夫轉和可以用來偵測數位影像中的圓形物件,稱為 **圓形偵測(Circle Detection)**。

根據圓的方程式:

https://chart.googleapis.com/chart?cht=tx&chl=(x-x_0)%5E2%20%2B%20(y-y_0)%5E2%20%3D%20r%5E2
其中https://chart.googleapis.com/chart?cht=tx&chl=(x_0%2Cy_0)為圓心座標,r為半徑。因此我們可以使用這三個參數作為霍夫域建立累積器,原理與上面的直線偵測類似。然而這樣的累積器所需要的記憶體空間較大,而且搜尋的空間相當大,因此並不實用。

OpenCV提供圓偵測演算法,在效率上進行改良,稱為霍夫梯度法(Hough Gradient Method)。
程式碼如下:
import numpy as np
import cv2
import math

img1 = cv2.imread("D:\Desktop\IThome\circle3.bmp", -1)
img2 = img1.copy()
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 150 ,200, 50,
                            minRadius = 120, maxRadius = 200)
circles = np.uint16(np.around(circles))
if circles is not None and circles[0][0].ndim == 1:
    for i in circles[0, :]:
        cv2.circle(img2, (i[0], i[1]), i[2], (0, 255, 0), 2)
        cv2.circle(img2, (i[0], i[1]), 2, (0, 0, 255), 3)

cv2.imshow("Original", img1)
cv2.imshow("After", img2)
cv2.waitKey()
cv2.destroyAllWindows()

在本程式中,霍夫圓偵測是使用Canny邊緣偵測法。在此,根據數位影像設定圓的最小半徑與最大半徑,分別為120與200。
結果如下:
https://ithelp.ithome.com.tw/upload/images/20220929/20152370h1T9J71iHk.png
https://ithelp.ithome.com.tw/upload/images/20220929/20152370UGJ5U3tgPN.png


上一篇
[Day 21]影像分割-邊緣偵測
下一篇
[Day 23]閥值化、分水嶺與GrabCut
系列文
數位影像處理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言