OpenCV 4.12.0
开源计算机视觉
加载中...
搜索中...
无匹配项
制作您自己的线性滤波器!

上一教程: 使用 inRange 进行阈值操作
下一教程: 为图像添加边框

原始作者Ana Huamán
兼容性OpenCV >= 3.0

目标

在本教程中,您将学习如何

  • 使用 OpenCV 函数 filter2D() 创建您自己的线性滤波器。

理论

注意
以下解释来源于 Bradski 和 Kaehler 的著作 Learning OpenCV

相关性

从非常广泛的意义上讲,相关性是图像的每个部分与一个算子(核)之间的操作。

什么是核?

核本质上是一个固定大小的数值系数数组,以及该数组中的一个锚点,锚点通常位于中心。

核相关性是如何工作的?

假设您想知道图像中某个特定位置的最终值。相关性的值按以下方式计算:

  1. 将核锚点放置在特定像素上方,核的其余部分覆盖图像中相应的局部像素。
  2. 将核系数乘以相应的图像像素值并求和结果。
  3. 将结果放置在输入图像中锚点的位置。
  4. 通过在整个图像上扫描核,对所有像素重复此过程。

将上述过程用方程表示,我们得到:

\[H(x,y) = \sum_{i=0}^{M_{i} - 1} \sum_{j=0}^{M_{j}-1} I(x+i - a_{i}, y + j - a_{j})K(i,j)\]

幸运的是,OpenCV 为您提供了 filter2D() 函数,因此您无需编写所有这些操作的代码。

该程序的作用是什么?

  • 加载图像
  • 执行归一化盒式滤波器。例如,对于大小为 \(size = 3\) 的核,核将是:

    \[K = \dfrac{1}{3 \cdot 3} \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix}\]

程序将使用大小为 3、5、7、9 和 11 的核执行滤波操作。

  • 滤波器的输出(使用每个核)将显示 500 毫秒。

代码

本教程的代码如下所示。

解释

加载图像

初始化参数

循环

执行一个无限循环,更新核大小并将线性滤波器应用于输入图像。让我们更详细地分析一下。

  • 首先,我们定义滤波器将使用的核。如下所示:

第一行是将 kernel_size 更新为范围 \([3,11]\) 内的奇数值。第二行通过将其值设置为一个由 \(1\) 填充的矩阵并除以元素数量进行归一化来实际构建核。

  • 设置核之后,我们可以使用函数 filter2D() 生成滤波器。
  • 参数表示:
    • src:源图像
    • dst:目标图像
    • ddepth: dst 的深度。负值(例如 \(-1\))表示深度与源图像相同。
    • kernel: 将在图像上扫描的核。
    • anchor: 锚点相对于其核的位置。默认情况下,位置 Point(-1, -1) 表示中心。
    • delta: 在相关性计算过程中要添加到每个像素的值。默认情况下为 \(0\)。
    • BORDER_DEFAULT: 我们将此值设为默认(更多详细信息请参见后续教程)
  • 我们的程序将执行一个 while 循环,每 500 毫秒更新一次滤波器核的大小,范围如上所示。

结果

  1. 编译上述代码后,您可以执行它,并将图像路径作为参数。结果将是一个窗口,显示一个被归一化滤波器模糊的图像。每 0.5 秒,核大小都会改变,如下面的系列快照所示。