
1. 项目速览:把三维重建从“重装备”变成“手持工具”
这个项目面向室内环境三维重建,目标很直接:让用户只需手持 Astra Pro RGB-D 相机 与 Zora P1 嵌入式开发板,就能完成室内空间扫描、位姿估计、点云融合与模型可视化。它不是把所有计算硬塞进一块板子里“硬扛”,而是采用轻量化、松耦合的系统设计:采集端保持灵活,计算端按能力分工,通信端由 ROS 串起来。这样一来,设备轻了,部署活了,重建链路也更容易扩展。🚀
| 项目要素 | 内容 |
|---|---|
| 项目名称 | 轻量化松耦合的手持 RGB-D 室内环境实时重建系统 |
| 来源 | 第一届 3D 视觉创新应用竞赛,陈钧涛 |
| 主要传感器 | Astra Pro RGB-D 相机 |
| 嵌入式设备 | Zora P1 开发板 |
| 核心软件栈 | ROS、PCL、OctoMap、G2O、Eigen3、OpenCV、Qt5、OpenMP |
| 主要能力 | RGB-D 采集、位姿估计、TSDF 融合、网格生成、在线/离线可视化 |
| 源代码 | 3DReconstruction_Handheld-reconstruction|
一句话概括:它把“相机采集、位姿估计、三维融合、模型显示”拆成可以独立协作的模块,让手持扫描不再被单机算力和设备体积绑住手脚。
2. 系统架构:三端协作,轻装上阵 🧩

系统整体可以理解为“三端协作”:
| 端侧 | 主要职责 | 典型组件 |
|---|---|---|
| 采集端 | 采集 RGB 图像、深度图、相机内参,并通过 ROS 发布数据 | Astra Pro、Zora P1、astra_camera |
| 服务端 | 进行较重的位姿估计与全局优化,并将优化后的相机位姿返回 | BundleFusion、GPU 工作站 |
| 在线端 | 在 PC 上完成一站式实时重建、图优化与可视化 | RGBD-SLAM v2、PCL、OctoMap、G2O |
这种设计的关键不在于“模块越多越热闹”,而在于每个模块都做自己最擅长的事情:嵌入式端负责轻便采集与局部融合,服务器负责高负载优化,PC 在线端负责交互式重建和展示。系统通过 ROS 消息连接,模块之间保持低耦合,后续替换相机、调整算法或升级计算端都更从容。
3. 两条重建路线:一条偏手持交互,一条偏在线显示

项目实现了两套互补流程:
| 模式 | 数据流 | 适用场景 | 技术重点 |
|---|---|---|---|
| 嵌入式/服务端协同模式 | Zora P1 采集 RGB-D → 服务器估计位姿 → 开发板融合与渲染 | 手持扫描、轻量端交互、服务器远程辅助 | ROS 通信、BundleFusion 位姿优化、FastFusion 融合 |
| PC 在线重建模式 | Zora P1 采集 RGB-D → PC 端直接估计位姿、建图与显示 | 桌面端快速验证、可视化调试、在线建图 | RGBD-SLAM、ORB 特征、RANSAC、G2O、OctoMap |
前者像是“轻便扫描枪 + 远程大脑”,后者像是“PC 工作站一站式重建台”。两者都围绕同一个目标:让室内场景以较低成本被实时捕获、配准并重建出来。
4. ROS 通信:让相机、开发板、服务器像一个系统一样说话 📡

项目里专门定义了 topic_demo 消息包,用于在 ROS 网络中传输相机位姿与 RGB-D 图像。这个设计非常重要:它把“位姿”和“图像帧”打包成同一个消息,开发板收到消息后就能直接把对应帧融合进模型,避免时间戳错位造成的建图抖动。
# topic_demo/msg/pose.msg
int32 time
float32 translation1
float32 translation2
float32 translation3
float32 q1
float32 q2
float32 q3
float32 q4
string depthname
string rgbname
sensor_msgs/Image colorImage
sensor_msgs/Image depthImage
跨设备运行时,需要让不同主机共享同一个 ROS Master。项目说明中给出了典型 IP 配置:
# 主机端,例如 192.168.2.51
export ROS_HOSTNAME=192.168.2.51
export ROS_MASTER_URI=http://192.168.2.53:11311
# 开发板端,例如 192.168.2.53
export ROS_HOSTNAME=192.168.2.53
export ROS_MASTER_URI=http://192.168.2.53:11311
# 开发板启动 Astra Pro
roslaunch astra_camera astrapro.launch
这套通信方式的好处是:相机必须接在开发板上,但重建算法不必都跑在开发板上。只要网络打通,服务端和在线端就能订阅数据、发布位姿、完成融合,系统部署弹性明显增强。
5. 服务器端:BundleFusion 负责“把相机走过的路算准” 🧠

