OpenCV 4.12.0
开源计算机视觉
加载中...
搜索中...
无匹配项
重映射

上一个教程: 使用广义Ballard和Guil霍夫变换进行对象检测
下一个教程: 仿射变换

原始作者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. 沿两个方向翻转