3. 深度估计基础:双目视差、ToF原理、单目深度估计(传统方法)
各位同学,咱们今天聊深度估计。说白了,就是让手机知道「这个人在镜头前 1.5 米,那棵树在 20 米外」。没有这个能力,散景效果就是瞎蒙的。
我入行那会儿,手机还没深度传感器呢。全靠算法硬猜深度,效果嘛……嗯,只能说「能用」。现在硬件丰富了,但算法依然是核心。这一章,我把三种主流方案掰开揉碎了讲给你听。
3.1 双目视差:人眼怎么看的,机器就怎么学
双目深度估计的原理,其实跟人眼一样。你想想看,左右眼看到的画面有细微差别,大脑就是靠这个「视差」来判断距离的。
核心公式:深度 Z = (f × B) / d
其中 f 是焦距,B 是基线距离(两个摄像头之间的距离),d 是视差(同一物体在左右图像上的像素偏移量)。
我在项目中遇到过一个问题:两个摄像头哪怕差 0.1 毫米的安装角度,出来的视差图就全是噪点。所以硬件标定是第一步,也是最容易踩坑的一步。
双目深度估计的典型流程
- 立体标定:用棋盘格标定左右相机的内参和外参,消除畸变和对齐误差。
- 立体校正:把左右图像投影到同一个平面上,让对应点只在水平方向有偏移。
- 立体匹配:对每个像素,在另一张图上找它的「孪生兄弟」。这一步最耗时。
- 视差计算:根据匹配结果算出每个像素的视差值。
- 深度映射:用公式把视差转成深度。
我曾经踩过的坑:立体匹配时用了全局优化算法,效果是好,但手机端跑一帧要 3 秒。后来换成 SGM(半全局匹配),速度提升 20 倍,精度只降了 5%。调优就是找平衡点。
双目方案的优缺点
| 维度 | 说明 |
|---|---|
| 优点 | 被动式,不发射能量;室内室外都能用;成本低 |
| 缺点 | 依赖纹理;弱光下效果差;基线限制了有效测距范围 |
| 典型场景 | 手机前置双摄、机器人避障、自动驾驶 |
3.2 ToF 原理:用光速丈量世界
ToF(Time of Flight)就粗暴多了。我发射一束光,等它反射回来,算时间差。光速是已知的,距离自然就出来了。
你可能会问:「光速那么快,怎么计时?」嗯,这就是 ToF 芯片的厉害之处。目前主流有两种方案:
- 直接 ToF(dToF):直接测量光子往返时间。精度高,但电路复杂。苹果的 LiDAR 用的就是这种。
- 间接 ToF(iToF):发射连续调制光,通过相位差算距离。成本低,但容易受多径干扰。
我个人习惯:做手机人像模式,iToF 就够了。但如果你要做 AR 测量,必须上 dToF。精度差一个数量级。
ToF 的典型参数
| 参数 | dToF | iToF |
|---|---|---|
| 测距范围 | 0.1m - 10m+ | 0.3m - 5m |
| 精度 | ±1cm | ±3cm |
| 功耗 | 较高 | 较低 |
| 抗干扰 | 强 | 弱(多径效应) |
注意:ToF 在强光下会饱和。大太阳底下拍人像,深度图经常出现「黑洞」。我一般会加一个置信度掩膜,把这些区域标记出来,交给单目算法去补。
3.3 单目深度估计(传统方法):没有硬件,全靠算力
单目深度估计,说白了就是「猜」。一张图,没有立体信息,怎么知道远近?传统方法靠的是各种视觉线索。
传统单目深度线索
- 线性透视:铁轨在远处汇聚,越近越宽。这是最直观的线索。
- 纹理梯度:近处的纹理清晰、细节多;远处的纹理模糊、细节少。
- 遮挡关系:前面的物体会挡住后面的物体。这个线索很可靠,但只能给出相对深度。
- 相对大小:同样的人,近处的大,远处的小。前提是你知道物体的大小。
- 大气散射:远处的物体颜色偏蓝、对比度低。风景照里特别明显。
我记得早期做单目深度估计,用的是「基于图割」的方法。把图像分割成超像素,然后用手工特征(比如颜色、纹理、位置)去训练一个回归模型。效果嘛……只能说「比随机好一点」。
传统方法的局限:依赖场景假设。比如「地面在图像下方,天空在上方」。换个场景,比如拍天花板,模型就崩了。
传统方法与深度学习的对比
| 维度 | 传统方法 | 深度学习方法 |
|---|---|---|
| 特征 | 手工设计(SIFT、HOG、颜色直方图) | 自动学习(CNN、Transformer) |
| 泛化能力 | 弱,场景依赖强 | 强,数据量大时效果好 |
| 计算量 | 低,可实时 | 高,需要 GPU |
| 精度 | 低(相对深度) | 高(可达到深度) |
3.4 三种方案的知识图谱
下面这张图,是我自己整理的三种深度估计方案的对比框架。你把它存下来,以后做方案选型时直接翻出来看。
3.5 实战中的融合策略
你可能会问:「那我到底该用哪种?」
我的答案是:别只用一种。现在的旗舰手机,基本都是多传感器融合。比如 iPhone 的 LiDAR(dToF) + 双目 + 单目深度学习,三重保险。
我建议的融合策略:
- ToF 提供低分辨率的深度(比如 240×180),作为「锚点」。
- 双目提供中分辨率的视差图(比如 640×480),填充细节。
- 单目深度学习做上采样和边缘修复,输出全分辨率深度图。
这样既保证了精度,又控制了功耗。我在项目里试过,比单用 ToF 的深度图边缘锐利度提升 40%。
3.6 避坑指南
- 标定是万恶之源:双目和 ToF 的联合标定,稍微偏一点,融合出来的深度图就是花的。我建议每 3 个月重新标定一次。
- 时间同步:ToF 和 RGB 相机的帧率可能不同。不做时间同步,运动物体就会出现「鬼影」。我一般用硬件触发信号来同步。
- 边缘处理:深度图的边缘往往不准。头发丝、眼镜框这些地方,我习惯用 RGB 图像的边缘检测结果来引导深度图修复。
我曾经犯过的错:为了追求深度图的分辨率,把 ToF 的深度图上采样到 1080P。结果边缘全是锯齿,散景效果反而更差了。后来我学乖了——深度图的分辨率够用就行,别盲目追求高分辨率。