🎥 双目立体视觉技术科普

揭秘立体校正的原理与实现

🌟 什么是双目立体视觉?

就像我们人类通过两只眼睛感知深度和距离一样,双目立体视觉系统使用两个摄像头来"看"世界,从而计算出物体的三维位置。这项技术广泛应用于自动驾驶、机器人导航、3D重建等领域。

❓ 为什么需要立体校正?

现实中的挑战

在实际应用中,两个摄像头很难做到完美平行安装。即使微小的角度偏差,也会导致:

  • 极线不对齐:对应的点不在同一水平线上
  • 搜索复杂:需要在整个2D平面搜索匹配点(复杂度O(n²))
  • 计算昂贵:实时性能大幅下降

💡 立体校正的神奇作用

通过数学变换,将两个摄像头的图像"校正"到同一平面,使得对应点位于同一水平线。这样,搜索从2D降为1D,复杂度从O(n²)降到O(n),速度提升数百倍!

📷 ➜ 🔧 ➜ 📐

原始图像立体校正极线对齐

🔬 核心技术:stereoRectify

功能概述

cv::stereoRectify 是OpenCV提供的立体校正计算函数,它的核心任务是:

  • 计算将两个图像平面对齐的旋转变换
  • 生成新的投影矩阵
  • 输出视差到深度的转换矩阵

🎯 关键输入参数

  • cameraMatrix1/2:左右相机的内参矩阵(焦距、光心位置)
  • distCoeffs1/2:镜头畸变系数
  • R, T:两个相机之间的相对旋转和平移
  • imageSize:图像分辨率

📤 重要输出参数

  • R1, R2:左右相机的校正旋转矩阵
  • P1, P2:新的3×4投影矩阵
  • Q:4×4重投影矩阵,用于将视差转为3D坐标

Alpha参数的奥秘

alpha参数控制校正后图像的裁剪策略:

  • alpha = 0:只保留有效像素,可能有裁剪
  • alpha = 1:保留所有原始像素,边缘可能有黑边
  • alpha = -1:让算法自动选择最优值

🖼️ 图像变换:remap

什么是remap?

cv::remap 是OpenCV的图像重映射函数。它根据预先计算好的映射关系,将原始图像的每个像素重新排列到新的位置,生成校正后的图像。

🗺️ 映射表的本质

想象一张"寻宝图":对于校正后图像的每个像素坐标(x', y'),映射表告诉我们应该从原图的哪个位置(x, y)取颜色值。这个映射表只需计算一次,就可以对所有图像重复使用!

生成映射表

使用 cv::initUndistortRectifyMap 函数生成映射表,它会同时完成:

  • 去除镜头畸变
  • 应用立体校正旋转
  • 重新投影到新的图像平面

🚀 完整工作流程

1

双目标定

使用棋盘格等标定板,通过 cv::stereoCalibrate 获取相机内参、畸变系数、以及两相机间的相对位姿(R, T)。

2

计算校正变换

调用 cv::stereoRectify,输入标定结果,输出校正旋转矩阵R1/R2、投影矩阵P1/P2和重投影矩阵Q。

3

生成映射表

分别为左右相机调用 cv::initUndistortRectifyMap,生成map1和map2映射矩阵。这一步只需执行一次。

4

校正图像

对每一对新采集的立体图像,使用 cv::remap 函数和预计算的映射表进行快速校正。

5

立体匹配

使用StereoBM或StereoSGBM算法在校正后的图像上进行匹配,计算视差图。

6

深度重建

利用Q矩阵和 cv::reprojectImageTo3D,将视差图转换为3D点云。

💡 实用技巧与建议

性能优化

  • 预计算映射表:在初始化阶段计算map,避免实时运行时重复计算
  • 选择合适插值INTER_LINEAR 是速度和质量的最佳平衡
  • 使用ROI:利用 validPixROI 裁剪无效区域,提高处理效率

效果验证

  • 在校正后的左右图像上画水平线
  • 检查对应特征点是否位于同一高度
  • 观察极线是否完全水平

常见问题

  • 标定精度:校正效果严重依赖于标定精度,建议使用高质量标定板
  • 图像畸变:大畸变镜头会导致校正后图像边缘变形严重
  • 基线距离:基线太小会导致深度精度不足,太大会减少视野重叠

🎓 核心概念总结

Q矩阵的魔法

Q矩阵将2D视差值转换为3D世界坐标:

  • 输入:图像坐标(x, y)和视差d
  • 输出:3D空间坐标(X, Y, Z)
  • 公式:[X Y Z W]ᵀ = Q · [x y d 1]ᵀ,最终坐标为(X/W, Y/W, Z/W)

📐 视差转3D点云计算

🔍 Q矩阵的结构

Q矩阵是一个4×4的重投影矩阵:

Q = [ 1 0 0 -cx ] [ 0 1 0 -cy ] [ 0 0 0 f ] [ 0 0 -1/T (cx-cx')/T ]

💡 直接计算公式

已知像素坐标(x, y)和视差d,3D世界坐标为:

X = (x - cx) × T / (d - (cx - cx')) Y = (y - cy) × T / (d - (cx - cx')) Z = f × T / (d - (cx - cx'))

其中:

  • cx, cy:左相机主点坐标
  • cx':右相机主点坐标
  • f:焦距(像素单位)
  • T:基线距离(世界坐标单位)
  • d:视差值(像素单位)

注意:当立体校正完美时,cx ≈ cx',公式可简化为除以d

🎯 关键要点

  • 距离反比:视差d越大,物体越近(Z越小)
  • 基线影响:基线T越大,深度分辨率越高
  • 焦距作用:焦距f影响深度测量的敏感度
  • 坐标系:计算结果在左相机坐标系下
🎯

立体校正 = 简化问题 + 加速计算 + 提高精度

从2D搜索降维到1D搜索,速度提升100倍以上!