4. 极线约束:匹配点为什么只在同一行
讲完对极几何,咱们终于可以聊聊极线约束了。
说实话,我第一次接触这个概念时,觉得它特别玄乎。什么极线、极点、极平面……听着像天书。但后来我亲手写了一个双目匹配程序,才发现——极线约束其实就是一句话:左图上的一个点,它的匹配点一定在右图的某一条直线上。
而且更妙的是,在标准双目系统中,这条线就是水平线。说白了,就是同一行。
4.1 什么是极线
咱们先看一个场景。
你左眼看一个物体,右眼看同一个物体。两个眼睛的视线在空间中交叉。现在,左眼视网膜上有一个点,它对应的是空间中某个点P的像。那么,这个点P在右眼视网膜上的像,会出现在哪里?
答案:一定在一条特定的直线上。这条线,就叫极线。
极线的本质:左图点pL、右相机光心OR、空间点P,这三个点确定了一个平面(极平面)。这个平面与右相机成像平面的交线,就是极线。
我习惯用一个比喻来理解:想象你拿一根激光笔,从左边相机射出一束光,穿过左图上的某个像素点,射向空间。这束光在空间中是一条射线。右边相机看到的,就是这条射线在右图上的投影——一条直线。
为什么会是一条线,而不是一个点?
因为左图上的一个像素点,对应的是空间中的一条射线(深度未知)。这条射线上的所有点,在右图上的像连起来,就是一条直线。
4.2 为什么匹配点只在同一行
好,现在关键问题来了:为什么在标准双目系统中,极线是水平的?
这其实是一个设计结果,不是自然规律。
我当年做第一个双目系统时,随便把两个摄像头绑在一起就开干了。结果匹配的时候发现,极线是斜的,匹配点得在整张图上搜,慢得要命。后来我才意识到——只有把两个相机严格平行放置,极线才会变成水平线。
具体来说,需要满足两个条件:
- 两个相机的光轴平行(朝向同一个方向)
- 两个相机的成像平面共面(在同一平面上)
满足这两个条件后,左图和右图的极线就变成了同一行。这就是所谓的标准立体配置。
我的经验:实际项目中,很难把两个相机装得绝对平行。所以我们会先做一步立体校正,把图像重新投影,让极线变成水平。这一步在OpenCV里叫 stereoRectify,我几乎每个项目都会用到它。
你想想看,如果极线是水平的,匹配就变成了一个一维搜索问题。原来要在二维平面上搜,现在只需要在同一行上从左到右搜。计算量直接从O(n²)降到了O(n)。
4.3 极线约束如何简化匹配
咱们用数字说话。
假设左图有1000×1000个像素,右图同样大小。如果不做任何约束,左图上的一个点,需要在右图的100万个像素里找匹配。这显然不现实。
有了极线约束后,左图上的一个点,只需要在右图的同一行上搜索。一行只有1000个像素。搜索空间缩小了1000倍。
而且,极线约束还带来了另一个好处——减少了误匹配。因为候选点少了,错误的匹配自然就少了。
| 匹配方式 | 搜索空间 | 计算量 | 误匹配率 |
|---|---|---|---|
| 无约束(全图搜索) | 1000×1000 = 1,000,000 像素 | 极高 | 高 |
| 极线约束(行搜索) | 1×1000 = 1000 像素 | 低 | 低 |
| 极线约束 + 视差范围限制 | 1×200(假设视差范围200) | 极低 | 极低 |
我曾经在一个项目中,需要做实时深度估计。如果全图搜索,一帧要算好几秒。用了极线约束后,一帧只需要几十毫秒。差距就是这么大。
注意:极线约束只告诉我们匹配点在哪条线上,但没告诉我们具体是线上的哪个点。所以还需要配合其他方法(如灰度匹配、特征匹配)来找到精确位置。
4.4 极线约束的数学表达
虽然咱们是零基础课程,但我觉得还是有必要提一下数学形式。别怕,很简单。
极线约束可以用一个公式表达:
pRT · F · pL = 0
其中:
pL是左图上的点坐标pR是右图上的点坐标F是基础矩阵(Fundamental Matrix),它编码了两个相机之间的几何关系
这个公式的意思是:如果pL和pR是匹配点,那么它们一定满足这个等式。反过来,如果满足这个等式,它们就有可能是匹配点。
我刚开始学的时候,觉得这个公式很抽象。后来我写代码时发现,其实只需要调用OpenCV的 findFundamentalMat 函数,就能算出F矩阵。然后用它来验证匹配点是否满足极线约束。
4.5 极线约束的完整流程
下面这张图展示了极线约束在双目匹配中的位置:
流程很清晰:
- 先输入左右图像
- 做立体校正,让极线变成水平
- 利用极线约束,只在同一行上搜索匹配点
- 沿极线做匹配搜索
- 计算视差,生成深度图
嗯,这里要注意:立体校正是极线约束的前提。如果校正没做好,极线不是水平的,那行搜索就不成立了。我见过不少新手,校正参数没调好就直接跑匹配,结果出来的深度图全是噪声。
4.6 避坑指南
最后,分享几个我踩过的坑:
- 不要以为相机标定一次就够了:相机在使用过程中可能会松动,尤其是车载或机器人场景。我建议每次项目开始前都重新标定一次。
- 极线约束不是万能的:它只能缩小搜索范围,不能解决所有匹配问题。比如纹理稀疏的区域、重复纹理的区域,即使在同一行上,匹配也可能出错。
- 注意图像畸变:如果镜头畸变严重,极线会弯曲。必须先做畸变校正,再做立体校正。
我的习惯:在写匹配代码前,我会先画几根极线在图像上,肉眼确认它们确实是水平的。这一步虽然简单,但能避免很多后续的调试痛苦。
极线约束,说白了就是利用几何知识,把匹配问题从二维降到了一维。它不复杂,但非常实用。掌握了它,你的双目匹配效率能提升好几个数量级。