19f20b6034685.png

*来源: 第一届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 体素网格 + 八叉树

三、系统硬件架构 🛠️

19f20bdcc9019.png

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 算法总流程

19f20c55ce53d.png

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 是经典的等值面提取算法:

19f20cd15274b.png

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, &param_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 重建

—

七、测试结果展示 📊

19f20cf9bc1c8.png

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,用消费级设备实现了专业级的重建效果。如果你正在寻找室内数字化的解决方案,这套系统绝对值得参考!🏆

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注