
*来源: 第一届3D视觉创新应用竞赛 | 参赛者:** 彭以平*
*硬件平台:** Astra Pro 深度相机 + Zora P1 开发板 + 便携电源系统*
*GitHub:** 3DReconstruction_Indoor-multi-floor*
一、项目亮点速览 ✨
你有没有想过——🏠 只需带着一个小设备走遍整栋楼,就能获得完整的三维数字地图?
这支团队用 Zora P1 + Astra Pro + TSDF + Marching Cube,搭建了一套完整的多楼层大型室内环境稠密重建系统,让"数字孪生楼宇"从梦想走进现实!🎯
核心能力表格:
| 核心能力 | 技术实现 |
|---|---|
| 🏢 多楼层重建 | 基于 ORB-SLAM2 扩展,支持大场景级联 |
| 🔄 TSDF 点云融合 | 避免密度爆炸,减少累计误差 |
| 📐 表面网格重建 | Marching Cube 三角面片提取 |
| 💾 纹理保留 | RGB 颜色融合,真实感强 |
| 🔋 便携式设计 | 11.6寸屏 + 锂电池,移动作业 |
二、背景与意义 🌍
2.1 应用场景
三维稠密重建技术在多个领域具有广泛应用:
| 应用领域 | 场景说明 |
|---|---|
| 🏗️ 混合现实(MR) | 室内导航、增强现实叠加 |
| 🎨 室内装修 | 虚拟家具摆放预览 |
| 🤖 机器人导航 | SLAM 建图、路径规划 |
| 📸 建筑测绘 | 数字化存档、BIM 模型 |
2.2 技术难点
在多楼层室内复杂环境下进行稠密三维重建面临以下挑战:
| 难点 | 描述 | 解决方案 |
|---|---|---|
| 📌 模型更新 | 图像序列输入,需关键帧筛选与模型融合 | ORB-SLAM2 关键帧机制 |
| 🎯 高质量表面 | 深度图生成点云,需连续表面而非离散点 | TSDF + Marching Cube |
| ⚡ 计算效率 | 大场景数据量大,需避免密度爆炸 | TSDF 体素网格 + 八叉树 |
三、系统硬件架构 🛠️

3.1 硬件组成
| 设备 | 型号/规格 | 功能 |
|---|---|---|
| 💻 开发板 | Zora P1(奥比中光定制) | 边缘计算、主控 |
| 📷 深度相机 | Astra Pro(单目结构光) | RGB-D 数据采集 |
| 🖥️ 显示模块 | 11.6寸液晶屏 | 实时预览 |
| 🔋 电源系统 | 12V 锂电池 + 220V 逆变器 | 移动供电 |
3.2 Zora P1 开发板
Zora P1 是奥比中光专为 3D 视觉应用定制的开发板:
- ✅ 支持 Android / Ubuntu / Armbian 多系统
- ✅ 高度适配奥比中光 RGB-D 模组
- ✅ 提供丰富周边接口(POE、EMMC、麦克风阵列、MIPI-CSI)
3.3 Astra Pro 相机
| 参数 | 规格 |
|---|---|
| 成像技术 | 单目结构光 |
| 深度范围 | 0.6m ~ 8m |
| 分辨率 | 640×480 |
| 优势 | 高精度、低功耗、响应迅速 |
四、核心算法详解 🔬
4.1 算法总流程

