OpenCV Sobel检测算子和Scharr检测算子
Sobel邊緣檢測算法比較簡單,實際應用中效率比canny邊緣檢測效率要高,但是邊緣不如Canny檢測的準確,但是很多實際應用的場合,sobel邊緣卻是首選,Sobel算子是高斯平滑與微分操作的結合體,所以其抗噪聲能力很強,用途較多。尤其是效率要求較高,而對細紋理不太關心的時候。
Sobel_x_or_y = cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)-
src:傳入的圖像
-
ddepth: 圖像的深度
-
dx和dy: 指求導的階數,0表示這個方向上沒有求導,取值為0、1。
-
ksize: 是Sobel算子的大小,即卷積核的大小,必須為奇數1、3、5、7,默認為3。
注意:如果ksize=-1,就演變成為3x3的Scharr算子。
-
scale:縮放導數的比例常數,默認情況為沒有伸縮系數。
-
borderType:圖像邊界的模式,默認值為cv2.BORDER_DEFAULT。
Sobel函數求完導數后會有負值,還有會大于255的值。而原圖像是uint8,即8位無符號數,所以Sobel建立的圖像位數不夠,會有截斷。因此要使用16位有符號的數據類型,即cv2.CV_16S。處理完圖像后,再使用cv2.convertScaleAbs()函數將其轉回原來的uint8格式,否則圖像無法顯示。
Sobel算子是在兩個方向計算的,最后還需要用cv2.addWeighted( )函數將其組合起來
Scale_abs = cv2.convertScaleAbs(x) # 格式轉換函數 result = cv2.addWeighted(src1, alpha, src2, beta) # 圖像混合 import cv2 as cv from matplotlib import pyplot as plt # 1 讀取圖像 img = cv.imread('./1.png', 0)# 2.1 計算Sobel卷積結果 x1 = cv.Sobel(img, cv.CV_16S, 1, 0) # x軸求導 y1 = cv.Sobel(img, cv.CV_16S, 0, 1) # y軸求導# 2.2 計算Scharr卷積結果 x2 = cv.Sobel(img, cv.CV_16S, 1, 0, ksize=-1) y2 = cv.Sobel(img, cv.CV_16S, 0, 1, ksize=-1)# 3.1 將Sobel數據結果進行轉換 Scale_absX1 = cv.convertScaleAbs(x1) # convert 轉換 scale 縮放 Scale_absY1 = cv.convertScaleAbs(y1)# 3.2 將Scharr數據結果進行轉換 Scale_absX2 = cv.convertScaleAbs(x2) # convert 轉換 scale 縮放 Scale_absY2 = cv.convertScaleAbs(y2)# 4.1 Sobel轉換后結果合成 result1 = cv.addWeighted(Scale_absX1, 0.5, Scale_absY1, 0.5, 0)# 4.2 Scharr轉換后結果合成 result2 = cv.addWeighted(Scale_absX2, 0.5, Scale_absY2, 0.5, 0)# 5. 圖像顯示 fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100) axes[0].imshow(img, cmap=plt.cm.gray) axes[0].set_title("原圖") axes[1].imshow(result1, cmap=plt.cm.gray) axes[1].set_title("Sobel濾波后結果") axes[2].imshow(result2, cmap=plt.cm.gray) axes[2].set_title("Scharr濾波后結果") plt.show()
上述代碼中計算sobel算子的部分中將ksize設為-1,就是利用Scharr進行邊緣檢測。
總結
以上是生活随笔為你收集整理的OpenCV Sobel检测算子和Scharr检测算子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV 自适应的直方图均衡化
- 下一篇: OpenCV Laplacian算子