Sobel算子
先來看看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)的圖像結果矩陣差別如下:
效果如下,缺一半的原因是右邊是黑-白得出負數,被OpenCV置為0
取絕對值進行改進
sobelx = cv2.Sobel(img,cv.CV_64F,1,0,ksize=3)
sobely = cv2.convertScaleAbs(sobely) #絕對值
同樣的使用dy水準方向處理也是如此,效果如下
但這兩者都隻能處理一個方向,如果二者結合就完美了
接下來可以用函數
cv.addWeighted()
進行疊加
效果如下
雖然将dx和dy都填1也能實作兩個方向的疊加,但效果并不好
sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3) #不建議這樣
sobelxy = cv2.convertScaleAbs(sobelxy)
利用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)
效果如下
将dx和dy都設1,效果如下,并不好
教程來自:https://www.bilibili.com/video/BV1oJ411D71z?p=2