
来源:第四届3D视觉创新应用竞赛 | 深圳大学 | 吴鹏飞 源代码:https://github.com/3DCVdeveloper/RobotV_Grab-box 相机SDK:奥比中光 Orbbec SDK 机械臂SDK:JAKA SDK
一、项目背景:中国智造的最后一公里
1.1 行业痛点
"中国制造2025"战略正推动我国制造业加速智能化转型,但在物流自动化领域,传统无序抓取技术仍面临严峻挑战:
- ❌ 遮挡干扰:纸箱随机堆叠,相互遮挡,识别困难
- ❌ 效率低下:人工搬运劳动强度大、效率低、成本高
- ❌ 精度不足:传统方法难以准确获取纸箱的6D位姿信息
1.2 解决方案
本项目设计了一套无序场景下的纸箱位姿识别系统,通过 数据采集 → 目标定位 → 位姿估计 → 机械臂抓取 四大核心步骤,实现复杂堆叠场景下的智能抓取。
技术亮点一览:
| 技术模块 | 核心技术 | 优势 |
|---|---|---|
| 🎮 数据采集 | NVIDIA Isaac Sim 虚拟仿真 | 大规模、高质量数据集 |
| 👁️ 目标定位 | YOLOv8 实例分割 | 轻量化、高效率 |
| 📐 位姿估计 | PCA + ICP 联合配准 | 粗精结合、精度保证 |
| 🤖 机械臂控制 | 节卡 zu12 + 手眼标定 | 精准抓取 |
二、系统架构:从"看"到"抓"的完整链路
2.1 整体流程图

2.2 硬件配置
| 组件 | 型号 | 关键参数 |
|---|---|---|
| 🎥 深度相机 | Orbbec Gemini 2 | 双目结构光、高分辨率深度图 |
| 🧠 计算平台 | NVIDIA Jetson Orin Nano | 边缘AI推理 |
| 🤖 机械臂 | 节卡机器人 zu12 | 四自由度、精准控制 |
| 💾 训练环境 | RTX 3090 × 2 | 深度学习训练 |
三、虚拟数据集:Isaac Sim仿真训练
3.1 为什么需要虚拟数据?
传统人工采集数据的局限性:
- 📷 角度覆盖不全,难以获取全视角数据
- ⏰ 标注效率低,无法快速生成大规模数据集
- 🏭 真实场景采集成本高、周期长
3.2 Isaac Sim 虚拟仿真流程
# NVIDIA Isaac Sim 虚拟数据生成核心流程
params_json_string = json.dumps({
"{plane.plane_splitter.icp_boxes}": [
[300.0, 200.0, 100.0], # 纸箱尺寸列表
[400.0, 300.0, 150.0]
],
"{plane.plane_splitter.threshold_height}": 50.0, # 高度差异阈值
"${plane.plane_splitter.visualize}": False
})
生成数据包括:
- JPG格式RGB图像(8位)
- NPY格式深度图像(16位)
- 边界框标注
- 相机位姿变换矩阵
- 分割图像
虚拟仿真优势:
- ✅ 场景多样:可随机化光源、材质、纹理、纸箱大小
- ✅ 物理真实:内置物理引擎模拟纸箱掉落堆叠
- ✅ 标注自动:自动生成边界框、深度图、位姿标签
- ✅ 规模可控:可生成任意数量的训练数据
3.3 仿真数据生成步骤

四、目标定位:YOLOv8 实例分割
4.1 为什么选择 YOLOv8?
考虑到纸箱纹理简单、对检测速度要求高(实时抓取),YOLOv8 成为最佳选择:
- ⚡ One-Stage检测:无需区域建议步长,直接从图像提取预测框
- 🎯 高精度:相比两阶段检测器,精度相当但速度更快
- 📦 轻量化:模型小,适合边缘设备部署(Jetson Orin Nano)
4.2 YOLOv8 网络架构