在嵌入式/服务端协同模式中,服务器端运行 BundleFusion 相关节点。它订阅开发板发布的 RGB 图像和深度图,计算当前帧的相机位姿,然后把平移、四元数、RGB 图像和深度图一起发布到 pose_info。
核心发布逻辑可以概括为:
// bundlefusion_ros: 订阅 RGB-D 图像,并发布优化后的位姿消息
validTransform = g_depthSensingBundler->getCurrentIntegrationFrame(
transformation, frameIdx, bGlobalTrackingLost
);
vec3f translation_vector = transformation.getTranslation();
Eigen::Quaternionf q(rotation_matrix_eigen);
topic_demo::pose msg;
msg.time = frameIdx;
msg.translation1 = translation_vector[0];
msg.translation2 = translation_vector[1];
msg.translation3 = translation_vector[2];
msg.q1 = -q.coeffs().transpose()[0];
msg.q2 = -q.coeffs().transpose()[1];
msg.q3 = -q.coeffs().transpose()[2];
msg.q4 = q.coeffs().transpose()[3];
cv_bridge::CvImage(...).toImageMsg(msg.colorImage);
cv_bridge::CvImage(...).toImageMsg(msg.depthImage);
pub.publish(msg);
从算法角度看,BundleFusion 的优势在于它不是只看“上一帧到下一帧”的短距离匹配,而是通过全局联合优化减少累积漂移。项目技术文档中提到的层次式思路可以理解为:
| 优化层级 | 作用 | 为什么重要 |
|---|---|---|
| 帧间跟踪 | 估计相邻 RGB-D 帧之间的相对运动 | 提供连续运动线索 |
| 分段优化 | 将视频流切成片段,片段内做局部一致性约束 | 降低长序列直接优化的复杂度 |
| 关键帧优化 | 以片段关键帧为节点做全局约束 | 控制长时间扫描中的漂移 |
| 回环约束 | 当相机回到旧区域时修正历史轨迹 | 让房间“闭合”得更自然 |
因此,服务端就像系统里的“位姿审稿人”:它不只问“这一帧像不像上一帧”,还会回头检查整个轨迹是否自洽。
6. 嵌入式端:FastFusion 用八叉树 TSDF 把深度帧熔成模型 🔧

开发板端接收 pose_info 后,会把位姿、RGB 图和深度图转换成 FastFusion 所需的数据结构,并调用 fusion->addMap() 进行融合,再用 fusion->updateMeshes() 更新网格。
// fastfusion_ros: 接收服务器发布的 pose_info,并执行融合
void addMapCallback(const topic_demo::pose::ConstPtr& msg, ...) {
Eigen::Quaterniond q(msg->q4, msg->q1, msg->q2, msg->q3);
Eigen::Vector3d t(msg->translation1, msg->translation2, msg->translation3);
CameraInfo pose(kinectPoseFromEigen1({ q.toRotationMatrix(), t },
fx, fy, cx, cy));
cv::Mat rgbimage =
cv_bridge::toCvCopy(msg->colorImage, msg->colorImage.encoding)->image;
cv::Mat depthimage =
cv_bridge::toCvCopy(msg->depthImage, msg->depthImage.encoding)->image;
fusion->addMap(depthimage, pose, rgbimage,
1.0f / imageDepthScale, maxCamDistance);
*newMesh = fusion->updateMeshes();
}
这里的关键技术是 TSDF(Truncated Signed Distance Function,截断符号距离函数)融合。它会把每一帧深度图投影到三维空间,把表面附近的体素距离不断加权平均。八叉树结构则让空间管理更聪明:有几何细节的地方细分得更密,空旷区域不浪费内存。
伪代码:八叉树 TSDF 融合流程
for each depth pixel:
point_3d = back_project(pixel, depth, camera_intrinsics)
point_world = transform(point_3d, camera_pose)
brick = octree.find_or_create_brick(point_world)
for each voxel near projected surface:
sdf = compute_signed_distance(voxel, depth_surface)
tsdf = clamp(sdf / truncation_distance, -1, 1)
voxel.tsdf = weighted_average(voxel.tsdf, tsdf)
voxel.color = weighted_average(voxel.color, rgb_pixel)
voxel.weight += observation_weight
mark_updated_bricks_for_incremental_meshing()
update_mesh_by_marching_cubes()
从工程实现看,fastfusion_ros 中的 FusionMipMapCPU 封装了地图融合、网格更新和队列管理等接口:
// fastfusion_ros/src/fusion/geometryfusion_mipmap_cpu.hpp
class FusionMipMapCPU : public Fusion_AoS {
public:
void addMap(const cv::Mat& imageDepth,
const CameraInfo& info,
const cv::Mat& imageColor,
float depthScaleFactor,
float maxCamDistance);
MeshSeparate getMeshSeparateMarchingCubes();
boost::shared_ptr<MeshInterleaved> updateMeshes();
void pushLeafQueueForMeshing(MapTreeNode* leaf);
};
这套方案的亮点是:它没有要求开发板实时跑完整的高负载全局优化,而是让开发板专注于接收优化位姿后的融合与渲染。算力分配更合理,系统也更接近真实可用的手持扫描流程。
7. 在线端:RGBD-SLAM 让 PC 直接“边看边建图” 🖥️

