OpenCV 4.11.0
开源计算机视觉
|
OpenCV 提供三种类型的梯度滤波器或高通滤波器:Sobel、Scharr 和 Laplacian。我们将分别了解它们。
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 位输入图像,这将导致截断的导数。 |
dx | x 方向导数的阶数。 |
dy | y 方向导数的阶数。 |
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)。 |
dx | x 方向导数的阶数。 |
dy | y 方向导数的阶数。 |
scale | 计算出的导数值的可选缩放因子。 |
delta | 在将结果存储到 dst 之前添加到的可选增量值。 |
borderType | 像素外推方法(参见 cv.BorderTypes)。 |
它计算图像的拉普拉斯算子,由关系式给出:\(\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 滤波器以及结果差异的此过程。