1. 立体视觉概述:双目立体视觉的原理、视差与深度的关系、立体匹配的挑战与评价指标
1.1 为什么我们需要两只眼睛?
先问大家一个问题:你闭上一只眼睛,还能准确判断距离吗?
试试看。伸手去拿桌上的水杯——是不是感觉有点拿不准?
这就是立体视觉的核心价值。我们人类用两只眼睛看世界,左右眼看到的画面其实有细微差别。大脑利用这种差别,就能算出物体的远近。说白了,这就是一套天然的深度感知系统。
我刚开始接触这个领域时,觉得这事儿挺神奇的。后来做了几个项目才明白,原理其实不复杂,但工程实现上坑特别多。
1.2 双目立体视觉的原理
双目立体视觉,就是模仿人眼的工作方式。我们用两个摄像头,左右各一个,同时拍摄同一场景。因为两个摄像头的位置不同,同一个物体在左右图像上的位置会有偏移。这个偏移量,就是我们常说的视差。
嗯,这里有个关键点:两个摄像头的光轴要尽量平行。如果歪了,后面校正起来会很麻烦。我在项目中遇到过摄像头安装偏差导致匹配失败的情况,后来花了整整两天做标定才搞定。
整个流程大致是这样的:
- 图像采集:左右相机同步拍摄
- 立体校正:把图像对齐到同一水平线上
- 立体匹配:找到左右图像中对应的像素点
- 视差计算:算出每个点的偏移量
- 深度恢复:根据视差算出实际距离
你想想看,这里面最核心、最难的步骤是什么?没错,就是立体匹配。后面我们会花大量篇幅讲这个。
1.3 视差与深度的关系
这个关系其实就是一个简单的几何公式。我直接给出来:
深度 Z = (基线距离 B × 焦距 f) / 视差 d
其中:
- B:左右相机光心之间的距离
- f:相机的焦距
- d:对应点的视差值
从公式可以看出,视差和深度成反比。物体越近,视差越大;物体越远,视差越小。当物体在无穷远处时,视差趋近于零。
我记得有一次做自动驾驶项目,需要检测前方100米外的车辆。当时算了一下,视差只有几个像素。这就意味着,哪怕一个像素的误差,深度误差都会被放大很多倍。所以,远距离测距对匹配精度要求极高。
重要结论:视差精度直接决定深度精度。在近距离(5米以内),视差误差对深度影响较小;在远距离(50米以上),视差误差会被急剧放大。
下面这张图展示了双目立体视觉的核心逻辑:
1.4 立体匹配的挑战
立体匹配听起来简单,做起来难。我做了这么多年,踩过的坑能写一本书。这里挑几个最常见的挑战说说:
1.4.1 遮挡问题
左眼能看到的地方,右眼不一定能看到。比如一个物体挡住了另一个物体的一部分。这部分区域在另一张图像里根本找不到对应点。怎么办?
我曾经在一个项目里遇到大面积遮挡,匹配结果惨不忍睹。后来用了左右一致性检测,才把错误匹配筛掉。
1.4.2 弱纹理区域
一面白墙,或者一片蓝天。像素值几乎一样,你让算法怎么匹配?
说白了,这就是信息不足。我习惯的做法是引入全局约束,或者用深度学习的方法提取更鲁棒的特征。
1.4.3 重复纹理
比如百叶窗、格子衬衫。每个窗口看起来都一样,算法很容易匹配到错误的位置。
嗯,这里要注意,单纯靠局部特征很难区分。我建议结合视差平滑性约束,或者用更大范围的上下文信息。
1.4.4 光照变化
左右相机曝光参数不同,或者场景中有强光源。同一物体在左右图像上的亮度不一样,匹配难度就上去了。
我记得有一次在室外做测试,太阳从侧面照过来,左右图像亮度差异巨大。后来加了光照归一化预处理,效果才好转。
1.4.5 深度不连续
物体边缘处,深度会突然变化。比如桌子和后面的墙。这些区域容易出现匹配错误。
避坑指南:我曾经在深度不连续区域吃过亏。当时用了简单的局部匹配算法,结果物体边缘全是毛刺。后来改用带边缘保持的代价聚合方法,才把边缘质量提上来。
1.5 评价指标
算法好不好,得有标准来衡量。我常用的评价指标有这几个:
| 指标 | 全称 | 含义 | 理想值 |
|---|---|---|---|
| RMSE | Root Mean Square Error | 预测视差与真实视差的均方根误差 | 越小越好 |
| Bad Pixel Rate | Bad Pixel Percentage | 误差超过阈值(如1像素)的像素占比 | 越低越好 |
| MAE | Mean Absolute Error | 预测视差与真实视差的平均绝对误差 | 越小越好 |
| Runtime | — | 处理一帧图像所需时间 | 实时应用需<33ms |
| Density | — | 有效视差值的像素占比 | 越高越好 |
你想想看,这些指标之间其实是有 trade-off 的。比如你想让 Bad Pixel Rate 很低,可能就要用更复杂的算法,Runtime 就上去了。做工程嘛,就是在这些指标之间找平衡。
个人经验:我一般先用 Bad Pixel Rate(阈值1像素)作为主要指标,因为它在实际应用中最能反映深度图的质量。如果 Bad Pixel Rate 低于5%,基本就能用了。当然,具体阈值要看你的应用场景——自动驾驶要求高,AR/VR 可以适当放宽。
1.6 本章小结
这一章我们聊了立体视觉的基本原理。说白了,就是用两个相机模拟人眼,通过视差算深度。公式很简单:Z = Bf / d。但实际做起来,遮挡、弱纹理、光照变化这些问题一个接一个。
评价指标方面,我建议重点关注 Bad Pixel Rate 和 Runtime。这两个指标直接决定了你的算法能不能落地。
嗯,立体匹配这条路很长,但每一步都值得。后面我们会深入每个环节,把坑一个个填上。