本章将学习如下内容:
- 查找图像渐变、边缘等
- 介绍如下函数:
cv2.Sobel()
,cv2.Scharr()
、cv2.Laplacian()
等
理论基础
OpenCV 提供三种梯度滤波器(或称高通滤波器):Sobel, Scharr and Laplacian。 我们将逐一探讨每种方法。
Sobel and Scharr 导数算子
Sobel算子是高斯平滑加微分的联合运算,因此它对噪声的抵抗力更强。
可以指定要取导数的方向,垂直或水平(分别通过参数yorder和xorder)。
还可以通过参数ksize指定内核的大小。如果ksize=-1
,则使用3x3 Scharr滤波器,
其结果优于3x3 Sobel滤波器。请参阅所用内核的文档。
Laplacian 算子
它计算由该关系给出的图像Laplacian算子,
$\Delta src = \frac{\partial ^2{src}}{\partial x^2} + \frac{\partial ^2{src}}{\partial y^2}$
其中每个衍生物都是使用Laplacian算子找到的。如果 ksize = 1
,
使用以下内核进行过滤:
$$\begin{aligned} kernel = \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{bmatrix} \end{aligned}$$
代码
下面的代码在一个图中显示了所有运算符。所有的内核都是5x5大小。
输出图像的深度传递-1以获得np.uint8
类型的结果。
%matplotlib inline
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('/data/cvdata/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()
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('/data/cvdata/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()
检查下面的结果: