OpenCV 4.11.0
开源计算机视觉库
加载中…
搜索中…
无匹配项
图像平滑

目标

  • 使用各种低通滤波器模糊图像
  • 将自定义滤波器应用于图像(二维卷积)

二维卷积(图像滤波)

与一维信号一样,图像也可以使用各种低通滤波器 (LPF)、高通滤波器 (HPF) 等进行滤波。LPF 有助于去除噪声、模糊图像等。HPF 滤波器有助于查找图像中的边缘。

OpenCV 提供了一个函数cv.filter2D()来将核与图像进行卷积。例如,我们将尝试对图像应用平均滤波器。5x5 平均滤波器核如下所示

\[K = \frac{1}{25} \begin{bmatrix} 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 & 1 \end{bmatrix}\]

我们使用以下函数:cv.filter2D (src, dst, ddepth, kernel, anchor = new cv.Point(-1, -1), delta = 0, borderType = cv.BORDER_DEFAULT)

参数
src输入图像。
dst与 src 大小和通道数相同的输出图像。
ddepth所需的目标图像深度。
kernel卷积核(或相关核),单通道浮点矩阵;如果要将不同的核应用于不同的通道,请使用 split 将图像拆分为单独的颜色平面并分别处理它们。
anchor核的锚点,指示滤波点在核内的相对位置;锚点应位于核内;默认值 new cv.Point(-1, -1) 表示锚点位于核中心。
delta存储到 dst 中之前添加到已滤波像素的可选值。
borderType像素外推方法(参见 cv.BorderTypes)。

试一试

图像模糊(图像平滑)

图像模糊是通过使用低通滤波器核对图像进行卷积来实现的。它对于去除噪声非常有用。它实际上是从图像中去除高频内容(例如:噪声、边缘)。因此,在此操作中边缘会稍微模糊。(好吧,也存在不会过度模糊边缘的模糊技术)。OpenCV 主要提供四种类型的模糊技术。

1. 平均模糊

这是通过使用归一化盒式滤波器对图像进行卷积来完成的。它简单地取核区域下所有像素的平均值,并替换中心元素。这是由函数cv.blur()cv.boxFilter()完成的。查看文档以了解有关内核的更多详细信息。我们应该指定内核的宽度和高度。3x3 归一化盒式滤波器如下所示

\[K = \frac{1}{9} \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix}\]

我们使用以下函数:cv.blur (src, dst, ksize, anchor = new cv.Point(-1, -1), borderType = cv.BORDER_DEFAULT)

参数
src输入图像;它可以具有任意数量的通道,这些通道独立处理,但深度应为 CV_8U、CV_16U、CV_16S、CV_32F 或 CV_64F。
dst与 src 大小和类型相同的输出图像。
ksize模糊内核大小。
anchor锚点;anchor = new cv.Point(-1, -1) 表示锚点位于内核中心。
borderType用于外推图像外像素的边界模式(参见 cv.BorderTypes)。

cv.boxFilter (src, dst, ddepth, ksize, anchor = new cv.Point(-1, -1), normalize = true, borderType = cv.BORDER_DEFAULT)

参数
src输入图像。
dst与 src 大小和类型相同的输出图像。
ddepth输出图像深度(-1 用于使用 src.depth())。
ksize模糊内核大小。
anchor锚点;anchor = new cv.Point(-1, -1) 表示锚点位于内核中心。
normalize标志,指定内核是否按其面积进行归一化。
borderType用于外推图像外像素的边界模式(参见 cv.BorderTypes)。
注意
如果不想使用归一化盒式滤波器,请使用cv.boxFilter()。将参数 normalize = false 传递给函数。

试一试

2. 高斯模糊

在此,使用高斯核而不是盒式滤波器。

我们使用以下函数:cv.GaussianBlur (src, dst, ksize, sigmaX, sigmaY = 0, borderType = cv.BORDER_DEFAULT)

参数
src输入图像;图像可以具有任意数量的通道,这些通道独立处理,但深度应为 CV_8U、CV_16U、CV_16S、CV_32F 或 CV_64F。
dst与 src 大小和类型相同的输出图像。
ksize模糊内核大小。
sigmaXX 方向上的高斯核标准差。
sigmaYY 方向上的高斯核标准差;如果 sigmaY 为零,则将其设置为等于 sigmaX,如果两个 sigma 都为零,则它们将根据 ksize.width 和 ksize.height 计算得出,为了完全控制结果,无论所有这些语义的未来可能修改如何,建议指定所有 ksize、sigmaX 和 sigmaY。
borderType像素外推方法(参见 cv.BorderTypes)。

试一试

3. 中值模糊

在此,函数cv.medianBlur()取核区域下所有像素的中值,并用此中值替换中心元素。这对于去除图像中的椒盐噪声非常有效。有趣的是,在上述滤波器中,中心元素是一个新计算的值,它可能是图像中的像素值或新值。但在中值模糊中,中心元素始终替换为图像中的某个像素值。它有效地减少了噪声。它的内核大小应为正奇数。

我们使用函数:cv.medianBlur (src, dst, ksize)

参数
src输入1、3或4通道图像;当ksize为3或5时,图像深度应为cv.CV_8U、cv.CV_16U或cv.CV_32F,对于更大的孔径尺寸,它只能是cv.CV_8U。
dst与src大小和类型相同的目标数组。
ksize孔径线性大小;它必须是奇数且大于1,例如:3、5、7……
注意
中值滤波器内部使用cv.BORDER_REPLICATE来处理边界像素。

尝试一下

4. 双边滤波

cv.bilateralFilter()在去除噪声的同时保持边缘清晰度非常有效。但与其他滤波器相比,该操作速度较慢。我们已经看到,高斯滤波器获取像素周围的邻域并找到其高斯加权平均值。此高斯滤波器仅是空间的函数,即在滤波时考虑附近的像素。它不考虑像素是否具有几乎相同的强度。它不考虑像素是否为边缘像素。因此,它也会模糊边缘,而我们不想这样做。

双边滤波器也采用空间高斯滤波器,但还有一个高斯滤波器,它是像素差的函数。空间的高斯函数确保仅考虑附近的像素进行模糊,而强度差的高斯函数确保仅考虑强度与中心像素相似的像素进行模糊。因此,它保留了边缘,因为边缘处的像素将具有较大的强度变化。

我们使用函数:cv.bilateralFilter (src, dst, d, sigmaColor, sigmaSpace, borderType = cv.BORDER_DEFAULT)

参数
src源8位或浮点型,1通道或3通道图像。
dst与 src 大小和类型相同的输出图像。
d滤波过程中使用的每个像素邻域的直径。如果它是非正数,则根据sigmaSpace计算。
sigmaColor颜色空间中的滤波器 sigma。参数值越大,像素邻域内越远的颜色将混合在一起,从而导致更大面积的半等颜色。
sigmaSpace坐标空间中的滤波器 sigma。参数值越大,只要颜色足够接近,越远的像素就会相互影响。当d>0时,它指定邻域大小,而不管sigmaSpace。否则,d与sigmaSpace成比例。
borderType用于外推图像外像素的边界模式(参见 cv.BorderTypes)。
注意
为简单起见,您可以将两个 sigma 值设置为相同。如果它们很小(<10),则滤波器不会产生太大影响,而如果它们很大(>150),则它们将产生非常强大的影响,使图像看起来“卡通化”。大型滤波器 (d > 5) 速度非常慢,因此建议对于实时应用程序使用 d=5,对于需要大量降噪的离线应用程序,则可以使用 d=9。

尝试一下