3. 相机成像模型

聊到人像模式,绕不开一个核心问题:手机怎么知道物体离我有多远?

答案就藏在相机成像模型里。说白了,我们得先搞懂相机是怎么「看」世界的,才能教它算出深度。这一章我会从最经典的针孔模型讲起,再带你理解视差和深度的关系,最后落到双目立体视觉——这也是很多手机双摄方案的理论基础。

3.1 针孔相机模型:最朴素的成像方式

针孔相机模型,是所有相机模型的起点。它简单到令人发指:一个不透光的盒子,前面戳个小孔,后面放一张感光底片。

光线从物体表面反射,穿过小孔,在底片上形成一个倒立的像。这就是最原始的成像过程。

核心公式(投影关系):

X_screen = f * (X_world / Z_world)
Y_screen = f * (Y_world / Z_world)

其中 f 是焦距(小孔到成像平面的距离),(X_world, Y_world, Z_world) 是物体在三维空间中的坐标,(X_screen, Y_screen) 是像点在成像平面上的位置。

这个公式告诉我们一件事:物体越远(Z_world 越大),它在成像平面上的投影就越小。反过来,近处的物体看起来更大。这就是透视效应的数学本质。

我在项目中遇到过一个问题:用针孔模型标定手机摄像头时,发现边缘区域畸变特别严重。后来才意识到,针孔模型是理想情况,真实镜头有透镜,必须引入畸变参数才能校正。嗯,这个坑我踩过,后面讲相机标定时会细说。

3.2 从针孔到数字图像:内参矩阵

实际相机不是用物理底片,而是用 CMOS 传感器把光信号转成像素。所以我们需要把成像平面上的物理坐标,映射到像素坐标上。

这个映射关系,就是相机内参矩阵 K:

K = [[fx,  0, cx],
     [ 0, fy, cy],
     [ 0,  0,  1]]
  • fx, fy:焦距在 x 和 y 方向上的像素单位(通常很接近)
  • cx, cy:光心在像素坐标系中的位置(一般是图像中心附近)

有了内参矩阵,我们就可以把三维空间中的点,投影到二维像素坐标上:

pixel_u = fx * (X_world / Z_world) + cx
pixel_v = fy * (Y_world / Z_world) + cy

我的习惯:拿到一台新手机或相机,第一件事就是标定内参。很多深度估计算法精度上不去,其实就是内参没标准。别问我怎么知道的……

3.3 视差与深度:一对天生的冤家

单目相机只能得到二维投影,丢失了深度信息。那怎么找回深度?答案是:用两个相机看同一个点。

你想想看,人的两只眼睛为什么长在两边?就是为了产生视差。左右眼看到的同一物体,在视网膜上的位置是有偏移的,这个偏移量就是视差。

视差和深度的关系,可以用一个极其简洁的公式表达:

深度-视差公式:

Z = (f * B) / d

其中:

  • Z:物体到相机的深度(距离)
  • f:相机焦距(像素单位)
  • B:两个相机之间的基线距离
  • d:视差值(左右图像中对应点的像素偏移)

这个公式告诉我们:视差越大,物体越近;视差越小,物体越远。而且深度和视差成反比——近处的物体视差变化剧烈,远处的物体视差变化平缓。

我曾经在做一个双目测距项目时,发现远处物体的深度抖动特别厉害。后来一分析,就是因为视差太小,量化误差被放大了。所以双目系统对远距离物体的深度估计,天生就不准。这也是为什么人像模式主要关注近景——散景效果本来就在近处才明显。

3.4 双目立体视觉:从两幅图算出深度图

双目立体视觉的流程,说白了就是三步:

  1. 图像校正:把左右两张图拉平,让对应的像素点在同一行上
  2. 立体匹配:在左图中选一个点,去右图的同一行上找它的匹配点
  3. 三角测量:根据匹配点的偏移量(视差),用上面的公式算出深度

这里面最核心、也最难的,是第二步——立体匹配。你想想看,左图的一个像素点,怎么在右图上找到它的「另一半」?

常用的方法有:

方法 原理 优缺点
块匹配(Block Matching) 以像素为中心取一个小窗口,计算左右窗口的相似度 速度快,但纹理弱区域容易出错
SGM(半全局匹配) 在块匹配基础上加入平滑约束,沿多个方向优化 精度高,速度适中,工业界常用
深度学习匹配 用 CNN 提取特征,计算匹配代价 精度最高,但需要 GPU,功耗大

注意:立体匹配有一个前提——左右图像必须已经极线校正过。如果没有校正,匹配点可能出现在不同行上,搜索空间从一维变成二维,计算量爆炸。我见过有人直接拿原始双目图像做匹配,结果跑了一天都没出结果……

3.5 知识结构总览

下面这张图,把本章的核心逻辑串起来了。你可以把它当作一个思维导图来看:

相机成像模型知识结构 相机成像模型 针孔相机模型 视差与深度关系 双目立体视觉 投影公式 内参矩阵 K Z = fB / d 反比关系 图像校正 立体匹配 块匹配 SGM 深度学习 核心逻辑 针孔模型 → 内参矩阵 → 双目成像 → 立体匹配 → 视差图 → 深度图

3.6 从理论到实战:双目系统的局限

理论讲完了,说点实际的。双目立体视觉在手机上做人像模式,有几个绕不开的坎:

  • 基线限制:手机两个摄像头之间的距离就那么几厘米,导致视差范围很小,深度分辨率有限
  • 弱纹理区域:拍一面白墙,左右图看起来一模一样,立体匹配直接失效
  • 遮挡问题:左图能看到的点,右图可能被前景挡住,匹配不到
  • 计算量:实时做全图立体匹配,手机芯片的功耗和发热是个大问题

我的建议:如果你在手机上做深度估计,别只依赖双目。现在的主流方案都是双目 + ToF + 深度学习多模态融合。单靠双目,在复杂场景下很容易翻车。