OpenCV(Python3)_14(图像梯度)

目标

在本章中,我们将学习:

理论

OpenCV提供三种类型的梯度滤波器或高通滤波器,Sobel,Scharr和Laplacian。我们会看到他们中的每一个。

1. Sobel和Scharr

Sobel算子是一个高斯平滑与微分操作的结合体,因此它抗噪声能力很强。您可以指定要采取的求导方向,垂直或水平(分别通过参数,yorder和xorder)。您也可以通过参数ksize指定内核的大小。如果ksize = -1,则使用3x3 Scharr滤波器,其结果比3x3 Sobel滤波器效果更好。请参阅所用内核的文档。

Sobel算子:


Scharr算子如下:


拉普拉斯算子

它由下面这个方程给出的图像的拉普拉斯算子:

                                                           

其中每个导数都是使用Sobel算子计算的。如果ksize = 1,则使用以下内核进行滤波。


程序:

下面的程序,分别使用了三种滤波器对图像处理。所有内核均为5x5大小。当输出图像的深度传递参数为-1时,其类型为np.uint8。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('lena.jpg',0)
laplacian = cv.Laplacian(img,cv.CV_64F)
#image,深度,X方向导数阶数,Y方向导数阶数,KSize
sobelx = cv.Sobel(img,cv.CV_64F,1,0,ksize=5)
sobely = cv.Sobel(img,cv.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()

结果:

                                                 

一件重要的事情!

在查看上面这个例子的注释时不知道你有没有注意到:当我们可以通过参数 -1 来设定输出图像的深度(数据类型)与原图像保持一致,但是我们在代码中使用的却是 cv.CV_64F。这是为什么呢?想象一下一个从黑到白的边缘的导数是正数,而一个从白到黑的边界点导数却是负数。如果原图像的深度是np.uint8 时,所有的负值都会被截断变成 0,换句话说就是把边缘丢失掉。

所以如果这两种边缘你都想检测到,最好的的办法就是将输出的数据类型设置的更高,比如 cv.CV_16S,cv.CV_64F 等。取绝对值然后再把它转回到 cv.CV_8U。下面的示例演示了输出图片的深度不同造成的不同效果。

程序:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('lena.jpg',0)
# Output dtype = cv.CV_8U
sobelx8u = cv.Sobel(img,cv.CV_8U,1,0,ksize=5)
# Output dtype = cv.CV_64F. Then take its absolute and convert to cv.CV_8U
sobelx64f = cv.Sobel(img,cv.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()

结果:

                                                    

猜你喜欢

转载自blog.csdn.net/qq_27806947/article/details/80766293