本文档记录 G2L_Net 项目在 Jetson Orin Nano + Ubuntu 22.04 + ROS2 Humble + Orbbec Femto Mega 平台上的阶段性复现流程。当前复现目标到此为止:完成 Femto Mega 对齐 RGBD / 彩色点云采集,并基于 HSV 颜色 + 空间 ROI 辅助分割目标物体点云。后续完整位姿训练与新物体适配不作为本阶段落地目标,只给出技术思路和部分关键代码方向。

1. 阶段目标说明 🎯

原始项目是 G2L-Net 6D 位姿估计代码,原始环境偏旧:

Ubuntu 16.04
Python 3.6
CUDA / PyTorch 老版本
ROS1 风格脚本
LINEMOD 数据集与预训练权重

本次迁移复现的硬件与软件平台为:

NVIDIA Jetson Orin Nano
Ubuntu 22.04
JetPack / CUDA 12.6
PyTorch 2.5.0a0 + NVIDIA Jetson wheel
ROS2 Humble
Orbbec Femto Mega RGB-D 相机

我们本阶段不追求“新物体完整训练并实时输出稳定 6D Pose”,而是把复现边界收束到:

1. 跑通原始功能测试脚本 test_linemod.py
2. 将 ROS1 实时推理脚本迁移到 ROS2
3. 用 Orbbec SDK 发布对齐 RGBD 相机数据
4. 发布结构化位姿 PoseStamped / 4x4 pose matrix
5. 采集一组对齐 RGBD + 彩色点云
6. 用 HSV 颜色范围 + XYZ / 深度 ROI 分割目标物体点云
7. 对后续完整复现给出路线说明

一句话总结:我们先把“相机采集、点云可视化、彩色 ROI 分割”这条链路打通,后续训练与部署先讲清思路,不硬刚全流程。 ✨

2. 当前代码文件说明 🧩

本次新增 / 改造的关键脚本位于:

G2L_Net/demo/
文件 作用
orbbec_ros2_camera_publisher.py 直接使用 pyorbbecsdk 读取 Femto Mega,并发布 ROS2 对齐 RGBD 话题
test_ros2.py 从 ROS2 RGBD 话题读取数据,运行 G2L_Net,并发布结构化位姿
capture_orbbec_rgbd_pointcloud.py 每按一次 s 保存一帧对齐 RGB、深度图和彩色点云
reconstruct_object_from_capture.py 清洗、裁剪、颜色过滤、配准并融合采集点云

默认相机话题设计如下:

/camera/rgb/image_rect_color                       sensor_msgs/Image, bgr8
/camera/depth_registered/hw_registered/image_rect  sensor_msgs/Image, 16UC1, mm
/camera/rgb/camera_info                            sensor_msgs/CameraInfo

位姿输出话题:

/g2l/pose          geometry_msgs/PoseStamped
/g2l/pose_matrix   std_msgs/Float32MultiArray, row-major 4x4 matrix

其中 /g2l/pose 的平移单位是 米,/g2l/pose_matrix 中的平移也统一为 米。

3. Jetson 基础环境准备 🧰

3.1 更新系统软件源

sudo apt update
sudo apt upgrade

如果 Jetson 已经配置好了 JetPack、CUDA 和 PyTorch,不建议随意升级 NVIDIA 相关底层包。升级前最好确认:

python3 - <<'PY'
import torch
print(torch.__version__)
print(torch.cuda.is_available())
print(torch.version.cuda)
PY

本次测试环境里曾确认:

torch: 2.5.0a0+872d972e41.nv24.08
CUDA: 12.6
torch.cuda.is_available(): True

3.2 安装 ROS2 Humble 相关依赖

sudo apt install 
  ros-humble-cv-bridge 
  ros-humble-message-filters 
  ros-humble-sensor-msgs 
  ros-humble-geometry-msgs 
  ros-humble-std-msgs 
  ros-humble-image-transport

每个新终端都需要:

source /opt/ros/humble/setup.bash

如果 Python 找不到 message_filters,优先确认:

source /opt/ros/humble/setup.bash
python3 - <<'PY'
import message_filters
print(message_filters.__file__)
PY

