OpenCV  4.10.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)

参数
src1、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)。
注意
为了简洁起见,您可以将 2 个 sigma 值设置为相同。如果它们很小(< 10),则滤波器不会产生太大影响,而如果它们很大(> 150),则会产生非常强烈的效果,使图像看起来像“卡通”。大滤波器(d > 5)非常慢,所以建议在实时应用中使用 d=5,在需要大量噪声过滤的离线应用中使用 d=9。

试一试