目錄
一.圖像邊緣檢測
1.圖像邊緣檢測概述
2.Sobel算子原理與實現
3.Scharr算子
4.Laplacian算子
5.Canny邊緣檢測(重點)
6.效果對比
一.圖像邊緣檢測
1.圖像邊緣檢測概述
2.Sobel算子原理與實現
代碼是實現步驟:
- 邊緣檢測是圖像處理和計算機視覺中的重要工具,用于檢測數字圖像中的明顯變化、邊緣或不連續區域。
- 主要方法包括:Sobel算子、scharr算子,Laplacian算子、Canny算子等。
- Sobel算子結合高斯平滑和微分求導,通過局部差分計算梯度近似值。
- 包含兩組3x3矩陣(橫向和縱向模板),分別用于水平和垂直方向的邊緣檢測。
- 橫向檢測:用右邊像素值減去左邊像素值;縱向檢測:用下方像素值減去上方像素值。
- 檢測時需分步進行(先橫向后縱向),避免同時設置
dx=1
和dy=1
導致結果不理想(線條過細且存在空洞)。 - 橫向檢測:
- 使用
cv2.Sobel()
,設置dx=1
、dy=0
,數據類型為cv2.CV_64F
以保存負數梯度值。 - 對結果取絕對值(
cv2.convertScaleAbs
)將負數轉為正數顯示。
- 使用
- 縱向檢測:
- 設置
dx=0
、dy=1
,同樣使用cv2.CV_64F
并取絕對值。
- 設置
- 融合結果:通過圖像加權融合(
cv2.addWeighted
)將橫向和縱向檢測結果合并,填補空洞。
import cv2
#1.sobel算子
yuan=cv2.imread('img.png',0)
cv2.imshow('yuan',yuan)
cv2.waitKey(0)
#x方向上的邊緣
yuan_x=cv2.Sobel(yuan,-1,dx=1,dy=0)#信息范圍(0~255)
cv2.imshow('yuan_x',yuan_x)
cv2.waitKey(0)
yuan_x_64=cv2.Sobel(yuan,cv2.CV_64F,dx=1,dy=0)#信息范圍(-1020~1020)
cv2.imshow('yuan_x_64',yuan_x_64)
cv2.waitKey(0)
#x方向上的邊緣含負數信息無法顯示,所以進行取絕對值操作
yuan_x_full=cv2.convertScaleAbs(yuan_x_64)
cv2.imshow('yuan_x_full',yuan_x_full)
cv2.waitKey(0)
#y方向上的邊緣
yuan_y_64=cv2.Sobel(yuan,cv2.CV_64F,dx=0,dy=1)#信息范圍(-1020~1020)
cv2.imshow('yuan_y_64',yuan_y_64)
cv2.waitKey(0)
yuan_y_full=cv2.convertScaleAbs(yuan_y_64)
cv2.imshow('yuan_y_full',yuan_y_full)
cv2.waitKey(0)
#圖像加權運算組合
yuan_xy_full=cv2.addWeighted(yuan_x_full,1,yuan_y_full,1,0)
cv2.imshow('yuan_xy_full',yuan_xy_full)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意事項:
- 輸入圖像需先轉換為灰度圖。
- 避免直接使用
unit8
數據類型(會丟失負數梯度信息),推薦使用cv2.CV_64F
。 - 分步檢測后融合的效果優于同時設置
dx=1
和dy=1
。
3.Scharr算子
- 改進:中心權重更大(中間為10,四角為3),精度更高,但線條更密集(可能包含更多偽邊緣)。
- 代碼實現:僅需將Sobel算子中的
cv2.Sobel
改為cv2.Scharr
。
#2.scharr算子
img=cv2.imread('img.png',0)
cv2.imshow('img',img)
cv2.waitKey(0)
img_x_64 = cv2.Scharr(img,cv2.CV_64F,dx=1,dy=0)
img_x_full=cv2.convertScaleAbs(img_x_64)
img_y_64 = cv2.Scharr(img,cv2.CV_64F,dx=0,dy=1)
img_y_full=cv2.convertScaleAbs(img_y_64)
img_xy_full=cv2.addWeighted(img_x_full,1,img_y_full,1,0)
cv2.imshow('img_xy_full',img_xy_full)
cv2.waitKey(0)
4.Laplacian算子
- 特點:不區分方向(直接計算變化率),卷積核中心為-4,四周為1,無需分步融合。
- 代碼:
cv2.Laplacian
?+ 取絕對值,步驟更簡單,但效果較粗糙(線條斷續、顏色淡)。img=cv2.imread('img.png',0) img_lap=cv2.Laplacian(img,cv2.CV_64F) img_lap_full=cv2.convertScaleAbs(img_lap) cv2.imshow('img_lap_full',img_lap_full) cv2.waitKey(0)
5.Canny邊緣檢測(重點)
- 原理:
- 高斯降噪:去除噪聲干擾。
- 梯度計算:通過Sobel算子計算梯度幅值和方向(像素變化最劇烈的方向)。
- 非極大值抑制:保留梯度方向上最亮的點,抑制其他點。
- 雙閾值篩選:
- 高閾值(如150):強邊緣(保留)。
- 低閾值(如100):弱邊緣(若與強邊緣連接則保留,否則剔除)。
- 代碼實現
#4.canny算子 img=cv2.imread('img.png',0) img_canny=cv2.Canny(img,120,180) img_canny_full=cv2.convertScaleAbs(img_canny) cv2.imshow('img_canny_full',img_canny_full) cv2.waitKey(0) cv2.destroyAllWindows()
優勢
邊緣更細、更真實(避免偽邊緣)。
背景干凈(純黑),僅保留顯著輪廓。
- 參數調整:閾值過高可能導致邊緣斷裂,過低則噪聲增多。
6.效果對比
- Sobel/Scharr:檢測較多細節(如花紋),但可能包含非邊緣信息。
- Laplacian:線條較淡,連續性差。
- Canny:僅保留強邊緣(如人物輪廓),背景純凈,適合