2D-2D对极几何:从对极约束到单应矩阵

各位同学,今天我们来聊聊视觉里程计里最基础、也最核心的一块——2D-2D对极几何

说实话,我刚入行那会儿,对极几何这玩意儿看得我头大。什么本质矩阵、基础矩阵,一堆数学公式。后来做项目踩了坑才明白,这些东西说白了就是解决一个问题:两张图片之间,相机到底动了多少?

嗯,咱们今天就把这块彻底讲透。

1. 对极约束:两张图之间的几何关系

想象一下,你拿着相机拍了两张照片。第一张里有个点P,第二张里也有个点P'。这两个点之间有什么几何关系?

我习惯这么理解:对极约束就是告诉你,P'一定在一条特定的直线上。这条线叫对极线。

为什么会这样?

你看啊,第一张图的相机中心O₁,第二张图的相机中心O₂,加上空间点P,这三个点构成了一个平面——对极平面。这个平面与第二张图的成像平面相交,那条交线就是对极线。

所以,P'一定在这条线上。这就是对极约束的核心思想。

核心公式:

x₂ᵀ · F · x₁ = 0

其中x₁、x₂是归一化平面上的点,F是基础矩阵。

我在项目中遇到过一个问题:如果两张图的匹配点太少,对极约束就不好使了。所以,匹配点数量至少得8对以上,这是八点法的基本要求。

2. 本质矩阵E与基础矩阵F

这两个矩阵,很多初学者容易搞混。我简单说说我的理解。

本质矩阵E:它只包含相机的旋转R和平移t的信息。说白了,就是相机在三维空间里怎么动的。

基础矩阵F:它除了包含R和t,还包含了相机的内参K。所以F = K⁻ᵀ · E · K⁻¹。

你想想看,如果相机内参已知,我们直接用E就够了。如果内参未知,那就得用F。

矩阵 包含信息 自由度 适用场景
本质矩阵E R, t 5 内参已知
基础矩阵F R, t, K 7 内参未知

我的小技巧:实际工程中,我一般先用E,因为它的自由度少,求解更稳定。除非相机内参真的不确定,才用F。

3. 八点法求解:从匹配点到矩阵

好了,理论讲完了,咱们来点实际的。怎么从一堆匹配点里算出E或F?

最经典的方法就是八点法。名字很直白,至少需要8对匹配点。

步骤是这样的:

  1. 收集8对以上的匹配点 (x₁, x₂)
  2. 构建线性方程组 A·f = 0
  3. 用SVD分解求解f
  4. 将f重构成3×3矩阵
  5. 强制满足奇异值约束(对E来说,两个奇异值相等,第三个为0)

代码实现其实不复杂:

def eight_point_algorithm(points1, points2):
    # 构建A矩阵
    A = np.zeros((len(points1), 9))
    for i in range(len(points1)):
        x1, y1 = points1[i]
        x2, y2 = points2[i]
        A[i] = [x2*x1, x2*y1, x2, y2*x1, y2*y1, y2, x1, y1, 1]
    
    # SVD求解
    U, S, Vt = np.linalg.svd(A)
    F = Vt[-1].reshape(3, 3)
    
    # 强制秩为2
    U, S, Vt = np.linalg.svd(F)
    S[2] = 0
    F = U @ np.diag(S) @ Vt
    
    return F

注意:八点法对噪声非常敏感。我曾经在室外场景测试,匹配点稍微有点偏差,算出来的E就完全不对了。所以,一定要先做归一化,把点的坐标缩放到[-1, 1]之间。

4. 单应矩阵H:平面场景的利器

聊完E和F,咱们再来说说单应矩阵H。

H和E/F最大的区别是什么?H假设场景中的点都在同一个平面上

你想想看,如果拍的是墙面、地面、桌面,这些平面场景,用H就特别合适。H描述的是两个平面之间的投影变换。

H的求解只需要4对匹配点(不共线),比八点法少一半。而且H的鲁棒性更好,对噪声不那么敏感。

我个人的经验是:如果场景近似平面,优先用H。比如无人机拍地面、机器人拍天花板,H的效果远好于E/F。

H的公式也很直观:

x₂ = H · x₁

求解方法类似,也是构建线性方程组,然后用SVD或直接线性变换(DLT)求解。

什么时候用E/F,什么时候用H?

  • 场景有深度变化(比如有近景有远景)→ 用E/F
  • 场景近似平面(比如墙面、地面)→ 用H
  • 相机纯旋转 → 只能用H,因为E/F在纯旋转时退化了

5. 知识体系总览

说了这么多,我画了一张图,帮你把今天的内容串起来:

2D-2D对极几何知识体系 两张图像 + 匹配点 场景是否近似平面? 单应矩阵 H 本质矩阵E / 基础矩阵F 4点法 / DLT 八点法 / SVD R, t (纯旋转时退化) R, t (需三角化验证)

6. 避坑指南

最后,分享几个我踩过的坑:

  • 匹配点质量比数量重要:我曾经用100对匹配点算E,结果不如20对高质量点。所以,先做RANSAC剔除误匹配。
  • 纯旋转场景别用E/F:相机只旋转不平移时,E/F会退化,算出来的t是错的。这时候只能用H。
  • 别忘了归一化:八点法不归一化,结果基本不能用。这是很多初学者容易忽略的。
  • 三角化验证:算出来的R和t对不对?把点三角化到三维空间,看看重投影误差。这是最直接的验证方法。

好了,2D-2D对极几何的核心内容就这些。记住,理论是基础,实践出真知。多写代码、多跑数据,才能真正理解这些矩阵背后的几何意义。

专注资料整理