OpenCV 邊緣檢測

Ammar Ali 2024年2月15日
  1. OpenCV Canny 邊緣檢測
  2. OpenCV Sobel 邊緣檢測
OpenCV 邊緣檢測

邊緣檢測廣泛用於影象處理中的背景去除、形狀檢測和影象結構分析。在影象處理中,影象中存在的邊緣被表徵為畫素強度水平的突然變化。

例如,如果有一張黑色背景的貓的圖片,在這張圖片的邊緣,會出現顏色或畫素值的突然變化,比如從黑色到白色。

OpenCV 中有兩種方法可以用來檢測影象中存在的邊緣,一種是 Canny 邊緣檢測器,另一種是 Sobel 邊緣檢測器。

本教程將討論使用 OpenCV 中的 canny 或 Sobel 邊緣檢測器檢測影象中的邊緣。

OpenCV Canny 邊緣檢測

我們可以使用 OpenCV 的 Canny() 函式進行精明邊緣檢測。我們必須使用 GaussianBlur() 函式來平滑影象以獲得更好的結果。

由於畫素強度的突然變化,在邊緣檢測期間可以檢測到一些額外的邊緣,這些邊緣不是我們想要檢測的實際邊緣的一部分。這就是為什麼我們需要去除給定影象中存在的噪聲。

例如,讓我們使用 imread() 函式讀取影象並使用 cvtColor() 函式將其轉換為灰度。

之後,我們將對影象進行平滑處理,然後將其與上下閾值一起傳遞到 Canny() 函式中,以檢測影象中存在的邊緣。

請參閱下面的程式碼。

import cv2

img_src = cv2.imread("cat.jpg")
cv2.imshow("Original", img_src)

gray_img = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
blur_img = cv2.GaussianBlur(gray_img, (3, 3), 0)
img_edges = cv2.Canny(image=blur_img, threshold1=50, threshold2=155)

cv2.imshow("Canny Edge Detection", img_edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出:

坎尼邊緣檢測器

Canny 邊緣檢測器是多級的,它通過多個步驟來找到影象中存在的邊緣。第一步,該演算法減少給定影象中存在的噪聲。

第二步,演算法求給定影象在 x 和 y 方向的一階導數,然後利用該導數求出邊緣梯度的大小和角度。

第三步,該演算法通過比較區域性最大畫素與其鄰域來去除不需要的邊緣。

第四步,演算法使用使用者定義的兩個強度級別過濾邊緣。如果邊緣的值在定義的強度範圍之間,則將其視為有效邊緣。

在上面的程式碼中,Canny() 函式的第一個引數 image 是給定的影象,應該是 8 位的。第二個引數 threshold1 和第三個引數 threshold2 設定閾值範圍。

Canny() 函式還有兩個可選引數。第一個可選引數 apertureSize 用於設定 Sobel 運算元的孔徑大小,預設情況下,其值設定為 3。

第二個可選引數 L2gradient 設定漸變型別。預設情況下,正常梯度設定為 false,如果我們將其設定為 true,函式將使用 L2 梯度。

如果我們在 Canny() 函式中更改閾值範圍,輸出將會改變,因為範圍過濾了邊緣。

OpenCV Sobel 邊緣檢測

如上所述,canny 邊緣檢測器是多級的。它去除噪聲,找到邊緣,並使用閾值範圍過濾它們。

如果我們不想去除噪聲或過濾邊緣,我們可以使用 OpenCV 的 Sobel() 函式而不是 Canny()Sobel() 函式求影象在 x、y 或兩個方向的導數,然後將影象與核卷積得到 Sobel 邊緣影象。

Sobel() 函式還使用畫素強度的突然變化來查詢邊緣。例如,讓我們使用 Sobel() 函式查詢上述貓影象的邊緣。

請參閱下面的程式碼。

import cv2

img_src = cv2.imread("cat.jpg")
cv2.imshow("Original", img_src)

gray_img = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
blur_img = cv2.GaussianBlur(gray_img, (3, 3), 0)
sobel_x = cv2.Sobel(src=blur_img, ddepth=cv2.CV_64F, dx=1, dy=1, ksize=3)

cv2.imshow("Sobel Edge Detection", sobel_x)
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出:

Sobel 邊緣檢測器

如我們所見,上圖中存在很多邊緣,甚至包含不需要的邊緣,因為邊緣沒有被過濾,我們也沒有去除影象中存在的噪聲。Sobel() 函式的第一個引數 src 是源影象。

第二個引數 ddepth 用於設定輸出影象的深度。第三個引數 dx 用於設定 x 導數的階,第四個引數 dy 用於設定 y 導數的階。

第四個引數 ksize 用於設定核心大小,其值應為 1、3、5 或 7。第五個引數 scale 用於設定導數的比例因子,並且預設情況下,不使用比例。

第六個引數 delta 也是可選的,用於設定新增到輸出的 delta 值。第七個引數 borderType 也是可選的,用於設定畫素外插的方法,預設設定邊框型別為預設邊框。

檢查此連結以獲取有關邊框型別的更多詳細資訊。

作者: Ammar Ali
Ammar Ali avatar Ammar Ali avatar

Hello! I am Ammar Ali, a programmer here to learn from experience, people, and docs, and create interesting and useful programming content. I mostly create content about Python, Matlab, and Microcontrollers like Arduino and PIC.

LinkedIn Facebook

相關文章 - OpenCV Image