注意:如果你手动覆盖了 PYTHONPATH,不要把 ROS2 的 Python 路径挤掉。推荐写法是追加:

export PYTHONPATH="/home/jetson/ws/good_restruction/default/code/code project test:$PYTHONPATH"

3.3 安装点云查看工具:pcl_viewer / MeshLab / Open3D 👀

安装 PCL 工具

pcl_viewer 来自 pcl-tools:

sudo apt install pcl-tools libpcl-dev

验证:

which pcl_viewer
pcl_viewer --help

打开点云:

pcl_viewer ~/ws/good_restruction/captures/object_01/point_cloud/0001.ply

常用操作:

鼠标左键:旋转
鼠标滚轮:缩放
鼠标中键 / 右键:平移,取决于桌面环境
r:重置视角

安装 MeshLab

sudo apt install meshlab

打开点云:

meshlab ~/ws/good_restruction/captures/object_01/point_cloud/0001.ply

MeshLab 更适合人工检查点云质量,比如:

是否混入桌面
是否混入背景
物体是否完整
是否有明显拖影
点云尺寸是否离谱

安装 Open3D

重建脚本使用 Open3D:

python3 -m pip install open3d

验证:

python3 - <<'PY'
import open3d as o3d
print(o3d.__version__)
PY

如果 Jetson 上 pip install open3d 不可用,可以先只完成 pcl_viewer / MeshLab 的点云质检;Open3D 部分后续再单独处理 wheel 或源码编译。

4. pyorbbecsdk 编译与安装指导 📷

本项目推荐用 Orbbec 官方 Python SDK 直接采集相机数据。假设源码在:

~/ws/pyorbbecsdk-2-main

进入目录:

cd ~/ws/pyorbbecsdk-2-main

安装编译依赖:

sudo apt install 
  build-essential 
  cmake 
  git 
  python3-dev 
  python3-pip 
  python3-numpy 
  libusb-1.0-0-dev 
  libudev-dev

安装 Python 构建工具:

python3 -m pip install --upgrade pip setuptools wheel
python3 -m pip install pybind11

常见编译方式:

mkdir -p build
cd build
cmake ..
make -j$(nproc)

如果项目提供 Python wheel 构建脚本,优先参考官方仓库中的 README.md 或 scripts 目录。编译完成后验证:

python3 - <<'PY'
from pyorbbecsdk import Pipeline
print("pyorbbecsdk import OK")
PY

连接 Femto Mega 后查看 USB 设备:

lsusb | grep -i orbbec

如果普通用户无权限访问相机,需要配置 udev 规则。通常做法是参考 Orbbec SDK 仓库提供的 udev 规则文件,复制到:

/etc/udev/rules.d/

然后执行:

sudo udevadm control --reload-rules
sudo udevadm trigger

重新插拔相机。

5. G2L_Net 基础运行方式 ✅

进入项目 demo 目录:

cd "/home/jetson/ws/good_restruction/default/code/code project test/G2L_Net/demo"

设置 Python 包路径:

export G2L_ROOT="/home/jetson/ws/good_restruction/default/code/code project test"
export PYTHONPATH="$G2L_ROOT:$PYTHONPATH"

运行离线功能测试:

python3 -m G2L_Net.demo.test_linemod

如果从 G2L_Net/demo 目录直接执行:

python3 test_linemod.py

可能出现:

ModuleNotFoundError: No module named 'G2L_Net'

原因是 Python 找不到项目根目录。解决方式是使用 python3 -m ...,或者正确设置 PYTHONPATH。

6. ROS2 相机数据发布 🚦

启动自定义 Orbbec ROS2 相机发布器:

source /opt/ros/humble/setup.bash

cd "/home/jetson/ws/good_restruction/default/code/code project test/G2L_Net/demo"

python3 orbbec_ros2_camera_publisher.py --fps 30

该脚本做了三件关键的事:

1. 使用 pyorbbecsdk 打开 Femto Mega
2. 使用 AlignFilter 将深度对齐到彩色相机坐标系
3. 发布 RGB、aligned depth、CameraInfo

