立体视觉与距离测量 - 从视差恢复 3D 信息
立体视觉原理 - 模拟人类双目视觉
立体视觉通过两个不同位置的相机 (类似人的双眼) 拍摄同一场景,利用视差 (同一点在两张图像中的位置差异) 计算深度。视差越大,物体越近。
基本原理:对于基线距离为 B、焦距为 f 的双目系统,深度 Z 与视差 d 的关系为:Z = B × f / d。这是三角测量的直接应用。
系统组成:
- 双目相机:两个平行放置的相机,基线距离 5-30cm
- 标定:确定相机内参 (焦距、主点) 和外参 (相对位置)
- 校正:将两张图像变换为行对齐 (简化匹配)
- 匹配:找到左右图像中对应的像素
- 三角化:从视差计算 3D 坐标
与单目深度估计的区别:立体视觉基于几何原理,深度精度可量化;单目深度估计基于学习的先验,精度依赖训练数据。立体视觉适合需要精确测量的场景。
原理与精度的补充:立体视觉 (Stereo Vision) 用 2 台相机从不同视点拍摄同一场景,从左右图像对应点的偏移 (视差:Disparity) 复原 3D 信息。例如 f=1,000 px、B=0.12m、d=50px 时,Z = 1000 × 0.12 / 50 = 2.4m。距离精度的极限:受视差量化误差 (±0.5 像素) 影响,距离精度按距离的平方成比例下降。在 B=0.12m、f=1,000 px 的条件下,距离 2m 处误差约 ±2cm,而距离 10m 处则扩大到 ±50cm。
对极几何与校正
对极几何描述了两个相机视图之间的几何约束关系,是立体匹配的数学基础。
对极约束:左图中的一个点,其对应点必然在右图的一条线 (对极线) 上。这将 2D 搜索问题简化为 1D 搜索。
基础矩阵 F:编码两视图间对极几何的 3×3 矩阵。对于对应点 x 和 x': x'^T F x = 0。从 8 对以上匹配点可估计 F。
立体校正 (Rectification):
- 将两张图像变换为对极线水平对齐
- 校正后,对应点在同一行上,匹配只需水平搜索
- OpenCV:
cv2.stereoRectify()计算校正变换 cv2.initUndistortRectifyMap()+cv2.remap()应用变换
相机标定:使用棋盘格标定板,cv2.stereoCalibrate() 同时标定两个相机的内参和相对位姿。标定精度直接影响深度测量精度。
对极几何的作用:对极几何 (Epipolar Geometry) 描述 2 个相机之间的几何关系,是大幅缩小立体匹配搜索范围的基础。对极约束是指:与左图像上的点 p_L 对应的右图像点 p_R,必定落在右图像上某条特定直线 (对极线) 上,可写成 p_R^T × F × p_L = 0。其中 F 为基础矩阵 (Fundamental Matrix),由 2 个相机的内参与外参计算得出。校正后对极线与图像水平轴平行,对应点搜索便可只在水平方向进行。
立体匹配 - 块匹配与 SGM
立体匹配是立体视觉的核心步骤,为每个像素找到左右图像中的对应点并计算视差。
块匹配 (Block Matching):
- 对左图每个像素,在右图同一行搜索最相似的块
- 相似度度量:SAD (绝对差之和)、SSD (平方差之和)、NCC (归一化互相关)
- 速度快但结果噪声大,边缘处不准确
- OpenCV:
cv2.StereoBM_create(numDisparities=64, blockSize=15)
SGM (Semi-Global Matching):
- 在多个方向 (通常 8 或 16 个) 上进行路径优化
- 平衡局部匹配代价和全局平滑性
- 质量远优于块匹配,是实际应用的主力算法
- OpenCV:
cv2.StereoSGBM_create(minDisparity=0, numDisparities=128, blockSize=5)
参数调优:
numDisparities:最大视差范围,取决于最近物体距离blockSize:匹配窗口大小。大窗口平滑但丢失细节P1, P2: SGM 平滑惩罚。P2 > P1,P2 控制深度不连续处的惩罚
块匹配与 SGM 的细节:立体匹配 (Stereo Matching) 为左图像的每个像素寻找右图像中的对应像素并生成视差图。块匹配 (BM) 把左图像的小块 (例:15x15) 在右图像上水平滑动,取 SAD (Sum of Absolute Differences) 最小的位置为对应点,用 cv2.StereoBM_create(numDisparities=64, blockSize=15) 即可调用;优点是快 (1080p 约 30ms)、实现简单,缺点是在无纹理区域失败、边缘附近不准确、对遮挡脆弱。Semi-Global Matching (SGM) 由 Hirschmuller (2005) 提出,从多个方向 (8 或 16 方向) 聚合代价以克服块匹配的局部性,能量函数为 E(D) = Σ_p [C(p, D_p) + Σ_q∈N(p) P1×T[|D_p - D_q| = 1] + P2×T[|D_p - D_q| > 1]],用 P1 (小视差变化的惩罚,推荐值 8×blockSize²) 与 P2 (大视差变化的惩罚,推荐值 32×blockSize²) 控制平滑度。cv2.StereoSGBM_create(minDisparity=0, numDisparities=128, blockSize=5, P1=600, P2=2400) 的画质远高于 BM,代价是约 5-10 倍的计算量 (1080p 约 200ms)。后处理可用 WLS (Weighted Least Squares) 滤波器去噪并保留边缘,通过 cv2.ximgproc.createDisparityWLSFilter() 使用;再以左右一致性检查 (Left-Right Consistency Check) 检出遮挡区域并标记为无效值。
深度学习立体匹配
深度学习方法在立体匹配精度上大幅超越传统方法,尤其在遮挡和弱纹理区域。
AANet (2020):使用自适应聚合替代 3D 卷积构建代价体积,速度快且精度高。在 KITTI 上接近实时。
RAFT-Stereo (2021):将 RAFT 光流架构适配到立体匹配。迭代更新视差估计,在 Middlebury 和 ETH3D 基准上达到最先进水平。
CREStereo (2022):级联循环网络,从粗到细逐步精修视差。在多个基准上排名第一。
自监督方法:不需要真值视差图进行训练。利用左右一致性约束和光度损失自监督学习。适合真值难以获取的场景。
实时深度学习立体: HITNet (Google) 在边缘设备上实现实时立体匹配。MobileStereoNet 针对移动设备优化。TensorRT 部署可达 30+ fps。
代表模型的演进:DispNet / FlowNet (2016) 是最早的深度学习立体匹配方法,在合成数据集 SceneFlow 上训练,EPE (End-Point Error) 达到 1.68px。GC-Net (2017) 引入 3D 代价聚合。PSMNet (2018) 即 Pyramid Stereo Matching Network,用 Spatial Pyramid Pooling 利用多尺度上下文信息,在大面积无纹理区域也能稳定估计视差,在 KITTI 2015 基准上取得 D1-all 2.32% (3px 误差率)。RAFT-Stereo 则从相关体出发,用基于 GRU 的更新单元逐步细化视差。实用比较:精度为 RAFT-Stereo > PSMNet > SGM > BM;速度 (1080p) 为 BM (30ms) > SGM (200ms) > PSMNet (300ms、GPU) > RAFT-Stereo (500ms、GPU);泛化性方面,深度学习方法在与训练数据不同的域上精度可能下降。
视差图到 3D 点云的转换
将视差图转换为 3D 坐标,生成可用于测量和可视化的点云。
转换公式:
X = (u - cx) × Z / fY = (v - cy) × Z / fZ = B × f / d
其中 (u,v) 是像素坐标,(cx,cy) 是主点,f 是焦距,B 是基线,d 是视差。
OpenCV 实现:
Q = cv2.stereoRectify(...)[4] # 重投影矩阵points_3d = cv2.reprojectImageTo3D(disparity, Q)
点云滤波:
- 去除无效视差 (d=0 或负值) 对应的点
- 去除距离过远的点 (视差过小,精度低)
- 统计滤波去除离群点
精度分析:深度精度与视差精度的关系:ΔZ = Z² / (B×f) × Δd。距离越远,同样的视差误差导致的深度误差越大。这是立体视觉的固有限制。
重投影与点云导出:用 [X, Y, Z, W]^T = Q × [x, y, disparity, 1]^T 做重投影,实际 3D 坐标由 (X/W, Y/W, Z/W) 得到。点云滤波先做距离滤波,去除有效范围外 (例:0.5m-10m) 的点;一般立体相机在距离 2m 处约 ±2cm、5m 处约 ±12cm。保存与可视化方面,以 PLY 格式保存后可用 Open3D 或 CloudCompare 查看,open3d.io.write_point_cloud('output.ply', pcd) 可输出带颜色信息的点云。在 ROS (Robot Operating System) 中则以 PointCloud2 消息发布,并用 RViz 可视化。
实用立体视觉 - 系统搭建与应用
搭建实用立体视觉系统的硬件选择、标定流程和典型应用。
硬件选择:
- 消费级: Intel RealSense D435/D455 (主动红外 + 立体), ZED 2 (被动立体)
- 工业级: Basler 双目系统,FLIR 同步相机对
- DIY:两个相同型号的 USB 相机 + 固定支架
标定流程:
- 打印棋盘格标定板 (9×6 或 7×5 内角点)
- 从多个角度拍摄 20-30 对图像
cv2.findChessboardCorners()检测角点cv2.stereoCalibrate()计算标定参数- 重投影误差 < 0.5 像素为良好标定
应用场景:
- 机器人避障:实时深度图用于路径规划
- 工业测量:非接触式尺寸测量,精度可达 0.1mm
- 自动驾驶:前方障碍物距离估计
- AR/VR:深度感知用于遮挡处理和手势识别
相机选型与市售机型:基线取测量距离的 1/10-1/30 为准,距离 3m 时 B=10-30cm;分辨率越高视差分辨力越好,1080p 足以应对一般用途;同步必须用硬件同步 (触发输入),软件同步在拍摄运动物体时会产生偏差;拍摄运动物体还需要没有卷帘畸变的全局快门。市售机型中,Intel RealSense D435 为 B=50mm、投射红外图案、USB 连接,室内 0.2-10m,日本区售价约 3 万日元;ZED 2 为 B=120mm、1080p、附带 SDK,室内外 0.3-20m,日本区售价约 6 万日元;Stereolabs ZED X 面向工业用途,具备 IP67 防护与硬件同步,日本区售价约 15 万日元。
应用实例:自动驾驶方面,Subaru EyeSight 用立体相机检出前方障碍物并进行碰撞规避;机器人拣选在物流仓库的单件拣选中使用 3D 位置估计;农业用于果实尺寸测量与采收机器人定位;建筑用于施工现场的 3D 测量与竣工形状管理。常见问题中,室外阳光造成的饱和可用 ND 滤镜或自动曝光应对。