透视与逆透视,及opencv中的warp

解析一下 OpenCV 中的 warp(变换)操作,特别是与透视相关的 warpPerspective

在 OpenCV 的上下文中,warp 通常指的是一种图像几何变换,它根据某种数学规则将输入图像中的像素映射到输出图像中的新位置。这个过程通常涉及两个核心步骤:

  1. 坐标变换:为输出图像中的每个像素点,计算其在输入图像中的对应位置。
  2. 像素插值:由于计算出的对应位置往往是浮点数,需要通过插值算法(如最近邻、双线性等)来确定该位置的像素值。

核心函数:cv2.warpPerspective

这是实现逆透视映射 (IPM) 最直接相关的函数。

功能

对图像进行透视变换 。它可以将图像投影到一个新的视平面,非常适合实现仿射变换 无法实现的"透视效果",例如将一张图片"贴"到一个变形的四边形表面上,或者像我们讨论的,生成鸟瞰图

工作原理
  1. 输入

    • src: 源图像。
    • M: 一个 3x3 的透视变换矩阵。这个矩阵定义了变换的规则。
    • dsize: 输出图像的大小 (width, height)
    • flags: 插值方法(如 cv2.INTER_LINEAR 最常用)。
    • borderMode: 处理边界像素的模式(如 cv2.BORDER_CONSTANT)。
    • borderValue: 如果边界模式为 BORDER_CONSTANT,用于填充边界的值(通常为黑色 0)。
  2. 内部过程(逆映射)
    warpPerspective 使用的是逆映射(Inverse Mapping),这是理解其行为的关键。它的工作流程是:

    • 对于输出图像(鸟瞰图) 上的每一个目标像素点 (x_dst, y_dst)...
    • 使用变换矩阵 M逆矩阵 M⁻¹ ,计算该点在输入图像 上对应的源位置 (x_src, y_src)
      (x_src, y_src) = apply_homography(M⁻¹, (x_dst, y_dst))
    • 由于 (x_src, y_src) 通常是浮点数,使用指定的插值算法(如双线性插值)从输入图像中该位置周围像素计算出一个新的像素值。
    • 将这个新像素值赋给输出图像的 (x_dst, y_dst) 位置。

    为什么用逆映射? 因为正向映射(从原图映射到目标图)会导致目标图上出现空洞(没有像素映射到)和重叠(多个像素映射到同一点)的问题。逆映射可以保证输出图像中的每个像素都被精确地填充。

  3. 输出

    经过透视变换后的新图像。


如何获取变换矩阵 M

M 矩阵是 warpPerspective 的灵魂。获取方式主要有两种:

  1. cv2.getPerspectiveTransform(src_pts, dst_pts)

    • 作用 :根据源图像和目标图像上的 4 组对应点 ,计算变换矩阵 M

    • 原理:通过解线性方程组来求解单应性矩阵。它需要至少 4 个点,并且假设这些点都在同一个平面上(完美符合IPM的假设)。

    • 示例

      python 复制代码
      # 假设在原始透视图像上选取了一个梯形的四边形区域
      src_pts = np.float32([[580, 460], [700, 460], [1100, 720], [200, 720]])
      # 希望它在鸟瞰图中变成一个矩形
      dst_pts = np.float32([[400, 0], [900, 0], [900, 720], [400, 720]])
      
      M = cv2.getPerspectiveTransform(src_pts, dst_pts) # 计算从 src 到 dst 的变换矩阵
      bird_eye_view = cv2.warpPerspective(image, M, (image.shape[1], image.shape[0]))
  2. cv2.findHomography(src_pts, dst_pts, method)

    • 作用:功能更强大的函数,也用于计算单应性矩阵。

    • 优势

      • 可以输入多于4个的点对,求一个最优解。
      • 内置了鲁棒性算法(如 cv2.RANSAC),可以排除错误匹配点( outliers ) 的干扰。这在通过特征点匹配计算Homography时非常有用。
      • getPerspectiveTransform 的一个更通用、更鲁棒的版本。
    • 示例

      python 复制代码
      M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

其他相关的 warp 函数

  1. cv2.warpAffine

    • 功能 :进行仿射变换。仿射变换是透视变换的一个子集,它保持了图像的"平直性"(直线变换后还是直线)和"平行性"(平行线变换后依然平行)。
    • 常见应用 :平移、旋转、缩放、剪切。它不能产生透视效果(近大远小)。
    • 变换矩阵 :使用 2x3 的矩阵。
  2. cv2.remap

    • 功能:一种更底、更灵活的几何变换函数。
    • 原理 :它直接要求你提供两个映射图 map_xmap_y,来指明输出图像中每个像素 (x,y) 应该从输入图像的哪个位置 (map_x(x,y), map_y(x,y)) 取像素值。
    • 应用 :常用于复杂的自定义变换,例如镜头畸变校正 。校正鱼眼相机图像时,cv2.fisheye.undistortImage 的内部通常就是先计算好 map_xmap_y,然后调用 remap 来实现的。

总结

函数 核心作用 变换类型 关键输入
warpPerspective 执行透视变换,实现IPM、视角转换 投影变换 3x3 单应性矩阵 M
getPerspectiveTransform 计算 用于 warpPerspective 的变换矩阵 M - 4组对应点
findHomography 鲁棒地计算 变换矩阵 M(更强大) - 多组对应点 + 方法(如RANSAC)
warpAffine 执行仿射变换(旋转、缩放、剪切等) 仿射变换 2x3 矩阵
remap 执行任意自定义的几何变换 任意变换 映射图 map_x, map_y

简单来说,在逆透视映射的流程中:
getPerspectiveTransform/findHomography 负责制定规则 (计算变换矩阵 M),而 warpPerspective 负责执行规则 (根据 M 对图像进行实际的像素变换)。

相关推荐
gaosushexiangji3 小时前
基于高速摄像机与6Dof测量的手机跌落实验分析
人工智能·科技·生活
还是大剑师兰特3 小时前
Transformer 面试题及详细答案120道(51-60)-- 模型变体与改进
人工智能·transformer·大剑师·transformer面试题
fayuan06963 小时前
一、Pytorch安装教程-windows环境,利用Anaconda搭建虚拟环境,Pycharm开发工具
人工智能·pytorch·pycharm·conda
androidstarjack3 小时前
如何评价 Visual Studio 2026?
ide·人工智能·visual studio
dxnb224 小时前
Datawhale25年9月组队学习:llm-preview+Task3:提示词工程
人工智能·学习
incidite4 小时前
PyTorch 核心知识手册:神经网络构建与训练基础
人工智能·pytorch·神经网络
时序之心4 小时前
ACL 2025 Time-LlaMA 大语言模型高效适配时间序列预测
人工智能·语言模型·论文·llama·时间序列
love530love4 小时前
【02】EPGF 架构搭建教程之 Python 多版本配置
运维·开发语言·人工智能·windows·python·架构·epgf 架构
山烛4 小时前
OpenCV :基于 Lucas-Kanade 算法的视频光流估计实现
人工智能·opencv·计算机视觉·音视频·图像识别·特征提取·光流估计