OpenCV  4.10.0
Open Source Computer Vision
正在加载...
正在搜索...
没有匹配内容
图像梯度

目标

理论

OpenCV 提供三种梯度滤波器或高通滤波器,即 Sobel、Scharr 和拉普拉斯。我们来逐一了解一下。

1. Sobel 和 Scharr 导数

Sobel 算子是高斯平滑加微分运算的组合,因此对噪声有更强的抵抗力。你可以通过参数 yorder 和 xorder 确定导数的方向(分别是垂直或水平)。你还可以通过参数 ksize 来指定内核的大小。如果 ksize = -1,则会使用 3x3 Scharr 滤波器,其效果比 3x3 Sobel 滤波器更好。请参阅文档了解使用的内核。

我们使用以下函数:cv.Sobel (src, dst, ddepth, dx, dy, ksize = 3, scale = 1, delta = 0, borderType = cv.BORDER_DEFAULT)

参数
src输入图像。
dst与 src 大小和通道数相同的输出图像。
ddepth输出图像深度(参见 cv.combinations);对于 8 位输入图像,它将生成截断的导数。
dxx 导数的阶数。
dyy 导数的阶数。
ksize扩展 Sobel 核的大小;它必须为 1、3、5 或 7。
scale用于计算的导数值的可选缩放因子。
delta存储在 dst 之前添加到结果中的可选增量值。
borderType像素外推方法(参见 cv.BorderTypes)。

cv.Scharr(src,dst,ddepth,dx,dy,scale = 1,delta = 0,borderType = cv.BORDER_DEFAULT

参数
src输入图像。
dst与 src 大小和通道数相同的输出图像。
ddepth输出图像深度(请参阅 cv.combinations)。
dxx 导数的阶数。
dyy 导数的阶数。
scale用于计算的导数值的可选缩放因子。
delta存储在 dst 之前添加到结果中的可选增量值。
borderType像素外推方法(参见 cv.BorderTypes)。

试用

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}\]

我们使用此函数:cv.Laplacian(src,dst,ddepth,ksize = 1,scale = 1,delta = 0,borderType = cv.BORDER_DEFAULT

参数
src输入图像。
dst与 src 大小和通道数相同的输出图像。
ddepth输出图像深度。
ksize用于计算二阶导数滤波器的孔径大小。
scale计算出的拉普拉斯值的可选缩放因子。
delta存储在 dst 之前添加到结果中的可选增量值。
borderType像素外推方法(参见 cv.BorderTypes)。

试用

一件重要的事!

在我们的最后一个示例中,输出数据类型是 cv.CV_8U。但这存在一些小问题。黑色到白色转换视为正斜率(具有正值),而白色到黑色转换则视为负斜率(具有负值)。因此,当您将数据转换为 cv.CV_8U 时,所有负斜率都变为零。从简单的角度来说,您错过了该边缘。

如果您想检测两个边缘,更好的选择是将输出数据类型保留为一些较高的形式,如 cv.CV_16S, cv.CV_64F 等,取其绝对值,然后转换回 cv.CV_8U。以下代码演示了水平 Sobel 滤波器和结果差异的此过程。

试用