Contents — find the section you need

在“同一平面”(例如桌面、海报、路面)上拍摄的两幅图像中,对应点之间的关系比一般的 3D 场景要简单得多。无论相机位置如何,该平面上的点都可以仅使用一个 3\times3 矩阵相互变换。这个矩阵就是单应性矩阵(一种投影变换)。极线几何入门 处理的是预设场景深度的对应关系约束,而单应性矩阵则与之相反,它处理的是完全不依赖于深度的对应关系——只有能够恰当地运用这两种方法,才能全面理解双视图几何。

0. 30 秒概要

  • 单应性矩阵 H 是一个 3\times3 矩阵,表示图像对应关系 \tilde{\mathbf{x}}'\sim H\tilde{\mathbf{x}},可以是同一平面上的点,也可以是相机纯旋转的情况。它有 8 个自由度,直至尺度模糊。

  • DLT(直接线性变换)方法为每个点对应关系构建两个线性方程,并通过 SVD 从 4 个或更多对应关系中线性求解 H。Hartley 归一化可有效稳定数值结果。

  • 由于实际对应关系包含不匹配项,因此在最终估计之前使用 RANSAC 算法去除异常值。最小样本量为 4 个点,这使得鲁棒估计的迭代次数低于基本矩阵估计。

  • 给定一台已校准的相机,其分解形式为 H=K(R+\mathbf{t}\mathbf{n}^\mathsf{T}/d)K^{-1},分解为旋转 R、平移方向和平面法线 \mathbf{n}。然而,通常情况下,仍存在多个物理上合理的候选解,需要额外信息来缩小范围。

  • 对于平面场景或纯旋转,单应性矩阵比本质矩阵或基本矩阵更合适。未能检测到这种退化意味着在深度信息根本无法恢复的情况下强行尝试 3D 重建。

1. 什么是单应性变换:平面投影变换

当两幅图像上的齐次坐标 \tilde{\mathbf{x}}=(x,y,1)^\mathsf{T} 和 \tilde{\mathbf{x}}'=(x',y',1)^\mathsf{T} 满足以下关系时:

\tilde{\mathbf{x}}' \sim H\tilde{\mathbf{x}}

通过某个 3\times3 矩阵 H,我们称 H 为单应性矩阵。\sim 表示在尺度上相等——将 H 乘以任何非零常数都表示相同的变换——因此 H 的自由度为 9-1=8。

Diagram 1 · Use the button to switch views
通过单应性矩阵 H 将图像 1 到图像 2 映射的同一平面上的四个对应点,与深度视差情况(其中单个 H 不足以满足需求)形成对比

Diagram 2 · Use the button to switch views

单应性矩阵成立通常有两种物理条件。第一种,所有对应的三维点都位于同一个平面上。其次,即使对于具有一般三维结构的场景,如果摄像机完全不平移而只进行纯粹的旋转(水平/垂直),则无论深度如何,其关系都可以用单应性矩阵来描述。这是因为当摄像机只旋转时,根本不会产生视差。

2. 基于DLT方法的估计

从单个对应关系(x,y)\to(x',y')出发,我们可以推导出H的每个元素h_1,\dots,h_9的线性约束(记为\mathbf{h}=\operatorname{vec}(H))。展开叉积\tilde{\mathbf{x}}'\times H\tilde{\mathbf{x}}=\mathbf{0}为零的条件,即可得到每个对应关系的以下两个独立方程。

\begin{bmatrix} -x & -y & -1 & 0 & 0 & 0 & x'x & x'y & x' \\ 0 & 0 & 0 & -x & -y & -1 & y'x & y'y & y' \end{bmatrix}\mathbf{h}=\mathbf{0}

对于4个对应关系,可以得到8个方程,这些方程(在一般情况下)唯一确定了8自由度的H。在实际情况下,当有 5 个或更多对应点可用时,可以通过奇异值分解 (SVD) 找到矩阵 A 中 A\mathbf{h}=\mathbf{0} 的最小二乘解,该矩阵堆叠了所有对应点——即对应于 A 最小奇异值的右奇异向量。这就是直接线性变换 (DLT) 方法。

