19f2111ea8605.png

*来源: 第二届3D视觉创新应用竞赛 | 参赛者:** 黄伟浩、黎镜林、程锦涛*

*硬件平台:** Astra Pro 深度相机 + Jetson Nano 开发板*

*GitHub:** 3DReconstruction_Offline-products*

一、项目亮点速览 ✨

你是否曾幻想过——🛒 网上购物也能像实体店一样"亲眼"看清商品的每一个细节?

这支团队告诉你:当然可以!他们用 RGBD 相机 + AI 算法,为中小商家量身打造了一套低成本、高精度的商品三维重建 + 实时位姿跟踪系统,让线上购物体验 up up!📈

核心能力表格:

核心能力 技术实现
📦 离线三维重建 Astra Pro 采集 + ICP 点云拼接 + 泊松网格重建
🎯 实时位姿跟踪 G2L-Net 深度学习网络 + 6D 姿态估计
📱 AR 效果叠加 三维模型 + 位姿信息 → 个性化增强现实
💰 低成本方案 Jetson Nano + Astra Pro,总成本控制在数千元内

二、背景与意义 🏪

2.1 市场需求

近年来,AR/VR 技术蓬勃发展,国内外巨头纷纷布局:

  • 🕶️ Google Glass、微软 HoloLens、Magic Leap 等 AR 眼镜引爆全球
  • 📈 疫情催化线上交易,2020 年以来线上交易额空前巨大
  • 💡 中小商家迫切需要一种低成本方式展示商品三维模型

2.2 痛点与机遇

大型商家(如苹果 🍎)有能力购买昂贵的高精度成像设备,但广大中小商家望而却步!

我们的目标是:让每个小商家都能拥有自己的 3D 商品展示系统! 💪

2.3 核心应用场景

19f2115ddc22b.png

三、系统架构 🏗️

系统流程图:

19f213d34b2b8.png

系统组成详解:

模块 组件 功能描述
信息采集端 Astra Pro 相机 采集 RGB 彩色图像和深度信息
信息采集端 Jetson Nano 实时处理点云数据,执行背景分割
PC 处理端 RTX 3050 Ti 运行 G2L-Net 深度学习网络
PC 处理端 训练模块 离线训练目标物体识别模型

四、核心技术详解 🔬

4.1 三维重建模块 🏗️

三维重建是本系统的"地基"工程 🎯,主要分为以下步骤:

步骤 1:点云采集与预处理

使用 Astra Pro 相机围绕目标物体旋转采集多帧点云,每帧点云包含:

  • 空间坐标 (x, y, z)
  • RGB 颜色信息

步骤 2:深度滤波——背景分割

由于每帧点云都包含前景、背景和目标物体,背景和前景会干扰 ICP 拼接精度。需要通过条件滤波器剔除干扰点:

19f213f156d25.png

深度滤波代码实现:

// 条件滤波器设置 - 剔除 Z 轴深度范围外的点
pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cloud(new pcl::ConditionAnd<pcl::PointXYZ>());
// 保留 1.0m ~ 1.2m 范围内的点(目标物体所在深度)
range_cloud->addComparison(
    pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(
        new pcl::FieldComparison<pcl::PointXYZ>("z", pcl::ComparisonOps::GT, 1.0)
    )
);
range_cloud->addComparison(
    pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(
        new pcl::FieldComparison<pcl::PointXYZ>("z", pcl::ComparisonOps::LT, 1.2)
    )
);
pcl::ConditionalRemoval<pcl::PointXYZ> condream;
condream.setCondition(range_cloud);
condream.setInputCloud(cloud);
condream.setKeepOrganized(true);
condream.filter(*cloud_filtered);  // 输出:只保留目标物体点云

> 💡 核心思想: 通过设置 Z 轴深度阈值,将目标物体(1.0~1.2m)与前景(小于1.0m)、背景(大于1.2m)分离!

步骤 3:ICP 点云拼接

经过滤波后的多帧点云需要拼接成完整模型,这里采用经典的 ICP(Iterative Closest Point)算法:

19f214b113384.png

ICP 算法核心流程:

// 初始化 ICP 迭代对象
pcl::IterativeClosestPoint<PointT, PointT> icp;
icp.setMaximumIterations(iterations);  // 设置最大迭代次数
// 遍历拼接所有点云帧
for (int i = 1; i <= pcd_num; i++) {
    // 读取当前帧点云
    filename = "data/zheng/" + std::to_string(i) + "rm.ply";
    pcl::io::loadPLYFile(filename, *cloud_tr);
    
    // 设置源点云(待变换)和目标点云(参考)
    icp.setInputSource(cloud_tr);   // 待对齐的点云
    icp.setInputTarget(cloud_icp); // 参考点云
    
    // 执行 ICP 迭代对齐
    icp.align(*cloud_icp);
    
    // 获取变换矩阵 R 和 T
    transformation_matrix = icp.getFinalTransformation().cast<double>();
    
    if (icp.hasConverged()) {
        std::cout << "Fitness Score: " << icp.getFitnessScore() << std::endl;
        print4x4Matrix(transformation_matrix);
    }
}
// 保存拼接结果
pcl::io::savePLYFileASCII("result.ply", *cloud_in);

