2. 深度估计基础

聊到人像模式的散景效果,核心其实就两个字——深度。你想想看,手机怎么知道哪个人是前景、哪块背景该虚化?靠的就是深度估计。这一章,咱们把地基打牢。

什么是深度图?一张“灰度地图”

深度图,说白了就是一张灰度图。每个像素的值代表场景中那个点到相机的距离。值越大(越亮),物体越远;值越小(越暗),物体越近。

深度图 ≠ 视差图 ≠ 视差图 很多人刚入门容易搞混。深度图是物理距离(单位毫米/米),视差图是左右视图的像素偏移量(单位像素)。两者可以通过相机参数互相转换,但概念上别混为一谈。

举个例子。一张 640×480 的 RGB 图,对应一张同样分辨率的深度图。像素 (200, 300) 的深度值是 1200mm,说明那个点离相机 1.2 米。整张图就是场景的“距离快照”。

我早期做双目深度估计时,第一次看到生成的深度图——人脸区域一片漆黑,背景墙壁灰白,边缘还有毛刺。嗯,那质量确实惨不忍睹。但也正是那张图让我意识到:深度估计的精度,直接决定了后续散景渲染的成败。

深度估计的应用场景:不止是虚化

很多人以为深度估计只用来做背景虚化。其实它的应用范围广得多。我列几个常见的:

  • 人像模式 / 背景虚化:手机摄影的招牌功能。通过深度图区分前景人物和背景,对背景做高斯模糊或光学模拟模糊。
  • AR / VR 交互:虚拟物体要“贴”在真实场景中,必须知道每个平面的深度。否则虚拟杯子会飘在空中,穿帮。
  • 自动驾驶:车辆需要知道前方障碍物的距离。深度估计是感知模块的标配。
  • 3D 重建:多视角深度图融合,可以生成场景的三维点云模型。
  • 机器人抓取:机械臂要抓取物体,得知道物体在空间中的精确位置和姿态。

我的经验:在手机人像模式中,深度图的分辨率往往不需要太高。320×240 的深度图配合边缘细化,就能做出不错的虚化效果。但自动驾驶场景就不行——低分辨率深度图会导致障碍物测距误差过大,直接威胁安全。

传统方法与深度学习方法对比

深度估计不是新概念。早些年没有深度学习的时候,大家也做了很多尝试。我简单梳理一下两者的核心差异。

对比维度 传统方法 深度学习方法
核心原理 几何约束、手工特征 端到端学习、数据驱动
输入要求 通常需要双目/多视图 单目即可(单张 RGB)
计算速度 较慢(全局优化耗时) 快(前向推理,可 GPU 加速)
精度 纹理丰富区域尚可,弱纹理区域差 整体精度高,泛化能力强
鲁棒性 对光照、遮挡敏感 对光照、遮挡有一定容忍度
代表方法 SGM、PatchMatch、MRF MiDaS、DPT、BTS、AdaBins

传统方法里,我印象最深的是 SGM(半全局匹配)。它通过多个方向的动态规划来近似全局优化,效果比局部匹配好不少。但有个致命问题——计算量太大。我在一个嵌入式项目里试过,640×480 的图,SGM 跑了将近 2 秒。这速度,做实时人像模式?想都别想。

深度学习方法就不一样了。以 MiDaS 为例,它用混合数据集训练,输入单张 RGB 图,直接输出深度图。前向推理在手机上也能跑到 30fps 以上。精度嘛,比传统方法高出一大截。

注意:深度学习方法的深度估计是“相对深度”,不是物理距离。它只能告诉你 A 点比 B 点近,但不知道具体近多少毫米。要得到深度,需要额外的标定或后处理。我在项目中踩过这个坑——直接用相对深度做虚化,结果背景模糊程度忽大忽小,很不自然。

知识结构总览

下面这张图,把本章的核心知识点串起来了。你可以把它当作一个快速索引。

深度估计知识结构 深度估计 深度图概念 应用场景 方法对比 灰度图 像素=距离 亮远暗近 与视差图区别 人像虚化 AR/VR 自动驾驶 3D重建 传统方法 深度学习方法 SGM / MRF MiDaS / DPT 核心:深度图是场景的“距离快照”,传统方法靠几何,深度学习方法靠数据 人像模式中,深度图质量直接决定虚化效果的自然度

传统方法:SGM 的“挣扎”

传统方法里,SGM 算是经典中的经典。它的思路是:把深度估计看作一个能量函数最小化问题。能量函数包含数据项(匹配代价)和平滑项(相邻像素深度应相近)。

但 SGM 有个硬伤——弱纹理区域。一面白墙,左右视图看起来一模一样,匹配代价算出来全是平的。SGM 只能靠平滑项“硬猜”,结果就是深度图上一片模糊。

我曾在某个安防监控项目里用 SGM 做行人深度估计。白天光线好还行,一到晚上,画面噪点一多,深度图直接崩了——行人轮廓和背景糊在一起,根本分不清。

深度学习方法:MiDaS 的“降维打击”

深度学习方法,尤其是 MiDaS,彻底改变了游戏规则。它用混合数据集训练(包含室内、室外、立体、激光扫描等多种来源),学会了从单张 RGB 图推断深度的能力。

MiDaS 的核心是编码器-解码器结构。编码器提取多尺度特征,解码器逐步恢复分辨率,最后输出深度图。它还用了一个技巧——多尺度融合,把不同尺度的特征拼接起来,保留细节和全局结构。

实用建议:如果你要在手机上部署深度估计模型,别直接用 MiDaS 原版(太大)。可以试试轻量化的版本,或者用知识蒸馏压缩模型。我在一个项目中把 MiDaS 从 200MB 压缩到 15MB,精度只掉了 3%,但推理速度从 200ms 降到了 30ms。

传统 vs 深度学习:怎么选?

这个问题没有标准答案。我个人的经验是:

  • 有双目/多视图输入,且计算资源有限:传统方法还能一战。比如嵌入式设备上的双目深度估计,SGM 优化后也能跑到实时。
  • 只有单张 RGB 图,且对精度要求高:无脑选深度学习方法。MiDaS、DPT、BTS 都是好选择。
  • 需要深度:传统方法更容易得到深度(通过三角测量)。深度学习方法需要额外标定或后处理。
  • 需要实时性:深度学习方法经过优化后,在 GPU/NPU 上可以跑得很快。传统方法在 CPU 上也能优化,但上限有限。

避坑提醒:我曾经在一个项目里试图用传统方法做单目深度估计——用了各种手工特征(SIFT、LBP、HOG),结果精度惨不忍睹。单目深度估计本身是病态问题(一张图丢失了深度信息),传统方法没有数据支撑,根本解不了。别在这上面浪费时间。