3. 极线几何与对极约束:极线、极点与基础矩阵、本质矩阵、单应性矩阵,以及如何通过极线校正简化匹配
做立体匹配这些年,我越来越觉得极线几何是个绕不开的坎儿。说白了,它就是双目视觉的「几何骨架」。你想想看,左右两张图里同一个点到底在哪?怎么找最快?极线几何就是回答这个问题的。
3.1 极线、极点——视觉里的「约束」
先聊个直观的。你闭上一只眼,用另一只眼看桌上的杯子。然后换只眼。你会发现杯子在背景上「跳」了一下。这个跳动的轨迹,就是极线。
在数学上,左图中的一个点,在右图中一定落在某条直线上。这条线就叫极线。所有极线都交于一点,那就是极点。极点是什么?说白了,就是两个相机光心的连线与成像平面的交点。
核心结论:极线约束把二维搜索降到了一维。原本要在整张图上找匹配点,现在只需要沿着一条线找。速度提升可不是一星半点。
我记得刚入行时,有个项目要在嵌入式设备上做实时匹配。那时候算力有限,整图搜索根本跑不动。后来用了极线约束,直接把搜索范围从几百像素宽缩到几十像素。嗯,效果立竿见影。
3.2 基础矩阵与本质矩阵——数学表达
极线几何的数学核心,就是这两个矩阵。我习惯这么区分:
- 本质矩阵 E:只包含旋转和平移信息。它工作在归一化坐标系下,跟相机内参无关。
- 基础矩阵 F:包含了内参。它直接作用于像素坐标。
两者的关系很简单:F = K-T E K-1。K 是相机内参矩阵。
实际项目中,我一般先算基础矩阵。为什么?因为很多时候内参标定得不够准,直接用本质矩阵反而容易出问题。基础矩阵直接从匹配点对算出来,更鲁棒。
怎么算?八点法就够了
八点法是最经典的方法。给定至少8对匹配点,就能解出基础矩阵。代码实现其实不复杂:
// 伪代码:八点法计算基础矩阵
// 输入:左右图像匹配点对 (x1, y1) 和 (x2, y2)
// 输出:3x3 基础矩阵 F
1. 构建矩阵 A,每对点贡献一行:
A[i] = [x2*x1, x2*y1, x2, y2*x1, y2*y1, y2, x1, y1, 1]
2. 对 A 做 SVD 分解:A = U * S * V^T
3. F 的初始值 = V 的最后一列,reshape 成 3x3
4. 对 F 再做 SVD,强制其秩为 2(最小特征值置零)
5. 返回 F
我的经验:用八点法之前,一定要对坐标做归一化。把点平移到原点,再缩放到均值为1。不做这步,数值稳定性会很差。我曾经因为这个踩过坑,算出来的 F 矩阵完全不能用。
3.3 单应性矩阵——平面场景的「特例」
单应性矩阵 H 描述的是两个平面之间的映射关系。它跟基础矩阵最大的区别是什么?
- 基础矩阵:描述的是点与极线的对应关系。一个点对应一条线。
- 单应性矩阵:描述的是点与点的直接对应。一个点对应一个点。
什么时候用单应性?场景近似在一个平面上时。比如拍一面墙、一块广告牌。或者相机纯旋转时(没有平移)。
我做过一个项目,需要拼接多张图片。那时候场景基本是平面(地面),用单应性矩阵做配准,又快又准。但如果场景有深度变化,单应性就不灵了,必须上基础矩阵。
3.4 极线校正——让匹配变得「无脑」
这是我最喜欢的一步。极线校正的目的,就是把左右图像「掰正」,让极线变成水平的。
校正之后,左图的点 (x, y) 在右图中的匹配点一定在 (x', y) 上。注意,y 坐标相同!这意味着搜索从二维变成了一维,而且是一维水平搜索。
校正后的好处:
- 匹配速度大幅提升(只需沿水平方向搜索)
- 可以用简单的行缓存做硬件加速
- 视差图直接反映深度信息
校正的步骤大致是:
- 根据基础矩阵或本质矩阵,分解出旋转和平移
- 构造新的旋转矩阵,让两个相机的光轴平行
- 重采样图像,生成校正后的左右视图
注意:校正会引入图像裁剪和插值失真。尤其是图像边缘,信息会丢失一部分。我建议在校正前先适当扩大图像边界,或者用更高分辨率的图像做输入。
3.5 知识体系总览
下面这张图是我自己梳理的极线几何知识结构,方便你快速把握全局:
3.6 避坑指南
最后分享几个我踩过的坑:
- 匹配点质量比数量重要。我曾经用几百对点算基础矩阵,结果还不如几十对高质量点。一定要先用 RANSAC 剔除误匹配。
- 校正后的图像要检查。有时候校正参数算错了,图像会扭曲得很厉害。我习惯在校正后画几条水平线,看看左右图的对应点是否真的在同一行上。
- 单应性矩阵别乱用。场景有深度变化时,用单应性做匹配会出大问题。我见过有人拿它做街景匹配,结果一塌糊涂。
极线几何这东西,刚开始觉得抽象。但一旦理解了它的几何意义,你会发现它其实很直观。说白了,就是给匹配加了个「轨道」,让搜索沿着轨道跑就行了。
公众号:蓝海资料掘金营,微信deep3321