检查话题:

ros2 topic list
ros2 topic echo /camera/rgb/camera_info --once
ros2 topic echo /camera/depth_registered/hw_registered/camera_info --once

如果需要看图像:

rqt_image_view

7. ROS2 实时推理与结构化位姿输出 🧭

另开一个终端:

source /opt/ros/humble/setup.bash

cd "/home/jetson/ws/good_restruction/default/code/code project test/G2L_Net/demo"

export G2L_ROOT="/home/jetson/ws/good_restruction/default/code/code project test"
export PYTHONPATH="$G2L_ROOT:$PYTHONPATH"

python3 test_ros2.py

验证结构化位姿:

ros2 topic echo /g2l/pose --once
ros2 topic echo /g2l/pose_matrix --once
ros2 topic hz /g2l/pose

PoseStamped 示例结构:

header:
  frame_id: camera_color_optical_frame
pose:
  position:
    x: ...
    y: ...
    z: ...
  orientation:
    x: ...
    y: ...
    z: ...
    w: ...

这里的 position 单位是 米。原始 G2L 代码内部多处使用毫米,因此脚本发布 ROS2 Pose 时做了 /1000.0 转换。

8. 采集对齐 RGBD 与彩色点云 📦

先停止所有占用 Femto Mega 的程序,比如:

orbbec_ros2_camera_publisher.py
OrbbecSDK_ROS2 driver
其他 pyorbbecsdk 示例

然后运行采集脚本:

cd "/home/jetson/ws/good_restruction/default/code/code project test/G2L_Net/demo"

python3 capture_orbbec_rgbd_pointcloud.py 
  --output ~/ws/good_restruction/captures/object_01

采集窗口出现后:

s:保存当前帧
q / Esc:退出

建议采集方式:

相机固定
目标物体放在转台或平稳桌面上
每转动 6-18 度按一次 s
绕物体一圈保存 20-60 帧
背景尽量干净,桌面颜色尽量不要接近物体颜色

输出目录:

object_01/
  camera_info.json
  index.csv
  rgb/0001.png
  depth/0001.png
  point_cloud/0001.ply
  preview/0001.jpg

其中:

