CV - 8: 双目立体视觉 (Stereo Vision)

8.1 双目立体视觉概述

8.1.1 问题定义

Two-View Stereo(双目立体视觉)

  • 输入:一对已标定的立体图像对(calibrated stereo pair)
  • 输出:密集深度图(dense depth map)

双目立体视觉通过模拟人类双眼视觉系统,利用两个不同位置拍摄的图像来重建场景的三维信息。

8.1.2 基本原理

3D重建 = 对应关系(Correspondence) + 三角测量(Triangulation)

基本流程

  1. 对于第一张图像中的每个像素
  2. 找到第二张图像中的对应极线(epipolar line)
  3. 在极线上搜索最佳匹配点
  4. 通过三角测量计算深度信息

8.2 简单立体系统

8.2.1 平行立体配置

最简单的情况:极线 = 对应的扫描线

配置要求

  • 两相机的图像平面相互平行
  • 图像平面与基线(baseline)平行
  • 两相机中心位于同一高度
  • 焦距相同

结果:极线沿着图像的水平扫描线排列

8.2.2 简单立体系统的本质矩阵

对于简单立体系统,本质矩阵\(\mathbf{E}\)可以简化:

\[\mathbf{R} = \mathbf{I}, \quad \mathbf{t} = (t, 0, 0)\] \[\mathbf{E} = [\mathbf{t}]_{\times}\mathbf{R} = \begin{bmatrix} 0 & 0 & 0 \\ 0 & 0 & -t \\ 0 & t & 0 \end{bmatrix}\]

