OpenCV 4.11.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秒,卷积核大小应该改变,如下面的系列快照所示