在线端主要基于 RGBD-SLAM v2。它直接订阅开发板发布的 RGB 图、深度图和相机内参,在 PC 上完成特征提取、位姿估计、图优化和可视化。项目中的 rgbdslam_orbbec.launch 已经把 Astra Pro 的话题接入配置好:
<!-- rgbdslam/launch/rgbdslam_orbbec.launch -->
<param name="config/topic_image_mono"
value="/camera/rgb/image_rect_color"/>
<param name="config/topic_image_depth"
value="/camera/depth/image_rect"/>
<param name="config/topic_cam_info"
value="/camera/depth/camera_info"/>
<param name="config/feature_extractor_type" value="ORB"/>
<param name="config/feature_detector_type" value="ORB"/>
<param name="config/max_keypoints" value="600"/>
<param name="config/max_matches" value="300"/>
<param name="config/ransac_iterations" value="100"/>
<param name="config/backend_solver" value="pcg"/>
在线重建链路可以拆成四步:
| 阶段 | 输入 | 处理方法 | 输出 |
|---|---|---|---|
| 特征提取 | RGB 图像 | ORB 特征检测与描述 | 稀疏特征点 |
| 位姿估计 | 特征匹配、深度信息 | RANSAC 筛除误匹配 | 帧间相对位姿 |
| 图优化 | 位姿节点与约束边 | G2O 后端优化 | 全局一致轨迹 |
| 地图生成 | 深度点云与优化位姿 | PCL/OctoMap 融合 | 点云或八叉树地图 |
其中,ORB 是一个工程上很务实的选择:它速度快、适合 CPU 实时运行,能在室内纹理较丰富的办公桌、墙面边缘、设备轮廓上提取稳定特征。配合 RANSAC 和 G2O,系统可以在噪声和局部遮挡中保持较稳健的轨迹估计。
8. 相机标定:内参不准,模型就会“长歪” 📐

Astra Pro 的 RGB 与深度数据要想可靠融合,内参标定必须先过关。项目技术文档中采用棋盘格分别标定 RGB 相机与红外相机,示例流程如下:
% 相机标定核心流程示意
images = imageDatastore('color/');
[imagePoints, boardSize] = detectCheckerboardPoints(images.Files);
squareSize = 30; % mm
worldPoints = generateCheckerboardPoints(boardSize, squareSize);
I = readimage(images, 1);
imageSize = [size(I, 1), size(I, 2)];
cameraParams = estimateCameraParameters(imagePoints, worldPoints, ...
'ImageSize', imageSize);
标定后的内参会影响反投影、点云生成、TSDF 融合和位姿估计。换句话说,内参不是“配置表里随便填的数字”,而是整个系统从二维图像走向三维空间的尺子。
9. 工程部署:依赖多,但脉络很清楚

项目源码主要包含四个 ROS 包:
| ROS 包 | 角色 | 说明 |
|---|---|---|
topic_demo |
消息定义 | 定义包含位姿与 RGB-D 图像的 pose 消息 |
bundlefusion_ros |
服务端优化 | 将 BundleFusion 接入 ROS,用于位姿估计与全局优化 |
fastfusion_ros |
嵌入式融合 | 接收优化位姿与图像,执行 TSDF 融合和网格更新 |
rgbdslam |
在线重建 | 基于 RGBD-SLAM v2 完成 PC 端在线建图与显示 |
环境依赖可以按端侧理解:
| 端侧 | 关键依赖 | 作用 |
|---|---|---|
| 开发板端 | ROS、OpenCV、Boost、Eigen3、Astra 驱动 | 采集 RGB-D 数据,运行轻量融合与显示 |
| 服务端 | ROS Melodic、CUDA、OpenGL、GLEW、Eigen3、OpenCV | 运行 BundleFusion 与 GPU 相关优化 |
| 在线端 | ROS Melodic、PCL 1.8、OctoMap 1.6、G2O、Qt5、OpenMP、Eigen3、OpenCV | 运行 RGBD-SLAM、点云/八叉树地图与 GUI |
典型编译方式与普通 ROS 工作空间一致:
cd ~/catkin_ws/src
# 将 bundlefusion_ros、fastfusion_ros、rgbdslam、topic_demo 放入 src
cd ~/catkin_ws
catkin_make
source devel/setup.bash
需要注意的是,bundlefusion_ros 依赖较大的外部库目录,项目 README 中提示需要额外下载并放入指定位置;此外,部分旧依赖涉及 OpenCV、CUDA、GLEW、GTK 和编译器版本,部署时应尽量按项目文档的版本组合进行复现。
10. 重建效果与性能:轻量设备也能认真干活 📊

