OpenCV 4.13.0
开源计算机视觉库 (Open Source Computer Vision)
正在加载...
正在搜索...
未找到匹配项
映射

上一教程: 使用广义 Ballard 和 Guil Hough 变换进行物体检测
下一教程: 仿射变换

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

目标

在本教程中,你将学习如何:

a. 使用 OpenCV 函数 cv::remap 来实现简单的映射操作。

理论

什么是映射?

  • 这是从图像中的一个位置获取像素并将其放置在新图像中的另一个位置的过程。
  • 为了完成映射过程,对于非整数像素位置,可能需要进行插值,因为源图像和目标图像之间并不总是一对一的像素对应关系。
  • 我们可以将每个像素位置 \((x,y)\) 的映射表示为

    \[g(x,y) = f ( h(x,y) )\]

    其中 \(g()\) 是映射后的图像,\(f()\) 是源图像,而 \(h(x,y)\) 是作用于 \((x,y)\) 的映射函数。

  • 让我们快速举个例子。假设我们有一张图像 \(I\),并且我们想进行一个映射,使得

    \[h(x,y) = (I.cols - x, y )\]

    会发生什么?很容易看出图像会在 \(x\) 方向上翻转。例如,考虑输入图像

观察红色圆圈如何相对于 \(x\)(将 \(x\) 视为水平方向)改变位置

  • 在 OpenCV 中,函数 cv::remap 提供了一个简单的映射实现。

代码

  • 这个程序做什么?
    • 加载图像
    • 每秒钟,对图像应用 4 种不同的映射过程中的一种,并在窗口中无限期地显示它们。
    • 等待用户退出程序

解释

  • 加载图像

  • 创建目标图像和两个映射矩阵(用于 x 和 y)

  • 创建一个窗口来显示结果

  • 建立一个循环。每隔 1000 毫秒,我们更新我们的映射矩阵(mat_xmat_y)并将它们应用于源图像

  • 应用映射的函数是 cv::remap 。我们提供以下参数:

    • src: 源图像
    • dst: 与 src 大小相同的目标图像
    • map_x: x 方向的映射函数。它等同于 \(h(i,j)\) 的第一个分量
    • map_y: 同上,但方向为 y。请注意,map_ymap_x 的大小都与 src 相同
    • INTER_LINEAR: 用于非整数像素的插值类型。这是默认值。
    • BORDER_CONSTANT: 默认

    我们如何更新我们的映射矩阵 mat_xmat_y ?继续阅读

  • 更新映射矩阵:我们将执行 4 种不同的映射
    1. 将图片缩小一半并将其显示在中间

      \[h(i,j) = ( 2 \times i - src.cols/2 + 0.5, 2 \times j - src.rows/2 + 0.5)\]

      对于所有满足以下条件的对 \((i,j)\):\(\dfrac{src.cols}{4}<i<\dfrac{3 \cdot src.cols}{4}\) 和 \(\dfrac{src.rows}{4}<j<\dfrac{3 \cdot src.rows}{4}\)
    2. 将图像上下颠倒:\(h( i, j ) = (i, src.rows - j)\)
    3. 从左到右反射图像:\(h(i,j) = ( src.cols - i, j )\)
    4. b 和 c 的组合:\(h(i,j) = ( src.cols - i, src.rows - j )\)

这在以下代码片段中得到体现。在这里,map_x 代表 h(i,j) 的第一个坐标,map_y 代表第二个坐标。

结果

  1. 编译上述代码后,您可以为其提供图像路径作为参数来执行它。例如,使用以下图像
  1. 这是将其缩小一半并居中后的结果
  1. 将其上下颠倒
  1. 在 x 方向上反射它
  1. 在两个方向上反射它