双目相机测距原理(完整流程版)

之前讲了三角测距的几何原理,这次聚焦双目相机这个具体设备,把从 "两个摄像头拍照片" 到 "输出每个像素的距离" 的完整链路拆开讲。


一、双目相机是什么

两个完全相同的摄像头,水平并排固定安装,间距为基线 B。

plaintext

左目摄像头 ──── 基线B ──── 右目摄像头
      \                      /
       \                    /
        \                  /
         \                /
          \              /
           \            /
            ● 目标物体
  • 两个摄像头同时拍摄同一场景;
  • 因为位置不同,同一个物体在左右图像中的像素位置不一样(这个偏差叫视差);
  • 视差越大 → 物体越近;视差越小 → 物体越远。

本质就是人眼双目视觉的工程复刻 —— 你的左眼和右眼看到的画面有差异,大脑靠这个差异感知深度。


二、测距完整流程(五步)

plaintext

①双目标定 → ②立体校正 → ③立体匹配 → ④视差计算 → ⑤深度计算
   (出厂做)    (实时预处理)   (核心算法)    (输出视差图)   (输出深度图)

第①步:双目标定(出厂 / 使用前做一次)

做什么:算出两个摄像头的内参外参

  • 内参:每个摄像头自己的焦距 f、主点坐标、畸变系数(镜头畸变校正);
  • 外参:左右摄像头之间的相对位置关系 —— 旋转矩阵 R 和平移向量 T(基线 B 就是 T 的水平分量)。

为什么需要

  • 两个摄像头不可能完全一样(焦距有微小差异、安装有倾斜);
  • 镜头有畸变(桶形畸变,画面边缘弯曲);
  • 不标定的话,左右图像对不齐,视差算不准。

方法:用棋盘格标定板,从不同角度拍十几组照片,算法求解内参外参。

这一步和之前的 "手眼标定" 是同一类问题 —— 都是求坐标系之间的变换关系。


第②步:立体校正(实时预处理)

做什么:把左右两张原始图像,经过几何变换,变成行对齐的理想图像。

为什么需要

  • 实际安装中,两个摄像头不可能完全水平对齐,可能一个高一个低、一个歪一点;
  • 行对齐后,同一个物体在左右图像中一定在同一行(y 坐标相同),只有 x 坐标不同;
  • 这样立体匹配时,只需要在同一行搜索对应点,计算量大幅减少。

plaintext

校正前:左图物体在第200行,右图物体在第205行(不对齐)
校正后:左图物体在第200行,右图物体也在第200行(行对齐)

方法:用标定得到的内外参,做极线校正(Bouguet 算法),输出两张行对齐的去畸变图像。


第③步:立体匹配(核心算法,计算量最大)

做什么:对左图中的每个像素,在右图中找到它对应的像素(同一个物理点在右图中的位置)。

为什么难

  • 左图有几百万像素,每个像素都要在右图中找 "哪个像素是同一个点";
  • 这是计算机视觉的经典难题,叫对应点问题

怎么找

  • 因为已经行对齐了,只需要在右图同一行搜索;
  • 取左图一个像素周围的小窗口(如 9×9),在右图同一行滑动,计算窗口相似度(SAD、SSD、NCC 等代价函数);
  • 相似度最高的位置,就是对应点。

plaintext

左图像素 (x, y) → 在右图第y行搜索 → 找到对应像素 (x', y)
视差 d = x - x'  (通常左图x > 右图x')

常用算法

表格

算法 特点
SGBM OpenCV 自带,半全局块匹配,效果好,速度中等,最常用
BM 块匹配,速度快,效果一般
RAFT-Stereo 深度学习方法,精度高,需要 GPU
GMS 快速特征匹配,适合特征丰富场景

匹配失败的情况

  • 无纹理区域(白墙、天空):左右图都一样,找不到对应点;
  • 重复纹理(栅栏、条纹):容易匹配错;
  • 遮挡区域:左图看得到,右图被挡住了,没有对应点;
  • 反光 / 透明物体:左右图像素值不一致。

第④步:视差计算(输出视差图)