ICP 算法原理:

步骤 说明
1️⃣ 最近邻搜索 对源点云中每个点,在目标点云中找最近邻点
2️⃣ 误差计算 计算所有最近邻点对之间的距离误差
3️⃣ SVD 分解 求解最优旋转矩阵 R 和平移向量 T
4️⃣ 点云变换 用 R 和 T 变换源点云
5️⃣ 迭代 重复 1-4,直至误差收敛

变换矩阵结构:

| R00  R01  R02  Tx |
| R10  R11  R12  Ty |
| R20  R21  R22  Tz |
|  0    0    0    1  |

步骤 4:K-Means 聚类分割

在更精细的分割任务中,使用 K-Means 聚类 将点云分成 K 个类别:

19f214fda9306.png

K-Means 核心实现:

// K-Means 类定义
class KMeans {
public:
    int m_k;
    std::vector<st_point> mv_pntcloud;           // 待聚类点云
    std::vector<std::vector<st_point>> m_grp_pntcloud;  // K 个类别
    std::vector<st_pointxyz> mv_center;           // K 个中心点
    
    // 设置输入点云
    bool SetInputCloud(pcl::PointCloud<pcl::PointXYZ>::Ptr pPntCloud);
    
    // 初始化 K 个中心点
    bool InitKCenter(st_pointxyz pc_arr[]);
    
    // 执行聚类
    bool Cluster();
    
    // 计算两点间欧氏距离
    double DistBetweenPoints(st_pointxyz& p1, st_pointxyz& p2);
    
    // 更新类别中心
    bool UpdateGroupCenter(std::vector<VecPoint_t>& grp_pntcloud, 
                           std::vector<st_pointxyz>& center);
};

// 聚类核心算法
bool KMeans::Cluster() {
    do {
        // Step 1: 为每个点分配最近的类别
        for (size_t i = 0; i < mv_pntcloud.size(); ++i) {
            double min_dist = DBL_MAX;
            int best_cluster = 0;
            for (size_t j = 0; j < m_k; ++j) {
                double dist = DistBetweenPoints(mv_pntcloud[i].pnt, mv_center[j]);
                if (dist < min_dist) {
                    min_dist = dist;
                    best_cluster = j;
                }
            }
            m_grp_pntcloud[best_cluster].push_back(mv_pntcloud[i]);
        }
        
        // Step 2: 记录旧中心位置
        std::vector<st_pointxyz> old_center = mv_center;
        
        // Step 3: 更新类别中心
        UpdateGroupCenter(m_grp_pntcloud, mv_center);
        
        // Step 4: 检查是否收敛
        if (!ExistCenterShift(old_center, mv_center)) {
            break;  // 中心不再移动,迭代结束
        }
        
        // 清空类别,准备下一轮迭代
        for (size_t i = 0; i < m_k; ++i) {
            m_grp_pntcloud[i].clear();
        }
        
    } while (true);
    
    return true;
}

步骤 5:Mesh 泊松重建

使用 MeshLab 进行表面网格重建:

  1. 计算点云法线方向
  1. 执行泊松表面重建
  1. 导出最终的 3D 模型
19f215716779c.png

4.2 物体位姿估计模块 🎯

G2L-Net 算法概述

G2L-Net(Global to Local Network) 是一种实时 6D 目标姿态估计网络,包含三个核心步骤:

步骤 子模块 功能
1️⃣ 全局定位 YOLOv3 2D 检测,提取 RGB 目标区域
2️⃣ 平移定位 局部平移网络,3D 分割 + 平移预测
3️⃣ 旋转定位 旋转残差估计器,精确旋转估计

G2L-Net 网络结构:

19f2162673fcb.png

关键点 3D-3D 配对求解

ADD 指标计算公式:

ADD = (1/|M|) Σ ||(R·x + T) - (R̃·x + T̃)||
          x∈M
          
其中:R, T 为真实值,R̃, T̃ 为预测值

4.3 ROS 通信与数据同步 🔗

主从机配置

角色 设备 功能
主机 Jetson Nano 发布相机数据 topic
从机 PC 订阅并处理数据

RGB-D 同步订阅

import message_filters

# 创建同步订阅器(ApproximateTime 策略)
rgb_sub = message_filters.Subscriber('/camera/rgb/image_rect_color/compressed', CompressedImage)
depth_sub = message_filters.Subscriber('/camera/depth_registered/hw_registered/image_rect_raw/compressedDepth', CompressedImage)

sync = message_filters.ApproximateTimeSynchronizer(
    [rgb_sub, depth_sub],  # 订阅的 topic 列表
    10,                     # 队列大小
    0.1                     # 同步时间窗口(秒)
)
sync.registerCallback(multi_callback)  # 同步回调函数

def multi_callback(rgb_msg, depth_msg):
    # 处理同步的 RGB 和 Depth 数据
    pass

