iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
自我挑戰組

數位影像處理系列 第 21

[Day 21]影像分割-邊緣偵測

  • 分享至 

  • xImage
  •  
數位影像處理的目的,通常是希望在影像中偵測某些感興趣的目標物件。然而,數位影像是由許多像素所構成,因此需事先定義像素的某些特性,例如:灰階、色彩等相似性,藉以擷取具有意義的影像物件相關資訊。

影像分割(Image Segmentation)可以定義為:「將數位影像分析具有意義的邊緣、直線、圓形或區域等相關資訊,以便更進一步的分析影像與辨識。」

因此在數位影像處理領域中,影像分割技術是一項重要技術,通常可以根據偵測的目標進行分為,例如: 邊緣偵測(Edge Detecion)、直線偵測(Line Detection)、圓形偵測(Circle Detection)、以區域為基礎的分割技術(Region-based Segmentation)等。

1.Sobel邊緣偵測

邊緣檢測顧名思義,目的是偵測影像中的物件邊緣,採用的方法是基於像素灰階的局部(或突然)變化。因此,最典型的邊緣偵測技術,通常是使用微積分的 **一階導函數(First-order Derivatives)** 進行影像濾波,求 **影像梯度(Image Gradients)**,再透過 **閥值化(Thresholding)** 的過程,選取影像梯度較大者,形成邊緣偵測的結果。

最簡單的邊緣檢測技術,就是Sobel濾波器。Sobel邊緣偵測演算法說明如下:
(1) 首先,輸入灰階影像f(x, y)。
(2) 使用Sobel濾波器求影像梯度與大小:

https://ithelp.ithome.com.tw/upload/images/20220928/20152370sUOIrj6FuZ.png
https://ithelp.ithome.com.tw/upload/images/20220928/20152370qmatk1nYOX.png
(3) 選取閥值(Threshold)T:
https://ithelp.ithome.com.tw/upload/images/20220928/20152370BYD6WYoBLe.png

Sobel邊緣檢測的程式碼如下:

import numpy as np
import cv2

def Sobel_edge_detection(f):
    grad_x = cv2.Sobel(f, cv2.CV_32F, 1, 0, ksize = 3)
    grad_y = cv2.Sobel(f, cv2.CV_32F, 0, 1, ksize = 3)
    magnitude = abs(grad_x) + abs(grad_y)
    g = np.uint8(np.clip(magnitude, 0, 255))
    ret, g = cv2.threshold(g, 127, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

    return g

def main():
    img1 = cv2.imread("D:\Desktop\IThome\lena.bmp", -1)
    img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    img2 = Sobel_edge_detection(img1)
    cv2.imshow("Original", img1)
    cv2.imshow("After", img2)
    cv2.waitKey()
    cv2.destroyAllWindows()

main()

上述範例中,輸入的影像為灰階影像,使用OpenCV的Sobel函式求影像梯度,並採用Threshold函式求邊緣偵測的結果影像,其中套用OTSU演算法,可以自動選取最佳的閥值。

成果如下:
https://ithelp.ithome.com.tw/upload/images/20220928/20152370nZ4HOxGT0r.png
邊緣偵測的結果影像僅含0、1,稱為二值影像(Binary Image)。Sobel可以有效偵測影像物件邊緣,缺點是邊緣的寬可能同時涉及許多像素,形成較厚的邊緣。


2.Canny邊緣偵測

Canny邊緣偵測目前已成為具有代表性的State-of-Art邊緣偵測技術。由John F.Canny於1986年提出。Canny針對邊緣偵測技術,規範最佳化的邊緣偵測演算法,其目標應包含以下幾點:
  • 好的偵測(Good Detection):演算法應盡可能偵測影像中所有的實際邊緣,產生的錯誤率低。

  • 好的定位(Good Localization):演算法所偵測的邊緣,應盡可能接近實際的邊緣。

  • 單一響應(Single Edge Response):演算法在實際的邊緣上,應僅回傳單一的點(或像素)。

    Canny根據以上的設計目標,發現並證明最佳的 步階邊緣偵測器(Step Edge Detector) 是使用高斯函數的一階導函數。Canny偵測演算法的步驟簡述如下:
    (1) 使用高斯濾波器進行平滑濾波。
    (2) 使用高斯函數的一階導函數計算影像梯度。
    (3) 套用非最大值抑制(Nonmaxima Suppression)技術於影像梯度影像,用來選取單一邊緣點。
    (4) 使用磁帶閥值(Hysteresis Thresholding)技術,其中牽涉兩個閥值,分別為Low Threshold與High Threshold,用來連接邊緣。

    程式碼如下:


import numpy as np
import cv2

img1 = cv2.imread("D:\Desktop\IThome\lena.bmp", -1)
img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img2 = cv2.Canny(img1, 50, 100)
cv2.imshow("Original", img1)
cv2.imshow("After", img2)
cv2.waitKey()
cv2.destroyAllWindows()

在上述程式中,使用OpenCV的Canny函式進行邊緣偵測。Canny函式的輸入參數及是磁帶閥值中的閥值,可自行改變這兩個參數觀察結果。

結果如下:
https://ithelp.ithome.com.tw/upload/images/20220928/20152370Hf9xIHglpk.png
可以發現Canny的效果比Sobel好上許多,因此成為具有代表性的邊緣偵測技術。


上一篇
[Day 20]色彩影像濾波與HSV分割
下一篇
[Day 22]直線與圓形偵測
系列文
數位影像處理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言