返回介绍

4.6 图像梯度

发布于 2019-07-01 11:38:52 字数 2928 浏览 1068 评论 0 收藏 0

目标

在这一章中,我们将学习:

  • 查找图像梯度,边缘等。
  • 我们将学习以下函数:cv2.Sobel()cv2.Scharr()cv2.Laplacian()等。

理论基础

OpenCV提供了三种类型的梯度滤波器或高通滤波器,Sobel,Scharr和Laplacian。

我们会一一介绍它们。

1. Sobel和Scharr导数

Sobel算子是一个联合了高斯平滑和差分的运算,因此它更能抵抗噪声。 您可以指定要取导数的方向,垂直方向或者水平方向(分别通过参数 yorder 和 xorder)。 你也可以通过参数 ksize 来指定内核的大小。 如果 ksize = -1,则使用3x3 Scharr滤波器,其结果比 3x3 Sobel 滤波器更好。 请参阅文档来看看使用的内核的特性。

2. 拉普拉斯导数

它计算由 $\Delta src = \frac{\partial ^2{src}}{\partial x^2} + \frac{\partial ^2{src}}{\partial y^2}$ 给出的,图像的拉普拉斯算子,其中每个导数都是用Sobel导数计算的,如果 ksize=1,则使用以下内核进行过滤:

$$
kernel = \begin{bmatrix} 0 & 1 & 0 \ 1 & -4 & 1 \ 0 & 1 & 0 \end{bmatrix}
$$

代码

下面的代码在单个图表中显示了所有操作的运算结果。 所有内核都是 5x5 大小。 输出图像的深度传递-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()

一件重要的事

在我们的最后一个例子中,输出数据类型是 cv2.CV_8U 或 np.uint8。 但是有一个小问题。 黑白转换为正斜率(正值),白转黑转换为负斜率(负值)。 所以当你把数据转换成np.uint8时,所有的负斜率都会变成零。 简而言之,你会忽略了这个边缘。

如果黑到白和白到黑两边你都想检测,更好的选择是保持输出数据类型的一些更多位数的形式,如cv2.CV16Scv2.CV64F等,取其绝对值,然后转换回 cv2.CV_8U

下面的代码演示了水平Sobel滤波器的这个过程和结果的差异。

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()

更多资源

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文