做什么:立体匹配完成后,每个像素都有了一个视差值 d,组成视差图(Disparity Map)。

  • 视差图是一张灰度图,每个像素的灰度值 = 视差大小;
  • 越亮 = 视差越大 = 物体越近;
  • 越暗 = 视差越小 = 物体越远。

plaintext

视差图示例:
近处的桌子 → 白色(视差大)
远处的墙   → 灰色(视差小)
天空       → 黑色(视差接近0,匹配失败)

第⑤步:深度计算(输出深度图)

做什么:把视差 d 代入公式,算出每个像素的真实深度 Z。

\(Z = \frac{f \times B}{d}\)

  • f:焦距(标定得到,像素单位);
  • B:基线长度(标定得到,毫米 / 米);
  • d:视差(像素);
  • Z:深度(和 B 同单位)。

输出:深度图(Depth Map),每个像素值 = 该点到相机的真实距离。

注意:视差 d=0 时,公式分母为 0,深度无穷大 —— 所以天空、远处物体视差接近 0,深度无法计算,通常标记为无效值。


三、核心公式的直观理解

\(Z = \frac{f \times B}{d}\)

表格

参数 变大时 深度 Z 怎么变 通俗解释
焦距 f ↑ Z ↑ 镜头越长,同样视差对应更远的距离
基线 B ↑ Z ↑ 两个摄像头离得越远,同样视差对应更远的距离
视差 d ↑ Z ↓ 物体越近,左右画面偏差越大

三个关键结论

  1. 基线越长,测距越远—— 但近处盲区越大;
  2. 焦距越长,测距越远—— 但视野越窄;
  3. 视差越小,深度对误差越敏感—— 远距离时,视差差 1 个像素,深度可能差好几米。

四、一个具体数值例子

假设双目相机参数:

  • 焦距 f = 500 像素
  • 基线 B = 120mm(0.12m)

物体在 1m 处

  • d = f×B/Z = 500×0.12/1 = 60 像素
  • 视差 60 像素,很大,容易匹配,深度精确

物体在 5m 处

  • d = 500×0.12/5 = 12 像素
  • 视差 12 像素,还能算

物体在 20m 处

  • d = 500×0.12/20 = 3 像素
  • 视差只有 3 像素,匹配误差 ±1 像素 → 深度误差 ±5m,基本不可用

这就是为什么双目相机远距离精度差—— 不是算法不行,是物理上视差太小了,和人眼看远处物体没立体感是一个道理。


五、双目测距的优缺点

优点

  • 被动测距:不发光,功耗低,无多设备干扰;
  • 有绝对尺度:基线和焦距已知,深度是物理精确值(不像单目深度估计没尺度);
  • 同时有纹理:左右图像都是完整 RGB,语义信息丰富;
  • 成本适中:比激光雷达便宜很多。

缺点

  • 依赖光照:暗处 / 逆光图像质量差,匹配失败;
  • 远距离失效:>10~20m 视差太小,精度暴跌;
  • 无纹理区域失效:白墙、天空算不出视差;
  • 计算量大:实时立体匹配需要 GPU 或专用芯片;
  • 基线与盲区矛盾:基线远→远距离好,但近处物体可能只被一个摄像头看到。

六、双目相机 vs 其他深度传感器

表格

方案 原理 有效距离 光照依赖 纹理依赖 成本
双目相机 被动立体匹配 0.5~20m
结构光深度相机 主动投影编码图案 + 三角测距 0.3~5m
ToF 深度相机 主动发光测飞行时间 0.3~10m
激光雷达 主动激光 ToF + 扫描 1~200m

结构光(如 iPhone FaceID、旧版 Kinect)本质也是三角测距,但它主动投影图案,解决了 "无纹理区域无法匹配" 的问题 —— 可以理解为 "双目 + 主动纹理"。


七、一句话总结

双目相机测距 = 两个摄像头同时拍照 → 标定校正让两行对齐 → 立体匹配找左右对应点 → 算出每个像素的视差 → 用公式 Z=f×B/d 算出深度。核心是视差,本质是三角几何,瓶颈是立体匹配和远距离视差太小。它是人眼双目视觉的工程复刻,近距精度高、有纹理有尺度,但受光照和距离限制。

Logo

立足具身智能前沿赛道,致力于搭建全球化、开源化、全栈式技术交流与实践共创平台。

更多推荐