天天看點

04 圖像梯度處理 Sobel算子

Sobel算子

先來看看sobel算子矩陣的構造,稱作卷積核更合适,這就是卷積運算

04 圖像梯度處理 Sobel算子

以3*3卷積核為例

可以看出Gx卷積核會增強垂直方向兩邊的差異,而Gy卷積核會增強水準方向上下的差異。

同時可以看到,離中間越近代表的權重越大,同時差異會更加明顯,類似高斯分布

函數:

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)

ddepth:圖像的深度

dx和dy分别表示水準和豎直方向(要哪個方向哪個就填1)

ksize是Sobel算子的大小

以前面用的圓的圖檔為例

#這裡新增了個參數CV_64F,是因為可能産生負數
#OpenCV對于負數的像素會直接設定為0,而這個參數就是為了避免這種情況
sobelx = cv2.Sobel(img,cv.CV_64F,1,0,ksize=3)
           

用CV_64F(保留負數)和不用CV_64F(負數置0)的圖像結果矩陣差別如下:

04 圖像梯度處理 Sobel算子
04 圖像梯度處理 Sobel算子

效果如下,缺一半的原因是右邊是黑-白得出負數,被OpenCV置為0

04 圖像梯度處理 Sobel算子

取絕對值進行改進

sobelx = cv2.Sobel(img,cv.CV_64F,1,0,ksize=3)
sobely = cv2.convertScaleAbs(sobely)  #絕對值
           
04 圖像梯度處理 Sobel算子

同樣的使用dy水準方向處理也是如此,效果如下

04 圖像梯度處理 Sobel算子

但這兩者都隻能處理一個方向,如果二者結合就完美了

接下來可以用函數

cv.addWeighted()

進行疊加

效果如下

04 圖像梯度處理 Sobel算子

雖然将dx和dy都填1也能實作兩個方向的疊加,但效果并不好

sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3) #不建議這樣
sobelxy = cv2.convertScaleAbs(sobelxy) 
           
04 圖像梯度處理 Sobel算子

利用sobel算子可以很好的保留下圖像的輪廓特征,下面用lena圖來看看效果

img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE) #轉灰階圖
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
           

效果如下

04 圖像梯度處理 Sobel算子

将dx和dy都設1,效果如下,并不好

04 圖像梯度處理 Sobel算子

教程來自:https://www.bilibili.com/video/BV1oJ411D71z?p=2