2D转3D方案

好问题!其实这个项目里 YOLO 仍然只做了 **2D 检测**,所谓"3D"是通过 **YOLO 给的 2D 像素坐标 + 深度图 + 相机内参** 反投影出来的。下面把关键代码拎出来讲清楚。

核心思路:单目深度相机的"伪 3D 检测"

不是 YOLO 输出 3D,而是 YOLO 给 `(u, v)` 像素坐标,深度图给该像素的 `Z`,内参 `K` 用来反解 `X, Y`。三者合起来才是 3D 坐标。

数学公式(针孔相机反投影):

```

X\] \[u

Y = K⁻¹ · v · Z

Z\] \[1

```

三段关键代码

1) 拿到相机内参并求逆

obj_detect.py:48-49

```python

def caminfo_callback(self, msg):

K = np.array(msg.k).reshape(3, 3)

self.depth_instrinsic_inv = np.linalg.inv(K)

```

`CameraInfo.k` 是 3×3 内参矩阵(fx, fy, cx, cy 等),这里直接缓存 `K⁻¹`,后面反投影要用。

2) YOLO 给出 2D 框,取中心像素 (cx, cy)

obj_detect.py:79-86

```python

results = self.model.predict(img0, verbose=False)

res = results0

boxes = res.boxes.xyxy.cpu().numpy() # YOLO 只输出 2D 框 (x1,y1,x2,y2)

...

for (x1, y1, x2, y2), conf, cls_id in zip(boxes, confs, clses):

cx, cy = int((x1 + x2) / 2), int((y1 + y2) / 2) # 框中心像素

```

注意 YOLO 这里输出的就是 2D `xyxy`,**没有任何深度信息**。

3) 用深度图查 Z,用 K⁻¹ 反投影成 3D

obj_detect.py:99-104

```python

深度估计

Z = depcy, cx * 1e-3 # 深度图里查出来的距离,单位 mm → m

if Z <= 0 or np.isnan(Z):

continue

uv1 = np.array(cx, cy, 1.0)

XYZ = self.depth_instrinsic_inv @ uv1 * Z # 反投影成 3D

```

这就是整个"3D 检测"的核心:

  • `dep` 是 obj_detect.py:36订阅的 `/depth_registered/image_rect` 深度图(与彩色图配准过,所以像素一一对应)。

  • `depcy, cx` 是 YOLO 框中心像素对应的深度值(毫米),`* 1e-3` 转米。

  • `K⁻¹ @ u,v,1` 得到的是相机光轴方向上的单位射线(Z=1 时的 X、Y),乘以 `Z` 就还原成真实 3D 坐标。

  • `XYZ0/1/2` 分别就是相机光学坐标系下的 `X, Y, Z`。

随后塞进 `ObjectHypothesisWithPose.pose.pose.position`,发布到 `/detection` 话题,下游 det_tf.py直接拿这个 position 发 TF。

为什么这样做有意义

| 方式 | 是否真 3D 检测 | 说明 |

|------|----------------|------|

| 单纯 YOLO | ❌ | 只有 2D 像素框 |

| YOLO + 深度图 + 内参反投影 | ⚠️ **半 3D** | 有 3D 位置,但没有 3D 朝向/姿态 |

| 真正的 3D 检测网络(PointNet、VoxelNeXt、SMOKE) | ✅ | 直接从点云或图像回归 6DoF 位姿 |

| YOLO + 深度 + ICP/PnP 配准 | ✅ | 有完整 6DoF 位姿 |

这个项目走的是第二种「半 3D」路线------**只要 3D 位置(XYZ)就够抓取了**,因为:

  1. 抓取的物体是方块,对称性高,姿态不重要。

  2. det_tf.py:46里 `t.transform.rotation.w = 1.0`------发布的 TF 姿态是单位四元数,机器人末端姿态由 MoveIt 自己定,不需要物体姿态。

  3. 简单可靠,不需要训练 3D 检测网络,复用成熟的 YOLO 模型即可。

关键依赖:深度图必须与彩色图对齐