动态参数调节

参数 调整项 推荐值 说明
RGB 压缩 jpeg_quality 70 平衡画质与带宽
Depth 压缩 png_level 6~7 深度精度与压缩率

五、硬件与软件环境 🛠️

5.1 硬件配置

设备 型号 用途
📷 深度相机 Astra Pro RGB-D 数据采集
💻 边缘计算 Jetson Nano 2G 实时点云预处理
🖥️ PC 处理端 AMD 5600H + RTX 3050 Ti 深度学习推理
🪑 转椅 可旋转办公椅 360° 物体旋转采集

5.2 软件环境

模块 软件/库 版本要求
边缘端系统 Ubuntu 18.04 –
机器人操作系统 ROS Melodic –
相机驱动 libuvc + libuvc_ros –
点云处理 PCL 1.9.1
图像处理 OpenCV 3.4.6
IDE Visual Studio 2019
网格重建 MeshLab 最新版
深度学习 PyTorch + TensorRT –

5.3 环境部署流程

Jetson Nano 环境配置流程
  1️⃣ 烧录镜像
     └─→ 下载 JetPack 4.x (对应 2G 版本)
     └─→ Etcher 烧录至 SD 卡
     
  2️⃣ 安装 Astra Pro 驱动
     └─→ 下载 OpenNI-Linux-x64
     └─→ 安装 libuvc 组件
     
  3️⃣ 安装 ROS Melodic
     └─→ sudo apt install ros-melodic-ros-base
     └─→ source /opt/ros/melodic/setup.bash
     
  4️⃣ 安装 Astra 相机包
     └─→ sudo apt install ros-melodic-astra-*
     
  5️⃣ 验证相机
     └─→ rosrun astra_launch astra.launch
     └─→ rviz 查看 /camera/depth/points

六、性能测试与结果分析 📊

6.1 三维重建效果

测试物体 点云质量 Mesh 效果 细节还原度
正面模型 ⭐⭐⭐⭐⭐ 优秀 高
背面模型 ⭐⭐⭐ 一般 低(仅轮廓)

6.2 位姿估计性能

指标 数值
2D 检测耗时 ~11ms
姿态估计耗时 ~32ms
总帧率 ~23 FPS

6.3 准确率测试

在 33 张测试图片中:

结果 数量 占比
✅ 正确识别 26 张 78.8%
⚠️ 丢弃(未检测/模糊) 5 张 15.2%
❌ 识别错误 2 张 6.0%

> 📌 误差阈值: 旋转向量分量误差小于 π/6 (约 0.523 rad)

七、技术创新与亮点 💡

19f2166b2496a.png

7.1 轻量化硬件平台

  • Astra Pro + Jetson Nano 构建采集-重建-显示一体化设备
  • 体积小、重量轻,便携性强

7.2 低成本解决方案

方案类型 价格范围
工业级 3D 扫描仪 数万 ~ 数十万
本方案 数千元

7.3 高精度重建模型

  • PCL 点云库 + 泊松表面重建
  • 获得精确度较高的三维模型

7.4 离线+实时双模式

模式 适用场景
离线重建 商品模型制作、存档
实时跟踪 AR 效果叠加、位姿监控

八、问题与解决方案 🧩

8.1 ROS 压缩数据问题

问题 原因 解决方案
Depth 压缩失真 JPEG 压缩不适合深度图 使用 compressDepth 子主题
OpenCV 读取失败 编码格式不兼容 使用 cv2.CV_LOAD_IMAGE_UNCHANGED
# 正确的 Depth 解码方式
depth_img_raw = cv2.imdecode(
    np.fromstring(raw_data, np.uint8), 
    cv2.CV_LOAD_IMAGE_UNCHANGED
)

8.2 D2C 对齐不准问题

问题 原因 解决方案
RGB 与 Depth 区域不匹配 Astra Pro 仅在特定距离支持硬件对齐 扩大 YOLO 目标检测框范围

8.3 已知不足

不足项 说明
❌ AR 效果未实现 涉及 OpenGL,开发能力有限
❌ 背面重建效果一般 需要优化 ICP 初始值

九、总结与展望 🚀

核心贡献

– 🎯 低成本解决方案:让中小商家也能享受 3D 商品展示的便利

– 🔧 完整技术闭环:采集 → 重建 → 训练 → 跟踪 → AR

– 📈 实时性能:G2L-Net 实现 23 FPS 的位姿跟踪

未来方向

方向 目标
🎨 AR 效果增强 结合 OpenGL 实现更丰富的 AR 交互
📱 移动端部署 优化模型,实现手机端实时推理
🏭 工业分拣 对接机械臂,实现自动分拣
🤖 自训练模型 开发低成本数据集制作工具

🌟 写在最后: 这支团队用朴素的硬件做出了不简单的成果!从三维重建到实时位姿跟踪,从 ROS 通信到深度学习,每个模块都体现了扎实的技术功底。如果你也有商品 3D 展示的需求,不妨试试这套方案,说不定会有惊喜哦!🎉

发表回复

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