OpenCV 4.11.0
开源计算机视觉库
加载中…
搜索中…
无匹配项
重新映射

上一篇教程: 使用广义 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_x* 和 *mat_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. 沿x和y方向都镜像