OpenCV  4.10.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's\)的矩阵,并将其除以元素数量来构建内核。

  • 设置内核后,我们可以用filter2D() 函数来生成滤波器
  • 参数说明
    • src:源图像
    • dst:目标图像
    • ddepthdst 的深度。负值(如 \(-1\)) 表示深度和源图像相同。
    • kernel:在图像中扫描的内核
    • anchor:锚相对于内核的位置。默认情况下,位置 Point(-1, -1) 表示中心。
    • delta:在相关性过程中要添加到每个像素中的值。默认值为 \(0\)
    • BORDER_DEFAULT:我们让这个值成为默认值(详情请见以下教程)
  • 我们的程序将执行一个 while 循环,每隔 500 毫秒滤波器的内核大小都会在指定的范围内进行更新。

结果

  1. 编译完上面的代码后,您可以执行它并把图像的路径作为参数。结果应该是一个窗口,显示一张经过标准化滤波器模糊处理的图像。每隔 0.5 秒,内核大小应该改变,如下面的一系列快照所示