4.3 核心代码实现
# main.py - YOLOv8目标检测调用
from ultralytics import YOLO
import open3d as o3d
# 加载训练好的模型
weight_path = '/home/xiaofeifei/Downloads/ultralytics-main/boxs.pt'
model = YOLO(weight_path)
# 获取相机帧
frames = pipeline.wait_for_frames(10000)
color_frame = frames.get_color_frame()
color_image = frame_to_bgr_image(color_frame)
# YOLOv8预测
results = model.predict(source=color_image)
# 可视化检测结果
annotated_frame = results[0].plot()
cv2.imshow("Color Viewer", annotated_frame)
# 获取检测结果用于位姿估计
# results[0].obb.xywhr 包含检测框的中心点、宽高、旋转角度
maskrcnn_result = results[0].obb.xywhr.tolist()
关键参数配置:
Method: YOLOv8
Backbone: CSPDarknet53+Focus
Neck: PANet
Head: Decoupled Head
学习率: SGD, lr=0.01, momentum=0.9
输入尺寸: 640 × 640
数据增强: 随机裁剪、随机翻转、归一化
五、位姿估计:PCA + ICP 联合配准
5.1 6D位姿估计概述
位姿估计的目标是求解物体坐标系O到相机坐标系C的刚性变换:
T_OC = [R_3×3 | t_3×1]
其中:
- R:3D旋转矩阵
- t:3D平移向量
两阶段配准策略:
粗配准(PCA) → 快速获得初始位姿 精配准(ICP) → 迭代优化精细结果
5.2 PCA 粗配准原理
PCA(主成分分析)通过分析点云的主要分布方向,快速获得纸箱的大致位姿:
# PCA粗配准核心流程
def pca_alignment(point_cloud):
# 1. 计算点云的协方差矩阵
covariance_matrix = np.cov(point_cloud.T)
# 2. SVD分解获取特征向量
eigenvalues, eigenvectors = np.linalg.eig(covariance_matrix)
# 3. 特征向量即为点云的主方向(纸箱的长宽轴)
principal_axes = eigenvectors[:3]
# 4. 根据主方向计算旋转矩阵R
R = compute_rotation_matrix(principal_axes)
# 5. 计算平移向量t(点云中心到原点)
t = -point_cloud.mean(axis=0)
return R, t
【此处插入PCA位姿估计效果图】
5.3 ICP 精配准原理
获得粗配准结果后,使用ICP(Iterative Closest Point)算法进行精细优化:
# ICP精配准算法
def icp_registration(source_cloud, target_cloud, initial_pose):
"""
ICP算法核心步骤:
1. 根据当前位姿变换源点云
2. 寻找最近点对应关系
3. 最小化点对距离(SVD求解最优R,t)
4. 迭代直到收敛
"""
# ICP目标函数:最小化配准误差
# E = Σ||Qi - (Pi·R + T)||²
for iteration in range(max_iterations):
# 步骤1:变换源点云
transformed = apply_transform(source_cloud, current_pose)
# 步骤2:寻找最近点对应关系
correspondences = find_nearest_neighbors(transformed, target_cloud)
# 步骤3:SVD求解最优变换
R, t = svd_alignment(source_cloud, correspondences)
# 步骤4:更新位姿
current_pose = compose_transform(R, t, current_pose)
# 步骤5:检查收敛条件
if check_convergence(current_pose, prev_pose):
break
return current_pose
ICP关键参数配置:
voxel_size: 5 # 栅格化尺寸 (mm)
max_correspondence_distance: 0.03 # 最大对应点距离 (m)
max_iter: 30 # 最大迭代次数
relative_fitness: 1e-6 # 收敛阈值
relative_rmse: 1e-6 # RMSE收敛阈值
【此处插入ICP精配准效果图】
5.4 配准结果对比
| 配准阶段 | 算法 | 精度 | 速度 | 适用场景 |
|---|---|---|---|---|
| 粗配准 | PCA | ★★★ | ⚡⚡⚡ | 初始位姿估计 |
| 精配准 | ICP | ★★★★★ | ⚡⚡ | 精细优化 |
六、机械臂抓取:手眼协同控制
6.1 手眼标定原理
手眼标定用于确定相机坐标系与机械臂坐标系之间的转换关系:
T_robot = T_camera→robot · T_object→camera
Eye-to-Hand(眼在手外)配置:
相机 (Gemini 2) 固定安装于工作空间正上方,俯视整个抓取区域 ↓ 手眼标定矩阵 机械臂 (末端夹爪) 节卡 zu12,执行抓取动作
6.2 手眼标定步骤
# 手眼标定核心流程
def eye_hand_calibration():
"""
使用标准球法进行手眼标定:
1. 将标准球固定于机械臂末端
2. 机械臂带动标准球在相机视野内移动
3. 采集多组(平移+旋转)点位数据
4. 使用UMEYAMA算法求解转换矩阵
"""
# 采集纯旋转点位
rotation_points = []
for i in range(N_ROTATION):
robot_arm.move_to(rotation_poses[i])
ball_center = detect_ball_center() # 点云中定位球心
rotation_points.append(ball_center)
# 采集纯平移点位
translation_points = []
for i in range(N_TRANSLATION):
robot_arm.move_to(translation_poses[i])
ball_center = detect_ball_center()
translation_points.append(ball_center)
# 使用UMEYAMA算法求解转换矩阵
T_camera_robot = umeyama_algorithm(rotation_points, translation_points)
return T_camera_robot
6.3 节卡机械臂控制
# Instruct.py - 节卡机械臂SDK封装
import jkrc
import numpy as np
import open3d as o3d
class JakaRobotController:
def __init__(self, ip="192.168.137.164"):
self.robot_arm = jkrc.RC(ip)
self.speed = 500.0 # 运动速度 mm/s
def login(self):
"""登录并使能机械臂"""
self.robot_arm.login()
self.robot_arm.power_on()
self.robot_arm.enable_robot()
def moving(self, pose_matrix):
"""线性运动到目标位置"""
xyzabc = self.get_xyzabc_from_matrix(pose_matrix)
self.robot_arm.linear_move(xyzabc, 0, True, self.speed)
def grasp(self, status=1):
"""夹爪控制"""
self.robot_arm.set_digital_output(0, 0, status)
七、完整抓取流程代码
# main.py - 完整抓取流程
from pyorbbecsdk import *
from ultralytics import YOLO
import open3d as o3d
def main():
# 初始化
ROBOT.log_in() # 机械臂登录
model = YOLO('boxs.pt') # 加载检测模型
pipeline = Pipeline()
pipeline.start(Config())
while True:
# 1. 获取相机数据
frames = pipeline.wait_for_frames()
color_frame = frames.get_color_frame()
color_image = frame_to_bgr_image(color_frame)
# 2. YOLOv8目标检测
results = model.predict(source=color_image)
# 3. 获取点云数据
camera_param = pipeline.get_camera_param()
points = frames.convert_to_color_points(camera_param)
points_array = np.array([[p.x, p.y, p.z] for p in points])
# 4. 位姿估计(PCA+ICP)
POSE.z_plane_registration_run2(inputDatas)
pose_result = POSE.get_output("result.Matrices")
# 5. 机械臂运动规划
ROBOT.moving(pose_result)
# 6. 执行抓取
ROBOT.grasp()
八、技术指标与创新点
8.1 核心性能指标
| 指标 | 数值 | 说明 |
|---|---|---|
| 🎯 检测精度 | >95% | YOLOv8实例分割准确率 |
| 📐 位姿精度 | <5mm | ICP精配准后误差 |
| ⚡ 处理速度 | 30fps | Jetson Orin Nano实时处理 |
| 🤝 抓取成功率 | >90% | 实测无序堆叠场景 |
8.2 关键技术创新
| 创新点 | 技术方案 | 达到效果 |
|---|---|---|
| 🎮 虚拟数据 | Isaac Sim物理仿真 | 1000+张高质量训练数据 |
| ⚡ 实时检测 | YOLOv8轻量化模型 | 边缘设备实时推理 |
| 📐 粗精配准 | PCA + ICP联合 | 兼顾速度与精度 |
| 🔧 手眼协同 | UMEYAMA标定 | 坐标系精确转换 |
8.3 未来优化方向
| 模块 | 当前问题 | 优化方案 |
|---|---|---|
| 数据集 | 只能标注正对相机情形 | 多角度自动标注 |
| 点云 | SDK每帧点云不一致 | 滤波算法优化 |
| 精度 | 遮挡时精度下降 | 迁移学习增强泛化 |
九、技术栈总结
| 类别 | 技术选型 |
|---|---|
| 🎮 仿真平台 | NVIDIA Isaac Sim / Omniverse |
| 🎥 深度视觉 | 奥比中光 Gemini 2 SDK |
| 🧠 边缘计算 | NVIDIA Jetson Orin Nano |
| 🔍 目标检测 | YOLOv8 (Ultralytics) |
| 📐 点云处理 | Open3D |
| 🤖 机械臂 | 节卡机器人 zu12 SDK |
| 🐍 开发语言 | Python 3.11 |