obj_detect.py:25默认订阅的是 **`/depth_registered/image_rect`**(注意 "registered" 这个词):

```python

self.declare_parameter("depth_topic", "/depth_registered/image_rect")

```

也就是说,**深度图必须先被配准到彩色相机的视角**,让深度图与彩色图像素一一对应。这正是项目里 register_depth.launch.pyy#L64-L74) 中的 `depth_image_proc::RegisterNode` 做的事:

```python

launch_ros.descriptions.ComposableNode(

package='depth_image_proc',

plugin='depth_image_proc::RegisterNode',

name='register_node',

remappings=[('depth/image_rect', '/depth/image_raw'),

('depth/camera_info', '/depth/camera_info'),

('rgb/camera_info', '/color/camera_info'),

('depth_registered/image_rect', '/depth_registered/image_rect'), # ← obj_detect 订阅这个

('depth_registered/camera_info', '/depth_registered/camera_info')]

),

```

如果深度图没配准:

  • YOLO 在彩色图上找到框中心 `(cx, cy)`。

  • 用这个 `(cx, cy)` 去深度图里查深度 → 查到的可能是另一个物体的深度,**3D 坐标完全错位**。

  • 所以"registered"这步是这个 2D→3D 反投影方案能成立的前提。

整条链路总结

```

彩色图 ──► YOLO ──► 2D 框 (cx, cy) ┐

深度图 ──► RegisterNode ──► 配准深度图 │ depcy, cx → Z

├──┐

CameraInfo (K) ──► K⁻¹ │ │

┘ │

▼

XYZ = K⁻¹ · u,v,1 · Z

│

▼

/detection (ObjectHypothesisWithPose)

│

▼

det_tf.py 发布 TF: cube1/cube2/...

│

▼

MoveIt 抓取

```

所以严格讲,这个项目并没有做"3D 目标检测",而是做了 **"2D 检测 + 深度反投影"的工程化组合**------这是机器人抓取场景里最常用、性价比最高的方案,因为:

  • 不需要标注 6DoF 位姿数据集(成本高);

  • 不需要训练 3D 检测网络(算力高);

  • 只要有深度相机,任何 2D 检测器都能升级成"3D 定位器"。

唯一的前提是:**深度图必须和彩色图配准**,且**深度图在该像素处必须有有效值**(这就是 obj_detect.py:101那行 `if Z <= 0 or np.isnan(Z): continue` 的意义------防止深度图空洞导致 NaN 坐标传给机器人)。

相关推荐
暴走约伯5 小时前
【VFX工具链源码拆解 02】告别机械劳动(上):一键统改百个子粒子颜色与批量重命名
3d·unity·c#·材质
Solange__11 小时前
AI世界模型、3D场景生成和游戏引擎怎么选?按5类任务比较交互、物理与导出
开发语言·人工智能·游戏·平面·3d·自然语言处理·游戏引擎
Solange__11 小时前
物流园区怎么用AI生成3D调度预演?从道路底图、车辆转弯到网页评审
图像处理·人工智能·游戏·3d·ai·自然语言处理·关卡设计
言乐61 天前
通过 3D 动画直观演示球形瓶内可滑动半圆机构在倾倒时防粘盖、回正时刮膏体的运动学过程
python·3d·django·virtualenv·pygame
苏州福兰克1 天前
没有3D内容,裸眼3D显示器还能用吗?
3d·计算机外设
慧都CAD开发笔记1 天前
汽车零部件检测软件如何用统一接口直读多种 CAD:3D InterOp 的三类数据接入
3d·汽车
苏州福兰克1 天前
长期看裸眼3D显示器容易视觉疲劳吗?
3d·计算机外设
苏州福兰克1 天前
商用裸眼3D显示器和家用款主要差别在哪里?
3d·计算机外设
天树星智源1 天前
静态物理满分、交互 11.54%:3D 场景生成系统的幻觉
论文阅读·人工智能·3d·机器人
Wanda12141 天前
机器人与机电一体化3D数字孪生机器-Day9
人工智能·3d·unity·机器人·数字孪生