与极线几何中的 8 点算法类似,直接使用原始像素坐标往往会导致数值病态。标准实现方法是 Hartley 的归一化 DLT:对每幅图像的点集应用相似性变换 T,T',使其质心为零,平均距离为 \sqrt{2},在该归一化坐标系中求解,然后使用 H=T'^{-1}H_{\text{norm}}T 将坐标变换回原坐标系。

3. 基于 RANSAC 的稳健估计

由于实际对应关系中包含不匹配点,直接对每个对应关系应用 DLT 会导致异常值严重扭曲解。RANSAC 重复以下步骤:

  1. 随机选择 4 个对应关系,并使用 DLT 为 H 构建一个假设。

  2. 对于每个对应关系,计算 H 预测位置与实际对应点之间的重投影误差。

  3. 选择在阈值范围内对应关系(内点)最多的假设。

  4. 使用所有最终的内点再次求解 DLT,如有必要,则进行非线性优化(直接最小化重投影误差)。

给定内点比率w、最小样本量s=4和目标成功概率p,所需迭代次数可估算如下:

N=\frac{\log(1-p)}{\log\!\left(1-w^{s}\right)}

对于相同的内点比率,单应性矩阵的s=4所需的迭代次数少于基本矩阵估计,后者需要s=5 – 8次迭代。因此,在进行SIFT或ORB匹配之后,通常的做法是先使用单应性矩阵进行粗略的几何验证,然后再进行完整的3D估计。

4. 分解 H:提取旋转、平移和平面法线

如果相机已标定且内部参数 K_1,K_2 已知,则可以使用平面的单位法线 \mathbf{n}(在相机 1 的坐标系中)、到平面的距离 d 和相对位姿 R,\mathbf{t} 来表示归一化的单应性矩阵 \tilde H = K_2^{-1}HK_1,如下所示:

\tilde H = R+\frac{\mathbf{t}\,\mathbf{n}^\mathsf{T}}{d}

如果相机只发生旋转而没有平移,则 \mathbf{t}=\mathbf{0},因此 \tilde H=R 即为旋转矩阵本身。

从 \tilde H 恢复 R,\mathbf{t}/d,\mathbf{n} 的过程称为单应性分解。目前已知有多种算法,包括经典的 Faugeras-Lustman 方法和解析的 Malis-Vargas 方法,它们利用 \tilde H^\mathsf{T}\tilde H 的特征分解获得闭式解。然而,仅从数学角度来看,可能存在多达 4 个物理上可能的解(包括对应于符号翻转或反射的解)。在实践中,可以通过以下方式缩小解的范围:

  • 正深度(手性):三角剖分的点必须位于两个摄像机的前方。

  • 平面法线的合理性:与应用中已知的粗略法线方向(例如地面或墙壁)保持一致。

  • 跨多帧的一致性:即使在单帧中存在歧义,但通过时间跟踪可以发现不自然的解缺乏连续性。

OpenCV 的 decomposeHomographyMat 函数执行此分解,并提供一些滤波函数(例如 filterHomographyDecompByVisibleRefpoints,它选择接近已知平面法线的解),以帮助评估多个候选解。

5. 与极线几何的关系:何时 H 是正确的答案

正如我们在极线几何入门中看到的,一般 3D 场景中的双视图对应关系由基本矩阵/本质矩阵描述。单应性矩阵是其特例,它们之间的选择如下。

情况 适用模型 原因
一般 3D 结构,带平移 F(未校准)/ E(已校准) 视差取决于深度,无法压缩到单个平面上
整个场景或感兴趣区域是一个平面 H 平面上的点可以用单应性矩阵精确描述
相机进行纯旋转(仅水平/垂直旋转) H 由于没有平移,因此不存在视差,所以 F/E 退化
观察远处的场景,视差非常小 H(实际近似) 由深度差异引起的视差会被像素噪声掩盖

问题在于,“H 存在许多内点”和“场景确实是平面的或相机确实是纯旋转的”有时仅凭观察很难区分。即使在一般的 3D 场景中,占据视野中心的墙壁或桌子也可能与单应性矩阵高度吻合。ORB-SLAM 的初始化过程通过 RANSAC 并行估计 H 和 F 来处理这种不确定性,并对每个模型的拟合优度进行评分,然后自动选择适合场景结构和相机运动的模型。实现层面的关键在于使用一个能够反映每个模型自由度差异的评分(类似于 GRIC 的思想),而不是简单地比较内点数量。