4.2 ORB-SLAM2 位姿估计
基于 ORB-SLAM2 开源框架,通过 ORB 特征描述子实现:
| 功能模块 | 说明 |
|---|---|
| 🛰️ 跟踪 | ORB 特征提取与匹配 |
| 🗺️ 局部建图 | 关键帧插入与筛选 |
| 🔄 闭环检测 | 回环识别与优化 |
关键帧输出:
- 时间戳(Timestamp)
- 相机位姿(R, t)
- RGB 图像
- 深度图像
4.3 TSDF 点云融合
TSDF(Truncated Signed Distance Function) 是本系统的核心创新点!
4.3.1 TSDF 原理
TSDF 将三维空间划分为体素网格,每个体素存储:该点到最近表面的距离(带符号)
| 区域 | TSDF 值 | 含义 |
|---|---|---|
| 表面之前 | 负值 | 物体内部 |
| 表面上 | 0 | 实际表面 |
| 表面之后 | 正值 | 物体外部 |
> 截断处理: 只保留 [−δ, +δ] 范围内的值,减少存储和计算量。
4.3.2 TSDF 融合代码
// 初始化 TSDF 体素网格
cpu_tsdf::TSDFVolumeOctree::Ptr tsdf(new cpu_tsdf::TSDFVolumeOctree);
// 设置网格尺寸:20m × 20m × 20m
tsdf->setGridSize(20., 20., 20.);
// 设置分辨率:2048³(最小体素 ~1cm)
tsdf->setResolution(2048, 2048, 2048);
// 设置相机内参
tsdf->setCameraIntrinsics(fx, fy, cx, cy);
// 设置传感器距离范围
tsdf->setSensorDistanceBounds(0, 3);
// 开启颜色融合
tsdf->setIntegrateColor(true);
// 设置深度截断阈值
tsdf->setDepthTruncationLimits(0.03, 0.03);
// 初始化
tsdf->reset();
4.3.3 TSDF 融合核心算法
// 对每一帧进行 TSDF 融合
for (size_t i = 0; i < vImRGB.size(); i++) {
// Step 1: 从 RGB-D 生成点云
PointCloud::Ptr cloud(new PointCloud);
unProject(vImRGB[i], vImD[i], camIntrinsic, cloud);
// Step 2: 获取相机位姿
Eigen::Affine3d Twc(vTwc[i].affine());
// Step 3: TSDF 融合
tsdf->integrateCloud(*cloud, pcl::PointCloud<pcl::Normal>(), Twc);
}
// Step 4: Marching Cube 提取表面
cpu_tsdf::MarchingCubesTSDFOctree mc;
mc.setInputTSDF(tsdf);
mc.setColorByRGB(true);
pcl::PolygonMesh::Ptr mesh(new pcl::PolygonMesh);
mc.reconstruct(*mesh);
4.3.4 TSDF 的优势
| 传统方法 | TSDF 方法 |
|---|---|
| ❌ 点云累加,密度爆炸 | ✅ 体素网格,密度可控 |
| ❌ 累计误差大 | ✅ 融合平均,误差小 |
| ❌ 难以提取表面 | ✅ 等值面直接提取 |
4.4 统计滤波去噪
重建过程中不可避免引入噪声,使用统计滤波优化:
// 对点云空间进行统计学分析
// 绘制邻域特征直方图
// 根据"坏点"与正常点的特征差异裁剪直方图
// 实现点云统计滤波
4.5 Marching Cube 表面重建
4.5.1 算法原理
Marching Cube 是经典的等值面提取算法:

4.5.2 Marching Cube 代码
// 初始化 Marching Cube
cpu_tsdf::MarchingCubesTSDFOctree mc;
mc.setMinWeight(0); // 最小权重阈值
mc.setInputTSDF(tsdf); // 输入 TSDF 体素
mc.setColorByRGB(true); // 启用颜色
// 执行重建
pcl::PolygonMesh::Ptr mesh(new pcl::PolygonMesh);
mc.reconstruct(*mesh);
// 保存结果
pcl::io::savePLYFileBinary("globalMesh.ply", *mesh);
4.5.3 八叉树优化
针对大场景,采用 八叉树(Octree) 结构优化:
// 八叉树节点结构
class OctreeNode {
float d_; // TSDF 距离值
float w_; // 观测权重
float ctr_x_; // 中心 x
float ctr_y_; // 中心 y
float ctr_z_; // 中心 z
float size_; // 体素大小
std::vector<OctreeNode::Ptr> children_; // 8 个子节点
};
// 八叉树分裂
void OctreeNode::split() {
children_.resize(8);
float newsize = size_ / 2;
// 创建 8 个子节点(8 象限)
children_[0].reset(instantiateNode(ctr_x_-off_x, ctr_y_-off_y, ctr_z_-off_z, ...));
// ... (其他 7 个节点)
}
五、相机驱动与数据采集 📷
5.1 Astra Pro 驱动代码
// 初始化 OpenNI
openni::OpenNI::initialize();
// 打开设备
mDevice.open(openni::ANY_DEVICE);
// 创建深度流
mDepthStream.create(mDevice, openni::SENSOR_DEPTH);
mDepthStream.start();
// D2C 对齐(深度图对齐到彩色图)
mDevice.setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR);
// 获取相机内参
OBCameraParams cameraParam;
mDevice.getProperty(openni::OBEXTENSION_ID_CAM_PARAMS,
(uint8_t*)&cameraParam, ¶m_size);
5.2 数据采集与保存
// 循环读取 RGB 和 Depth
void Orbbec::getFrames(cv::Mat &rgb, cv::Mat &depth) {
openni::VideoFrameRef frameDepth;
mDepthStream.readFrame(&frameDepth);
mCapture >> rgb;
// 转换为 OpenCV 格式
depth = cv::Mat(frameDepth.getHeight(), frameDepth.getWidth(),
CV_16UC1, (void*)frameDepth.getData());
}
// 按 TUM-RGBD 格式保存
void timeStamp::image_save(const cv::Mat &color, const cv::Mat &depth) {
// 保存 RGB 和 Depth 图像
cv::imwrite("rgb/" + m_timestamp + ".png", color);
cv::imwrite("depth/" + m_timestamp + ".png", depth);
// 生成时间戳索引文件
generateText(color_filename, "rgb.txt");
generateText(depth_filename, "depth.txt");
}
5.3 相机内参标定
⚠️ SDK 读取的内参可能为 NaN,需自行标定!
| 参数 | 标定值 |
|---|---|
| fx | 595.4 |
| fy | 593.6 |
| cx | 311.7 |
| cy | 246.7 |
| factor | 1000(mm→m) |
六、系统使用指南 📋
6.1 环境依赖
| 依赖 | 说明 |
|---|---|
| OpenNI2 SDK | 奥比中光官方 SDK(Arm64 版本) |
| PCL | 点云库 |
| OpenCV | 图像处理 |
| cpu_tsdf | TSDF 融合库 |
| Eigen | 矩阵运算 |
6.2 编译与运行
编译:
sh build.sh
数据采集:
sh run_cam.sh
# 连接 Astra Pro,实时预览 + 保存 TUM-RGBD 数据
离线重建:
sh run_reconstruction.sh
# 读取 ORB-SLAM2 关键帧,执行 TSDF 融合 + MC 重建
—
七、测试结果展示 📊