由对极约束 \(\mathbf{x}'^T\mathbf{E}\mathbf{x} = 0\):

\[(u' \ v' \ 1) \begin{bmatrix} 0 & 0 & 0 \\ 0 & 0 & -t \\ 0 & t & 0 \end{bmatrix} \begin{pmatrix} u \\ v \\ 1 \end{pmatrix} = 0\]

可得:\(v = v'\)

结论:对应点的\(v\)坐标相同!


8.3 立体图像校正

8.3.1 校正的必要性

对于一般的立体系统,图像平面通常不平行。我们可以使用立体校正(Stereo Rectification)将图像投影到平行于基线的公共平面上。

8.3.2 校正算法

步骤

  1. 从本质矩阵或基础矩阵计算\(R_1\)
  2. 旋转右相机\(R_1\)以对齐两相机的方向
  3. 旋转两相机\(R_{rect}\)使图像平面平行于基线(即将原始极点映射到无穷远)
  4. 缩放图像\(H\)以减少畸变

8.3.3 计算校正旋转矩阵

计算极点\(e_1\)

  • 使用SVD分解,因为\(\mathbf{F}e_1 = 0\)

构造\(R_{rect} = (r_1, r_2, r_3)^T\)

\[r_1 = \frac{e_1}{\|e_1\|}\] \[r_2 = \frac{[0,0,1]^T \times r_1}{\|[0,0,1]^T \times r_1\|}\] \[r_3 = r_1 \times r_2\]

结果:\(R_{rect}e_1 = (\|e_1\|, 0, 0)^T\),这是一个无穷远点


8.4 视差与深度

8.4.1 视差(Disparity)

视差:对应点在两幅图像中的水平位置差

\[d = x - x'\]

8.4.2 深度计算

对于简单立体系统,通过相似三角形:

\[\frac{x}{f} = \frac{B_1}{z}, \quad \frac{-x'}{f} = \frac{B_2}{z}\] \[\frac{x - x'}{f} = \frac{B_1 + B_2}{z} = \frac{B}{z}\]

深度公式

\[\boxed{z = \frac{fB}{x - x'} = \frac{fB}{d}}\]

其中:

  • \(f\):焦距
  • \(B\):基线长度
  • \(d = x - x'\):视差

重要性质:视差与深度成反比!

8.4.3 基线的影响

较大基线

  • ✅ 较小的三角测量误差(更精确)
  • ❌ 匹配更困难(视角差异大)

较小基线

  • ❌ 较大的三角测量误差
  • ✅ 匹配更容易

8.5 局部立体匹配

8.5.1 相似性度量

考虑两个\(K \times K\)窗口的像素展平为向量\(\mathbf{w}_L, \mathbf{w}_R \in \mathbb{R}^{K^2}\)

平方差之和(SSD)

\[\text{SSD}(x, y, d) = \|\mathbf{w}_L(x, y) - \mathbf{w}_R(x - d, y)\|_2^2\]

零均值归一化互相关(ZNCC)

\[\text{ZNCC}(x, y, d) = \frac{(\mathbf{w}_L(x, y) - \bar{w}_L(x, y))^T (\mathbf{w}_R(x - d, y) - \bar{w}_R(x - d, y))}{\|\mathbf{w}_L(x, y) - \bar{w}_L(x, y)\|_2 \|\mathbf{w}_R(x - d, y) - \bar{w}_R(x - d, y)\|_2}\]

其中\(\bar{w}\)是向量的均值。

8.5.2 算法流程

  1. 选择视差范围\([0, D]\)
  2. 对于每个像素\(x = (x, y)\),计算最佳视差: \(d^*(x, y) = \arg\min_{d \in [0,D]} C(x, y, d)\)
  3. 对两幅图像都执行匹配
  4. 应用左右一致性检查去除异常值

8.5.3 窗口大小的影响

小窗口(如5×5):

  • ✅ 更多细节
  • ❌ 更多噪声

大窗口(如11×11):

  • ✅ 更平滑的结果
  • ❌ 细节丢失

8.5.4 半遮挡

半遮挡(Half Occlusions):某些区域在一幅图像中可见,但在另一幅图像中不可见。

影响:在输出深度图中产生裂缝或空洞。

8.5.5 失败情况

  1. 无纹理区域:平坦区域难以找到可靠的对应关系
  2. 重复模式:周期性纹理导致歧义
  3. 非朗伯表面:镜面反射导致在不同视角下外观变化

8.6 全局立体匹配

8.6.1 非局部约束

局部立体匹配独立地为每个窗口找到最佳匹配。需要引入非局部约束进行全局优化。

常见约束

  1. 唯一性(Uniqueness):一幅图像中的每个点最多匹配另一幅图像中的一个点

  2. 顺序性(Ordering):对应点应以相同的顺序出现

  3. 平滑性(Smoothness):相邻点应有相似的视差值

8.6.2 能量函数

\[E(d) = E_d(d) + \lambda E_s(d)\]

数据项(Data term)

\[E_d(d) = \sum_{(x,y) \in I} C(x, y, d(x, y))\]

测量窗口匹配的质量(如SSD)

平滑项(Smoothness term)

\[E_s(d) = \sum_{(p,q) \in \mathcal{E}} V(d_p, d_q)\]

其中\(\mathcal{E}\)是相邻像素的集合(4连通或8连通)

目标:最小化总能量\(E(d)\)

8.6.3 视差空间图像

Disparity Space Image (DSI)

  • 将对角线上的有效值重新排列成矩形数组
  • 每条路径对应一个立体匹配
  • 寻找最低代价路径

8.6.4 动态规划求解

对应类型

  • 匹配:添加匹配代价(小代价如果强度一致)
  • 遮挡:添加无匹配代价(大代价)

递推公式

\[C(i,j) = \min \begin{cases} C(i-1, j-1) + e(i, j) & \text{匹配} \\ C(i-1, j) + \text{occlusion} & \text{左图遮挡} \\ C(i, j-1) + \text{occlusion} & \text{右图遮挡} \end{cases}\]

复杂度:\(O(MN)\),其中\(M\)和\(N\)是图像尺寸

Python实现示例

import numpy as np

# 初始化
n, m = 5, 7
C = np.full((n, m), float('inf'))
e = np.random.rand(n, m)

# 基础情况:初始化第一列
for i in range(n):
    C[i][0] = 0

# 填充代价表
for j in range(1, m):
    for i in range(n):
        for k in range(n):
            C[i][j] = min(C[i][j], e[k][j] + C[k][j - 1])

8.6.5 遮挡填充

左遮挡像素填充:用扫描线中前面最近的有效像素值填充

右遮挡像素填充:用扫描线中后面最近的有效像素值填充


8.7 动态规划的应用:接缝裁剪

8.7.1 Seam Carving算法

动态规划不仅用于立体匹配,还用于接缝裁剪(Seam Carving)实现内容感知的图像缩放。

算法:找到最小能量的接缝(seam)

\[s^* = \min_s E(s) = \min_s \sum_{i=1}^n e(\mathbf{I}(s_i))\]

其中能量函数\(e_1(\mathbf{I})\)可以是梯度:

\[e_1(\mathbf{I}) = \left|\frac{\partial}{\partial x}\mathbf{I}\right| + \left|\frac{\partial}{\partial y}\mathbf{I}\right|\]

递推公式

\[M(i,j) = e(i,j) + \min(M(i-1,j-1), M(i-1,j), M(i-1,j+1))\]

应用

  • 图像缩放(保持重要内容)
  • 全景图像矩形化

8.8 深度学习方法

8.8.1 监督学习

MC-CNN (CVPR 2015):使用CNN学习匹配代价

网络结构

  • 输入:两个图像块\(x\)和\(x'\)
  • 使用Siamese网络(共享权重)提取特征
  • 输出:归一化特征向量
  • 计算相似度:\(x^T x'\)
  • 损失函数:SVM/Hinge loss

8.8.2 无监督学习

思想:利用几何约束作为监督信号

流程

  1. 左图像\(I_l(x)\)通过深度CNN预测逆深度\(D(x) = fB/d(x)\)
  2. 使用视差进行逆向扭曲:\(I_w(x) = I_r(x + D(x))\)
  3. 重建误差作为损失:\(\|I_w(x) - I_l(x)\|\)

优点:不需要标注的深度真值


8.9 主动立体视觉

8.9.1 结构光

Active Stereo with Structured Light

  • 投射”结构化”光模式到物体上
  • 简化对应问题
  • 使用一个相机和一个投影仪

常见模式

  • 彩色条纹
  • 编码图案
  • 点阵模式

8.9.2 Kinect

Microsoft Kinect

  • 使用红外结构光
  • 投射红外点阵图案
  • 通过模式匹配计算深度

组件

  • 红外投影仪(IR Projector)
  • 左/右红外相机(IR Imagers)
  • RGB相机

8.9.3 Apple TrueDepth

组件

  • 红外相机
  • 泛光照明器
  • 点阵投影仪
  • 接近传感器

应用:Face ID、AR表情、人像模式

8.9.4 激光扫描

光学三角测量:结构光扫描的高精度版本

  • 投射单条激光光带
  • 在物体表面扫描
  • 高精度重建

著名应用:Digital Michelangelo Project(数字米开朗基罗计划)

  • 扫描大卫像等艺术品
  • 亚毫米级精度
  • 生成数十亿三角面片的模型

8.10 立体数据集

8.10.1 Middlebury Stereo Dataset

经典的立体视觉基准数据集,包含:

  • 精确标定的立体图像对
  • 结构光扫描的真值深度
  • 多种场景(室内物体、复杂纹理)

8.10.2 KITTI Dataset

自动驾驶立体数据集

  • 真实道路场景
  • 激光雷达深度真值
  • 相机标定参数
  • 多种天气和光照条件

8.10.3 合成数据

优势

  • 完美的真值深度
  • 可控的场景参数
  • 大规模数据生成

8.11 现代3D重建技术

8.11.1 KinectFusion (2011)

特点

  • 实时密集3D重建
  • 使用体素表示(TSDF)
  • GPU加速
  • 相机跟踪与重建同步

8.11.2 DynamicFusion (2015)

扩展

  • 非刚性场景重建
  • 实时人体捕捉
  • 变形跟踪
  • 规范空间表示

8.12 总结

8.12.1 双目立体视觉管线

  1. 立体校正:使极线对齐到扫描线
  2. 匹配代价计算:SSD、ZNCC等相似性度量
  3. 代价聚合:窗口匹配或全局优化
  4. 视差计算:最小化匹配代价
  5. 视差后处理:左右一致性检查、遮挡填充
  6. 深度计算:\(z = fB/d\)

8.12.2 方法对比

方法 优点 缺点
局部立体匹配 快速、易实现 噪声多、边界模糊
全局优化 平滑结果、边界清晰 计算量大
深度学习 性能最优 需要大量数据
主动立体 鲁棒、适用无纹理 需要额外硬件

8.12.3 挑战与未来方向

当前挑战

  • 无纹理区域
  • 重复纹理
  • 透明/反射物体
  • 遮挡处理

未来方向

  • 端到端深度学习
  • 多视图立体
  • 动态场景重建
  • 神经隐式表示(NeRF等)

参考资料

  • 教材:Computer Vision: Algorithms and Applications (2nd Edition), Chapter 12
  • 论文
    • Y. Boykov, O. Veksler, R. Zabih. “Fast Approximate Energy Minimization via Graph Cuts.” PAMI 2001
    • J. Zbontar, Y. LeCun. “Computing the Stereo Matching Cost with a Convolutional Neural Network.” CVPR 2015
    • R. Garg et al. “Unsupervised CNN for Single View Depth Estimation: Geometry to the Rescue.” ECCV 2016



Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • notes of ML
  • notes of VCI
  • notes of AIP
  • notes of AI Math Fundamentals
  • notes of ICS