6. 应用:图像拼接、AR 平面跟踪和地面平面估计

图像拼接(全景合成)——将相机原地旋转拍摄的多幅图像组合成一幅图像——是单应性矩阵的一个典型应用。它估计相邻图像之间的单应性矩阵,并将每幅图像扭曲到同一个参考系中,然后进行融合。当相机几乎完全旋转的假设不成立时(例如边走边拍,或场景中存在近景物体),视差会导致重影和图像重叠。

增强现实中的平面锚点跟踪在第一帧中检测一个平面(例如桌子或海报),并通过跟踪后续每一帧的单应性矩阵,逐帧稳定地确定物体相对于该平面的相对姿态。利用分解后的 R,\mathbf{t}/d,您可以将锚定在平面坐标系中的虚拟物体叠加到画面上,而不会出现视觉不一致。

地面平面估计利用了道路或地面“近乎平面”的先验知识。车载摄像头或机器人中的地面平面检测方法跟踪连续帧之间的单应性矩阵,并检测偏离该矩阵的区域(障碍物、非地面物体)。这种方法检测的是几何一致性的破坏,而不是识别物体本身。

7. OpenCV 中的实现示例

import cv2 as cv
import numpy as np

orb = cv.ORB_create(nfeatures=3000)
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)
matches = cv.BFMatcher(cv.NORM_HAMMING).knnMatch(des1, des2, k=2)
good = [m for m, n in matches if m.distance < 0.75 * n.distance]

p1 = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
p2 = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)

# threshold is the allowed reprojection error, in pixels. USAC_MAGSAC is also selectable in place of RANSAC.
H, mask = cv.findHomography(p1, p2, method=cv.RANSAC, ransacReprojThreshold=3.0)
inliers = mask.ravel().astype(bool)

# if K is known, decompose into candidate solutions
num_solutions, Rs, ts, ns = cv.decomposeHomographyMat(H, K)

请注意,findHomography 返回的 H 是尺度模糊的。与极线几何入门中的本质矩阵一样,分解得到的平移向量也只能确定一个方向——其绝对尺度必须通过其他方式提供(例如已知的平面距离、立体基线、惯性传感器等)。

8. 棘手情况

  • 平面性破缺:即使看起来是平面的场景也可能包含具有实际厚度的物体——例如书籍、标志边缘、植物——这些物体上的点会成为系统性的异常值。随意放宽 RANSAC 的阈值会导致非平面点被拉入,从而扭曲 H 本身。

  • 纯旋转假设失效:如果手持拼接时包含哪怕是轻微的平移,较近的物体移动幅度更大,从而产生重影。使用三脚架或在镜头光学中心附近旋转是更佳选择。

  • 退化配置:如果对应点集中在图像中的一条线上或一个狭窄区域内,则 DLT 矩阵会变得病态,并且误差会在 H 的外推区域(远离对应点的区域)急剧上升。

  • 重复图案或低纹理平面:对于瓷砖地板或格子窗等重复图案,仅靠局部描述符无法区分正确的对应关系和偏移一个周期的错配。

  • 分解歧义:如果 K 不准确或噪声较大,则可能无法从分解得到的多个候选解中唯一地选出物理上正确的解。始终将此与额外的先验知识(法线方向、正深度)结合使用。

9. 总结

单应性矩阵是一个框架,它能用单个 3\times3 矩阵精确表示两种有限但实际中常见的场景:平面上的对应关系,或相机的纯旋转。DLT 方法是最小二乘法的起点,RANSAC 算法用于处理异常值,而分解则是提取物理旋转、平移和法线的最终阶段。最重要的是判断何时使用单应性矩阵是正确的模型,何时应该切换到基本/本质矩阵——如果判断错误,最终会试图在一个仅仅是平面的场景中恢复并不存在的深度。

检查你的理解
单应性变换能否使不同深度的物体对齐?

一般平移变换会使非平面物体产生视差。

在使用单个单应性变换之前,请检查平面场景或纯旋转假设。

参考文献

What to read next

Review the background光流入门——从图像运动中读取速度和结构Continue the series极线几何——从两幅图像中读取深度和相机运动Explore another aspect of this field图像亮度 Lab — 曝光、伽马与裁剪