7.1 重建效果
| 场景 | 效果描述 |
|---|---|
| 🏠 室内墙面 | 纹理清晰,几何准确 |
| 🚪 门框边缘 | 边缘锐利,无明显变形 |
| 🪜 楼梯区域 | 多楼层级联成功 |
| 📦 家具物件 | 轮廓完整,细节保留 |
7.2 技术指标
| 指标 | 数值 |
|---|---|
| 最大建图范围 | 20m × 20m × 20m |
| 体素分辨率 | 2048³(~1cm 精度) |
| 传感器距离 | 0 ~ 3m |
| 深度截断 | ±3cm |
| 颜色融合 | RGB 纹理保留 |
八、技术创新亮点 💡
8.1 四大核心创新
| 创新点 | 说明 |
|---|---|
| 🎯 ORB-SLAM2 扩展 | 基于开源框架扩展多楼层大型室内环境稠密重建 |
| 🔄 TSDF 融合优化 | 避免点云密度爆炸,减少累计误差 |
| 📐 统计滤波去噪 | 优化点云质量,移除离群点 |
| 🌐 八叉树加速 | 支持大场景高效存储与查询 |
8.2 与传统方法对比
| 方法 | 密度控制 | 累计误差 | 表面提取 |
|---|---|---|---|
| 直接点云融合 | ❌ 爆炸式增长 | ❌ 逐帧累积 | ❌ 需额外处理 |
| 本方案 TSDF | ✅ 体素网格 | ✅ 融合平均 | ✅ 等值面直接提取 |
九、踩坑与解决方案 🧩
9.1 已解决问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 内参读取为 NaN | SDK 兼容性问题 | 手动标定相机内参 |
| ORB 检测失效 | 光照/纹理影响 | 多次采集取最优 |
| 深度阳光干扰 | 结构光原理限制 | 室内采集、避免强光 |
9.2 已知局限
| 局限 | 说明 | 改进方向 |
|---|---|---|
| ⚠️ 实时性不足 | Zora P1 算力限制 | 降采样或 GPU 加速 |
| ⚠️ Ubuntu 兼容性 | 版本适配问题 | 使用指定 Armbian 版本 |
| ⚠️ 室外效果差 | 红外结构光原理 | 改用 ToF 或双目方案 |
十、总结与展望 🚀
核心贡献
– 🏢 完整解决方案:从数据采集到模型输出,端到端实现
– 🔧 TSDF 创新应用:巧妙解决大场景点云融合难题
– 🎨 纹理保留:RGB 融合,真实感强
– 🔋 便携部署:移动电源系统,支持户外作业
未来方向
| 方向 | 目标 |
|---|---|
| ⚡ GPU 加速 | 提升实时性,实现在线重建 |
| 🗺️ 多楼层地图拼接 | 楼层间自动注册 |
| 🎭 语义分割 | 添加物体识别标签 |
| 📱 移动端优化 | 手机端实时预览 |
🌟 写在最后: 多楼层室内三维重建是一个充满挑战但极具价值的领域。这支团队巧妙结合 ORB-SLAM2、TSDF 和 Marching Cube,用消费级设备实现了专业级的重建效果。如果你正在寻找室内数字化的解决方案,这套系统绝对值得参考!🏆