?原始圖片:
?
1、Sobel()
Sobel 算子結合了高斯平滑和微分,用于計算圖像的梯度,從而突出顯示邊緣。
import cv2# 讀取圖像
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)# 使用 Sobel 算子查找水平和垂直邊緣
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)# 疊加水平和垂直邊緣
edges = cv2.addWeighted(cv2.convertScaleAbs(sobel_x), 0.5, cv2.convertScaleAbs(sobel_y), 0.5, 0)# 顯示結果
cv2.imshow("Original Image", image)
cv2.imshow("Edges", edges)cv2.waitKey(0)
cv2.destroyAllWindows()
函數原型:
sobel = cv2.Sobel(src, ddepth, dx, dy, ksize, scale, delta, borderType)?
參數說明:
- src: 輸入圖像(單通道,例如灰度圖)。
- ddepth: 輸出圖像的深度(例如?
cv2.CV_64F
?表示 64 位浮點數)。 - dx: x 方向上的導數階數(0表示沒有導數,1表示一階導數)。
- dy: y 方向上的導數階數(與 dx 類似)。
- ksize: Sobel 核的大小,必須是 1, 3, 5 或 7 等奇數。
- scale: 可選值,縮放導數結果,以便調整圖像亮度(默認值為 1)。
- delta: 可選值,在存儲之前添加到結果中的值(默認值為 0)。
- borderType: 邊界類型,用于確定圖像邊界(默認值為?
cv2.BORDER_DEFAULT
)。
?2、Scharr()
Scharr 算子是一種改進的 Sobel 算子,適用于增強邊緣檢測的精度,在正常的 Sobel 核的尺寸上有更好的性能。
scharr_x = cv2.Scharr(src, ddepth, dx, dy, scale, delta, borderType)
參數說明:
- 與?
cv2.Sobel()
?相同,只是?ksize
?參數被硬編碼為 3。
import cv2
import numpy as np# 讀取圖像并轉換為灰度圖
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)# 使用 Scharr 算子計算 x 和 y 方向上的梯度
grad_x = cv2.Scharr(image, cv2.CV_64F, 1, 0)
grad_y = cv2.Scharr(image, cv2.CV_64F, 0, 1)# 將梯度取絕對值并轉換為 8 位圖像
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)# 合并 x 方向和 y 方向的梯度
scharr = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)# 顯示圖像
cv2.imshow('Scharr Edge Detection', scharr)
cv2.waitKey(0)
cv2.destroyAllWindows()
?
3、Canny()
Canny 邊緣檢測是一種多級邊緣檢測算法,效果較為顯著,常用來檢測圖像中的明顯邊緣。
?函數原型:
edges = cv2.Canny(image, threshold1, threshold2, apertureSize, L2gradient)
參數說明:
- image: 輸入圖像,通常是灰度圖。
- threshold1: 較低的閾值,用于邊緣檢測的滯后閾值過程。
- threshold2: 較高的閾值。
- apertureSize: Sobel 算子的大小,默認值為 3。
- L2gradient: 可選參數,用于計算圖像梯度幅值的標志。如果為 True,則使用更精確的 L2 范數計算梯度,否則使用 L1 范數。
-
import cv2# 讀取圖像并轉換為灰度圖 image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# 使用 Canny 邊緣檢測 edges = cv2.Canny(image, 100, 200)# 顯示圖像 cv2.imshow('Canny Edge Detection', edges) cv2.waitKey(0) cv2.destroyAllWindows()
4、Laplacian?()
Laplacian 算子是一種二階導數算子,用于檢測圖像中的邊緣。
laplacian = cv2.Laplacian(src, ddepth, ksize, scale, delta, borderType)
參數說明:
- src: 輸入圖像。
- ddepth: 輸出圖像的深度。
- ksize: Laplacian 算子的大小,必須是正奇數。
- scale: 可選參數,用于縮放導數值,默認值為 1。
- delta: 可選參數,在存儲之前添加到結果中的值,默認值為 0。
- borderType: 邊界模式,默認值為?
cv2.BORDER_DEFAULT
。import cv2 import numpy as np# 讀取圖像并轉換為灰度圖 image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# 使用 Laplacian 邊緣檢測 laplacian = cv2.Laplacian(image, cv2.CV_64F)# 將結果轉換為 8 位圖像 laplacian = cv2.convertScaleAbs(laplacian)# 顯示圖像 cv2.imshow('Laplacian Edge Detection', laplacian) cv2.waitKey(0) cv2.destroyAllWindows()
5、Prewitt算子
Prewitt 算子是另一種一階導數算子,可以檢測水平和垂直邊緣。雖然 OpenCV 沒有直接提供?cv2.prewitt()
?函數,但可以使用?cv2.filter2D
?函數自定義 Prewitt 核來實現。?
import cv2
import numpy as np# 讀取圖像并轉換為灰度圖
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)# 定義 Prewitt 核
prewitt_kernel_x = np.array([[1, 0, -1],[1, 0, -1],[1, 0, -1]])
prewitt_kernel_y = np.array([[1, 1, 1],[0, 0, 0],[-1, -1, -1]])# 使用 Prewitt 核進行邊緣檢測
grad_x = cv2.filter2D(image, cv2.CV_64F, prewitt_kernel_x)
grad_y = cv2.filter2D(image, cv2.CV_64F, prewitt_kernel_y)# 計算梯度幅值
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)
prewitt = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)# 顯示圖像
cv2.imshow('Prewitt Edge Detection', prewitt)
cv2.waitKey(0)
cv2.destroyAllWindows()
??
?6、Roberts Cross算子
羅伯特交叉算子是一種簡單且快速的邊緣檢測算子,適用于檢測圖像的對角邊緣。OpenCV 中沒有直接提供羅伯特交叉算子,但可以通過自定義卷積核實現。
import cv2
import numpy as np# 讀取圖像并轉換為灰度圖
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# 定義 Roberts 核
roberts_kernel_x = np.array([[1, 0],[0, -1]])
roberts_kernel_y = np.array([[0, 1],[-1, 0]])# 使用 Roberts 核進行邊緣檢測
grad_x = cv2.filter2D(image, cv2.CV_64F, roberts_kernel_x)
grad_y = cv2.filter2D(image, cv2.CV_64F, roberts_kernel_y)# 計算梯度幅值
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)
roberts = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)# 顯示圖像
cv2.imshow('Roberts Edge Detection', roberts)
cv2.waitKey(0)
cv2.destroyAllWindows()
7、自定義卷積核
還可以通過自定義卷積核來進行邊緣檢測。
import cv2
import numpy as np# 讀取圖像并轉換為灰度圖
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)# 定義自定義卷積核
custom_kernel = np.array([[-1, -1, -1],[-1, 7, -1],[-1, -1, -1]])# 使用自定義卷積核進行邊緣檢測
custom_edges = cv2.filter2D(image, cv2.CV_64F, custom_kernel)# 將結果轉換為 8 位圖像
custom_edges = cv2.convertScaleAbs(custom_edges)# 顯示圖像
cv2.imshow('Custom Kernel Edge Detection', custom_edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
?8、基于直方圖的邊緣檢測
基于直方圖的方法,通過分析圖像的灰度直方圖來檢測邊緣。
import cv2
import numpy as np# 讀取圖像并轉換為灰度圖
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)# 計算圖像的直方圖
hist = cv2.calcHist([image], [0], None, [256], [0, 256])# 找到直方圖的峰值
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(hist)# 使用峰值作為閾值進行二值化處理
_, binary = cv2.threshold(image, max_loc[1] - 30, 255, cv2.THRESH_BINARY)# 顯示圖像
cv2.imshow('Histogram Based Edge Detection', binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
?
9、adaptiveThreshold()
自適應閾值
自適應閾值可以在照明不均勻的情況下檢測邊緣。
函數原型:
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst])
參數說明:
src
:輸入圖像,應為灰度圖像(單通道)。maxValue
:指定在滿足條件時給輸出像素賦予的最大值(通常為255)。adaptiveMethod
:自適應方法。可選值有:cv2.ADAPTIVE_THRESH_MEAN_C
:基于鄰域均值的自適應閾值化方法。cv2.ADAPTIVE_THRESH_GAUSSIAN_C
:基于鄰域加權均值的自適應閾值化方法。
thresholdType
:閾值類型,應為?cv2.THRESH_BINARY
?或?cv2.THRESH_BINARY_INV
。blockSize
:指定用于計算閾值的鄰域大小,一般為奇數。C
:從計算的平均值或加權平均值中減去的常數。
import cv2# 讀取圖像并轉換為灰度圖
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# 自適應閾值
adaptive_threshold = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)# 顯示圖像
cv2.imshow('Adaptive Threshold Edge Detection', adaptive_threshold)
cv2.waitKey(0)
cv2.destroyAllWindows()
?
10、threshold()
閾值化 (cv2.threshold
)
簡單的全局閾值化方法,通過固定的閾值來二值化圖像以檢測邊緣。
import cv2# 讀取圖像并轉換為灰度圖
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)# 全局閾值化
_, threshold = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)# 顯示圖像
cv2.imshow('Global Threshold Edge Detection', threshold)
cv2.waitKey(0)
cv2.destroyAllWindows()
?