项目技术文档中展示了约 10 平方米室内区域的重建结果,包括桌面细节、开放式桌面区域,以及三工位、四工位等办公场景。整体表现说明系统可以恢复桌椅相对位置、桌面结构和主要室内布局,适合室内扫描、空间数字化、机器人环境建模等场景。
性能数据如下,已整理为适合飞书粘贴阅读的表格:
| 运行端 | 测试内容 | 速度 |
|---|---|---|
| 开发板离线端 | 数据集融合 | 11.6 fps |
| 开发板离线端 | 数据集渲染 | 2.3 fps |
| 开发板离线端 | 实时读取 ROS 数据并融合 | 8.6 fps |
| 开发板离线端 | 实时读取 ROS 数据并渲染 | 2.8 fps |
| GPU 服务端 | 数据集重建 | 2.6 fps |
| GPU 服务端 | 实时读取 ROS 数据并重建 | 8.6 fps |
| CPU 在线端 | 数据集重建与渲染 | 7.6 fps |
| CPU 在线端 | 实时读取 ROS 数据并重建渲染 | 8.4 fps |
从数据可以看出,系统的实时性不是靠单点爆发,而是靠任务拆分实现平衡:服务端负责重位姿计算,开发板负责融合显示,在线端负责 PC 一体化重建。这样的架构对低成本设备更友好,也便于后续扩展更强算力或更高分辨率传感器。
11. 技术亮点:轻、准、活,三件事都要 ✨
| 技术亮点 | 具体体现 | 工程价值 |
|---|---|---|
| 轻量化手持采集 | Astra Pro 与 Zora P1 体积小、重量低 | 降低室内扫描门槛 |
| 松耦合系统架构 | ROS 网络连接采集端、服务端、在线端 | 便于调试、替换和扩展 |
| 八叉树 TSDF 融合 | 按空间复杂度管理体素与网格更新 | 节省内存,提高融合效率 |
| 全局位姿优化 | BundleFusion 进行层次式联合优化 | 减少轨迹漂移,提高模型一致性 |
| 在线 SLAM 可视化 | RGBD-SLAM 支持实时轨迹和地图展示 | 方便实验验证与现场演示 |
不过,项目也暴露出很真实的工程边界:Zora P1 的内存和 CPU 资源有限,若把所有重建任务都压在开发板上,容易出现卡顿甚至崩溃。因此,项目最后采用“位姿优化外包、开发板融合显示”的策略,本质上是在有限硬件条件下做了一次很务实的系统工程取舍。
12. 可优化方向:下一版可以更丝滑 🛠️

| 优化方向 | 可行做法 | 预期收益 |
|---|---|---|
| 降低通信延迟 | 压缩 RGB-D 数据、同步时间戳、优化 ROS 队列 | 提升实时扫描稳定性 |
| 提高嵌入式端性能 | 使用更高效的 TSDF 数据结构或 GPU/NPU 加速 | 提升融合与渲染帧率 |
| 增强弱纹理鲁棒性 | 引入 IMU、平面约束或语义特征 | 减少白墙、走廊场景漂移 |
| 改善模型质量 | 加入深度滤波、法向一致性约束、后处理网格优化 | 降低噪声,提升表面平滑度 |
| 简化部署 | 容器化依赖、统一启动脚本、可视化配置面板 | 降低复现实验和现场演示成本 |
13. 总结:这不是“一个算法”,而是一套会协作的重建系统
这套轻量化松耦合手持 RGB-D 室内实时重建系统的价值,不只在于能生成室内三维模型,更在于它把复杂重建任务拆解成了清晰的系统链路:Astra Pro 负责看见世界,Zora P1 负责轻便采集与交互,服务器负责算准位姿,PC 在线端负责快速验证和展示。
它的路线并不花哨,却很工程化:用 ROS 做通信胶水,用 BundleFusion 解决精确位姿,用 FastFusion 完成高效融合,用 RGBD-SLAM 支撑在线重建。对于低成本 RGB-D 设备、嵌入式视觉和室内数字化应用来说,这是一套很有参考价值的系统范例。换个更轻快的说法:拿起相机走一圈,空间数据就开始认真排队建模了。 🎯