透视与逆透视,及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 对图像进行实际的像素变换)。

相关推荐
中國龍在廣州6 分钟前
现在人工智能的研究路径可能走反了
人工智能·算法·搜索引擎·chatgpt·机器人
攻城狮7号15 分钟前
小米具身大模型 MiMo-Embodied 发布并全面开源:统一机器人与自动驾驶
人工智能·机器人·自动驾驶·开源大模型·mimo-embodied·小米具身大模型
搜移IT科技20 分钟前
【无标题】2025ARCE亚洲机器人大会暨展览会将带来哪些新技术与新体验?
人工智能
6***x54520 分钟前
C++在计算机视觉中的图像处理
c++·图像处理·计算机视觉·游戏引擎·logback·milvus
信也科技布道师FTE39 分钟前
当AMIS遇见AI智能体:如何为低代码开发装上“智慧大脑”?
人工智能·低代码·llm
青瓷程序设计41 分钟前
植物识别系统【最新版】Python+TensorFlow+Vue3+Django+人工智能+深度学习+卷积神经网络算法
人工智能·python·深度学习
AI即插即用1 小时前
即插即用系列 | CVPR 2025 WPFormer:用于表面缺陷检测的查询式Transformer
人工智能·深度学习·yolo·目标检测·cnn·视觉检测·transformer
唐兴通个人1 小时前
数字化AI大客户营销TOB营销客户开发专业销售技巧培训讲师培训师唐兴通老师分享AI销冠人工智能销售AI赋能销售医药金融工业品制造业
人工智能·金融
人机与认知实验室2 小时前
国内主流大语言模型之比较
人工智能·语言模型·自然语言处理
T0uken2 小时前
【Python】UV:境内的深度学习环境搭建
人工智能·深度学习·uv