rgb/*.png:对齐彩色图
depth/*.png:对齐深度图,16UC1,单位 mm
point_cloud/*.ply:带 RGB 颜色的点云
preview/*.jpg:彩色 + 深度叠加预览图

9. 点云质检:先看,再调,再重建 👓

采集完不要急着融合。先打开几个点云看看质量:

pcl_viewer ~/ws/good_restruction/captures/object_01/point_cloud/0001.ply
pcl_viewer ~/ws/good_restruction/captures/object_01/point_cloud/0010.ply
pcl_viewer ~/ws/good_restruction/captures/object_01/point_cloud/0020.ply

或者用 MeshLab:

meshlab ~/ws/good_restruction/captures/object_01/point_cloud/0001.ply

重点检查:

目标物体是否完整
桌面是否过多
背景是否混入
颜色是否正常
点云单位是否正常
不同帧之间是不是相机没动、物体在动

如果原始点云已经很乱,后面算法会很辛苦。此时最有效的修复方式通常不是调参,而是重新采集:更干净的背景、更稳定的光照、更近一点的距离、更慢一点的转动。

10. 彩色辅助 ROI 分割:当前阶段的重点 🌈

目标物体有红、黑、黄三种颜色,因此可以使用 HSV 颜色范围辅助分割。

脚本支持最多 3 个 HSV 范围:

--hsv-range HMIN,HMAX,SMIN,SMAX,VMIN,VMAX

OpenCV HSV 范围:

H: 0-179
S: 0-255
V: 0-255

红色常跨越 HSV 边界,因此可以写成:

--hsv-range 170,10,70,255,40,255

脚本会理解为:

H >= 170 或 H <= 10

红、黄、黑三色过滤推荐起步命令:

cd "/home/jetson/ws/good_restruction/default/code/code project test/G2L_Net/demo"

python3 reconstruct_object_from_capture.py 
  --input ~/ws/good_restruction/captures/object_01 
  --output ~/ws/good_restruction/captures/object_01/reconstruction_red_black_yellow_try1 
  --object-name obj_01 
  --max-frames 10 
  --x-min -0.30 --x-max 0.30 
  --y-min -0.30 --y-max 0.30 
  --min-depth 0.25 --max-depth 1.50 
  --voxel-size 0.003 
  --ransac-distance 0.025 
  --icp-distance 0.015 
  --hsv-range 170,10,70,255,40,255 
  --hsv-range 18,42,60,255,50,255 
  --hsv-range 0,179,0,255,0,65

三个颜色范围分别代表:

红色:170,10,70,255,40,255
黄色:18,42,60,255,50,255
黑色:0,179,0,255,0,65

脚本日志中会出现:

color=保留点数/颜色过滤前点数

调参建议:

黑色区域漏得多:把黑色 V 上限从 65 提到 85
背景被保留太多:收紧 x/y ROI 或提高 S 下限
黄色发暗:降低黄色 V 下限,比如 50 -> 35
红色不完整:尝试 160,15 或降低 S 下限

11. 重建结果检查与判断标准 📏

查看报告:

cat ~/ws/good_restruction/captures/object_01/reconstruction_red_black_yellow_try1/reconstruction_report.json

重点看:

point_count
bbox_extent_m
diameter_mm_bbox_diagonal

如果一个桌面小物体真实尺寸约 10 cm,那么直径通常应该是:

几十 mm 到两三百 mm

如果出现:

diameter_mm_bbox_diagonal: 2048

这就明显不对。除非你的物体真的有 2 米大,否则说明混入了大量背景,或点云配准严重漂移。

打开结果:

pcl_viewer ~/ws/good_restruction/captures/object_01/reconstruction_red_black_yellow_try1/obj_01.ply

也可以检查中间结果:

pcl_viewer ~/ws/good_restruction/captures/object_01/reconstruction_red_black_yellow_try1/cleaned/0001_0001.ply
pcl_viewer ~/ws/good_restruction/captures/object_01/reconstruction_red_black_yellow_try1/registered/0002_0002.ply

判断逻辑:

cleaned 里很脏:颜色 / ROI / 深度范围需要继续调
cleaned 干净但 merged 散开:配准失败,需要减少帧数、调 ICP / RANSAC 或改用辅助标定方法
前 10 帧正常,更多帧散开:分段配准或剔除坏帧

12. 超参数调节原则 🛠️

优先级从高到低:

1. XYZ / depth ROI
2. HSV 颜色范围
3. voxel-size
4. ransac-distance / icp-distance
5. 是否去桌面平面

12.1 ROI 范围

起步:

--x-min -0.30 --x-max 0.30
--y-min -0.30 --y-max 0.30
--min-depth 0.25 --max-depth 1.50

背景太多就收紧:

--x-min -0.20 --x-max 0.20
--y-min -0.20 --y-max 0.20
--min-depth 0.30 --max-depth 1.20

物体被裁掉就放宽。

12.2 voxel-size

单位是米:

小物体:0.0015 - 0.003
中等物体:0.003 - 0.005
大物体:0.005 - 0.01

建议起步:

--voxel-size 0.003

12.3 RANSAC / ICP 阈值

经验关系:

ransac-distance ≈ 6-10 倍 voxel-size
icp-distance ≈ 3-6 倍 voxel-size

例如:

--voxel-size 0.003
--ransac-distance 0.025
--icp-distance 0.015

12.4 去桌面平面

如果桌面很多,默认去平面有帮助。

如果目标物体本身有大平面,例如盒子、板状物,可能被误删,可以加:

--no-remove-plane

13. 本阶段代码片段:多颜色 HSV 过滤 🔍

核心思想是“多个颜色范围取并集”:

keep = np.zeros(len(colors), dtype=bool)

for h_min, h_max, s_min, s_max, v_min, v_max in hsv_ranges:
    if h_min <= h_max:
        hue_mask = (hsv[:, 0] >= h_min) & (hsv[:, 0] <= h_max)
    else:
        hue_mask = (hsv[:, 0] >= h_min) | (hsv[:, 0] <= h_max)

    keep |= (
        hue_mask
        & (hsv[:, 1] >= s_min)
        & (hsv[:, 1] <= s_max)
        & (hsv[:, 2] >= v_min)
        & (hsv[:, 2] <= v_max)
    )

这样红、黑、黄三种颜色不是互相排斥的条件,而是:

红色点 OR 黄色点 OR 黑色点

这比只靠空间 ROI 更适合“目标物体颜色明确、背景颜色不同”的场景。

14. 后续完整复现路线:讲思路,不在本阶段硬落地 🧠

如果后续要继续走完整新物体 6D 位姿估计,需要注意:

只有物体点云模型是不够的。

G2L_Net 推理链路还依赖:

YOLO 检测权重
Seg3D / CE / box / gan / vec 等网络权重
models_info.yml
obj_XX.ply
相机内参
真实或合成训练数据

完整路线大致是:

1. 通过彩色 ROI 得到干净物体模型 obj_XX.ply
2. 计算物体 diameter 并更新 models_info.yml
3. 生成训练数据:RGB、depth、mask、bbox、pose label
4. 训练或微调 YOLO 检测器
5. 训练 G2L_Net 位姿相关网络
6. 将权重放入 G2L_Net/models/XX/
7. 修改 object_id 并运行 test_ros2.py
8. 通过 /g2l/pose 和可视化投影框评估效果

训练数据生成可以考虑两条路线:

路线 A:真实采集 + 人工/半自动标注
路线 B:基于 obj_XX.ply 的合成渲染数据

如果只希望快速形成工程闭环,也可以考虑另一条更工程化的方案:

YOLO / 颜色分割定位目标区域
RGBD 生成局部点云
局部点云与 obj_XX.ply 做 ICP / colored ICP
输出 6D 位姿

这条路线不完全等价于论文 G2L_Net,但对特定物体、特定场景常常更容易落地。

15. 常见问题排查 🧯

15.1No module named G2L_Net

原因:没有设置项目根目录。

解决:

export PYTHONPATH="/home/jetson/ws/good_restruction/default/code/code project test:$PYTHONPATH"

或使用:

python3 -m G2L_Net.demo.test_linemod

15.2No module named message_filters

安装:

sudo apt install ros-humble-message-filters
source /opt/ros/humble/setup.bash

确认 Python 路径没有覆盖 ROS2 环境。

15.3 OpenCVcv2.line 点类型报错

OpenCV 4 对点坐标类型更严格,线段端点必须是 Python int tuple,而不是 np.float32。

修复方式是将投影点显式转换:

(int(round(x)), int(round(y)))

15.4 ArUco API 报错

OpenCV 4.10 的 ArUco API 与旧版本不同,旧写法:

cv2.aruco.Dictionary(...)

可能需要替换为:

cv2.aruco.getPredefinedDictionary(...)

detectMarkers 也不再接受部分旧关键字参数,需要按新 API 调整。

15.5 重建出来的直径离谱

例如:

diameter_mm_bbox_diagonal: 2048

如果目标物体并不是 2 米级别,那就是背景混入或配准漂移。

处理顺序:

1. 打开 cleaned 单帧看是否干净
2. 收紧 XYZ / depth ROI
3. 调整 HSV 范围
4. 先只跑 max-frames 10
5. 再逐步增加帧数

16. 本阶段结论 ✅

本阶段复现已经完成到:

Jetson Orin Nano 环境可运行 G2L_Net 基础测试
Femto Mega 可采集对齐 RGBD
ROS2 版本相机发布和推理脚本已打通
可发布结构化位姿话题
可手动采集多帧彩色点云
可利用红 / 黑 / 黄 HSV 颜色范围辅助 ROI 分割目标物体点云

后续若继续推进完整 6D 位姿复现,重点不再是相机链路,而是:

新物体数据集制作
检测模型训练
G2L_Net 位姿网络训练
模型文件与尺度单位管理
真实场景精度评估

到这里,本阶段的“小闭环”已经跑起来了。

下一步要不要继续炼成完整 6D Pose,就看项目目标和时间预算啦。🙂

发表回复

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