原理
OpenCV提供了三種類型的梯度過濾器或者高通濾波器,Sobel,Scharr和Laplacian。
1.Sobel和Scharr 導(dǎo)數(shù)
Sobel算子是一個連接高斯平滑和微分運算,所以它更抗噪音,你可以指定求導(dǎo)的方向,垂直的或水平的(參數(shù)yorder和xorder)。你也可以指定核的大小ksize,如果ksize=-1,會使用一個3x3的Scharr過濾器,這個的結(jié)果要比3x3的sobel過濾器的結(jié)果好。
2.拉普拉斯導(dǎo)數(shù)
如果通過公式計算圖片的拉布拉斯

用Sobel導(dǎo)數(shù)找到每個導(dǎo)數(shù),如果ksize=1,下面的核用來過濾:

代碼:
下面的代碼在一個圖里顯示了所有算子。核都是5x5的。圖片的深度傳的是參數(shù)-1來得到np.uint8類型。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img =?cv2.imread('dave.jpg',0)
laplacian = cv2.Laplacian(img,cv2.CV_64F)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
plt.subplot(2,2,1), plt.imshow(img,cmap='gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,2), plt.imshow(laplacian,cmap='gray')
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,3), plt.imshow(sobelx,cmap='gray')
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,4), plt.imshow(sobely,cmap='gray')
plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])
plt.show()
結(jié)果:

一個重要的問題!
在上一個例子里,輸出數(shù)據(jù)類型是cv2.CV_8U或者np.uint8.但是有一點問題。黑到白的轉(zhuǎn)換是正坡(正值)而白到黑的轉(zhuǎn)換時負坡(負值)。所以當你把數(shù)據(jù)轉(zhuǎn)換成np.uint8時,所有的負坡變成0.簡單說,你會丟掉那些邊緣。
如果你想檢測兩個邊緣,更好的選擇是讓輸出數(shù)據(jù)類型保持高級形式,像cv2.CV_16S,cv2.CV_64F等。用他們的絕對值,然后轉(zhuǎn)換回cv2.CV_8U。下面的代碼展示了這個過程,
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('box.png',0)
# Output dtype = cv2.CV_8U
sobelx8u = cv2.Sobel(img,cv2.CV_8U,1,0,ksize=5)
# Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U
sobelx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
abs_sobel64f = np.absolute(sobelx64f)
sobel_8u = np.uint8(abs_sobel64f)
plt.subplot(1,3,1), plt.imshow(img,cmap='gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(1,3,2), plt.imshow(sobelx8u,cmap='gray')
plt.title('Sobel CV_8U'), plt.xticks([]), plt.yticks([])
plt.subplot(1,3,3), plt.imshow(sobel_8u,cmap='gray')
plt.title('Sobel abs(CV_64F)'), plt.xticks([]), plt.yticks([])
plt.show()
結(jié)果: