深入解析slambook2中的双目视觉三维重建实现
slambook2 edition 2 of the slambook 项目地址: https://gitcode.com/gh_mirrors/sl/slambook2
本文将以slambook2项目中的stereoVision.cpp为例,详细讲解如何使用OpenCV和Pangolin实现基于双目视觉的三维重建。这个示例程序展示了从双目图像到三维点云重建的完整流程,是学习计算机视觉中立体视觉技术的优秀案例。
程序概述
该程序主要完成了以下几个关键步骤:
- 读取左右目图像
- 计算视差图
- 根据视差图重建三维点云
- 使用Pangolin可视化点云
核心代码解析
1. 相机参数设置
程序首先定义了相机的内参和基线距离:
// 内参
double fx = 718.856, fy = 718.856, cx = 607.1928, cy = 185.2157;
// 基线
double b = 0.573;
这些参数对于三维重建至关重要:
fx
,fy
:相机在x和y方向的焦距cx
,cy
:主点坐标b
:双目相机基线距离,即两个相机光心之间的距离
2. 视差图计算
程序使用OpenCV的StereoSGBM算法计算视差图:
cv::Ptr<cv::StereoSGBM> sgbm = cv::StereoSGBM::create(
0, 96, 9, 8 * 9 * 9, 32 * 9 * 9, 1, 63, 10, 100, 32);
cv::Mat disparity_sgbm, disparity;
sgbm->compute(left, right, disparity_sgbm);
disparity_sgbm.convertTo(disparity, CV_32F, 1.0 / 16.0f);
这里使用了半全局块匹配算法(Semi-Global Block Matching),参数说明:
minDisparity
:最小视差,设为0numDisparities
:视差搜索范围,设为96blockSize
:匹配块大小,设为9- 其他参数控制算法的惩罚项和一致性检查
3. 三维点云重建
根据视差图重建三维点云的核心代码如下:
for (int v = 0; v < left.rows; v++)
for (int u = 0; u < left.cols; u++) {
if (disparity.at<float>(v, u) <= 0.0 || disparity.at<float>(v, u) >= 96.0) continue;
Vector4d point(0, 0, 0, left.at<uchar>(v, u) / 255.0);
// 根据双目模型计算 point 的位置
double x = (u - cx) / fx;
double y = (v - cy) / fy;
double depth = fx * b / (disparity.at<float>(v, u));
point[0] = x * depth;
point[1] = y * depth;
point[2] = depth;
pointcloud.push_back(point);
}
这里的关键公式是深度计算:
depth = (f * b) / disparity
其中:
f
是焦距b
是基线距离disparity
是视差值
4. 点云可视化
程序使用Pangolin库进行点云可视化:
pangolin::CreateWindowAndBind("Point Cloud Viewer", 1024, 768);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// 设置相机视角
pangolin::OpenGlRenderState s_cam(
pangolin::ProjectionMatrix(1024, 768, 500, 500, 512, 389, 0.1, 1000),
pangolin::ModelViewLookAt(0, -0.1, -1.8, 0, 0, 0, 0.0, -1.0, 0.0)
);
// 绘制点云
glPointSize(2);
glBegin(GL_POINTS);
for (auto &p: pointcloud) {
glColor3f(p[3], p[3], p[3]);
glVertex3d(p[0], p[1], p[2]);
}
glEnd();
技术要点深入
1. 视差与深度的关系
双目视觉的核心原理是通过两个相机观察同一场景,利用视差计算深度。视差是指同一物体在两个相机图像中的水平位置差。视差越大,物体距离相机越近;视差越小,物体距离相机越远。
2. SGBM算法特点
StereoSGBM算法相比传统的块匹配算法有以下优势:
- 结合了全局能量最小化思想
- 在多个方向上进行路径优化
- 对遮挡区域和纹理缺乏区域有更好的处理能力
3. 点云重建精度
影响重建精度的主要因素:
- 相机标定精度:内参和基线距离的准确性直接影响重建结果
- 视差计算质量:错误的视差会导致深度计算错误
- 图像分辨率:更高分辨率的图像能提供更精细的深度信息
实际应用中的注意事项
-
参数调优:SGBM的参数需要根据具体场景调整,特别是
numDisparities
和blockSize
对结果影响很大。 -
异常值处理:视差图中可能存在噪声和错误匹配,需要设置合理的视差范围过滤异常值。
-
计算效率:对于高分辨率图像,可以降低采样率(如u+=2,v+=2)提高处理速度。
-
内存管理:大规模点云会消耗大量内存,需要考虑分块处理或使用更高效的数据结构。
总结
slambook2中的这个双目视觉示例展示了从图像到三维点云的完整流程,涵盖了计算机视觉中的多个关键技术点。通过这个例子,我们可以学习到:
- 如何使用OpenCV进行立体匹配
- 如何根据视差图计算三维坐标
- 如何使用Pangolin进行三维可视化
- 双目视觉的基本原理和实现方法
这个程序虽然简洁,但包含了立体视觉的核心思想,是学习三维重建的绝佳起点。读者可以在此基础上进行扩展,如加入点云滤波、表面重建等高级功能,构建更完整的三维重建系统。
slambook2 edition 2 of the slambook 项目地址: https://gitcode.com/gh_mirrors/sl/slambook2
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考