坐标系基础:从世界到像素,再到机器人

做手眼标定,说白了就是搞清楚「眼睛」和「手」之间的位置关系。但在这之前,有个更基础的问题必须解决——坐标系。

我刚开始接触这个领域时,觉得坐标系不就是几个箭头嘛,有什么好讲的?直到第一次做标定,数据怎么都对不上,折腾了两天才发现是图像坐标系和像素坐标系搞混了。嗯,从那以后我再也不敢小看这些基础概念了。

这一章,我们就把六个核心坐标系掰开揉碎讲清楚。你想想看,如果连坐标系的变换都搞不明白,后面的手眼标定矩阵推导、目标检测坐标映射,根本无从下手。

六个核心坐标系,一个都不能少

在实际的机器人视觉系统中,我们通常要面对六个坐标系。它们各自有各自的「地盘」,但最终要能互相通信。

坐标系 英文缩写 核心作用 维度
世界坐标系 World 描述场景中所有物体的位置 3D (Xw, Yw, Zw)
相机坐标系 Camera 以相机光心为原点,描述物体相对相机的3D位置 3D (Xc, Yc, Zc)
图像坐标系 Image 物理成像平面上的位置,单位是毫米 2D (x, y)
像素坐标系 Pixel 图像在计算机内存中的存储位置,单位是像素 2D (u, v)
机器人基坐标系 Base 固定在机器人底座,描述机器人本体的位置 3D (Xb, Yb, Zb)
工具坐标系 Tool 固定在机器人末端执行器上,描述工具的位置和姿态 3D (Xt, Yt, Zt)

核心要点:世界坐标系是「全局地图」,相机坐标系是「眼睛看到的」,像素坐标系是「电脑存下来的」,机器人基坐标系是「机器人的根」,工具坐标系是「机器人的手」。手眼标定,就是把这些坐标系串起来。

从3D世界到2D像素:相机成像的四个步骤

相机是怎么把三维世界变成二维照片的?这个过程涉及四个坐标系的连续变换。我个人习惯把这四个步骤记成一条流水线:

  1. 世界 → 相机:刚体变换(旋转+平移)
  2. 相机 → 图像:透视投影(小孔成像)
  3. 图像 → 像素:离散化采样(毫米变像素)

咱们一步步看。

1. 世界坐标系 → 相机坐标系

这一步是刚体变换。说白了,就是把物体在世界中的位置,挪到以相机为原点的坐标系里。

// 齐次坐标形式
| Xc |   | R11 R12 R13 Tx | | Xw |
| Yc | = | R21 R22 R23 Ty | | Yw |
| Zc |   | R31 R32 R33 Tz | | Zw |
| 1  |   | 0   0   0   1  | | 1  |

这里的 R 是 3x3 旋转矩阵,T 是 3x1 平移向量。合起来就是相机的外参矩阵。

我的经验:外参矩阵的物理意义很直观——它告诉你相机在世界中的位置和朝向。我在做移动机器人标定时,经常需要先固定好世界坐标系的原点,比如选在机器人底座正下方,这样后面的计算会省很多事。

2. 相机坐标系 → 图像坐标系

这一步是透视投影,也就是小孔成像模型。

x = f * Xc / Zc
y = f * Yc / Zc

其中 f 是焦距。注意,这里 Zc 不能为0,否则投影无意义。这也是为什么相机不能贴在物体上拍照。

3. 图像坐标系 → 像素坐标系

这一步最容易出错。图像坐标系的单位是毫米,像素坐标系的单位是像素。它们之间差一个缩放和偏移。

u = x / dx + u0
v = y / dy + v0

dx 和 dy 是每个像素在 x 和 y 方向上的物理尺寸,u0、v0 是主点(光轴与成像平面的交点)的像素坐标。

我曾经踩过的坑:有一次标定结果总是偏一个固定偏移,查了半天才发现是 u0、v0 的值给错了。很多相机标定库默认主点在图像中心,但实际传感器可能不是。所以拿到相机参数后,一定要先验证一下主点坐标是否准确。

机器人侧的坐标系:基座标系与工具坐标系

讲完相机侧的四个坐标系,咱们再看看机器人侧的两个坐标系。

机器人基坐标系

这个坐标系固定在机器人底座上,通常是机器人控制器的「世界原点」。所有机器人运动指令,最终都要换算到这个坐标系下执行。

基坐标系的原点一般选在底座安装面的中心,Z 轴向上。不同品牌的机器人可能有细微差别,但大差不差。

工具坐标系

工具坐标系固定在机器人末端法兰盘上。它的原点通常是工具的中心点(TCP, Tool Center Point)。

为什么要单独定义工具坐标系?因为机器人末端可以装不同的工具——夹爪、焊枪、相机。每个工具的 TCP 位置和姿态都不一样。你想想看,如果每次换工具都要重新编程,那效率得多低?

关键概念:手眼标定中,我们通常把相机固定在机器人末端(眼在手上),或者固定在场景中(眼在手外)。无论哪种方式,最终要建立的都是相机坐标系和机器人基坐标系(或工具坐标系)之间的变换关系。

坐标系变换关系总览

为了让你更直观地理解这些坐标系之间的关系,我画了一张图。

坐标系变换关系总览 世界坐标系 相机坐标系 图像坐标系 像素坐标系 机器人基坐标系 工具坐标系 外参矩阵 透视投影 离散化 运动学 手眼标定 💡 说明: 手眼标定的核心,就是求解世界坐标系与机器人基坐标系之间的变换关系(或相机与工具坐标系之间的变换)。

变换矩阵的数学本质

所有坐标系之间的变换,在数学上都可以用一个 4x4 的齐次变换矩阵来表示。这个矩阵长这样:

| R11 R12 R13 Tx |
| R21 R22 R23 Ty |
| R31 R32 R33 Tz |
| 0   0   0   1  |

左上角 3x3 是旋转部分,右上角 3x1 是平移部分。为什么用齐次坐标?因为这样可以把旋转和平移统一成一次矩阵乘法,方便连续变换。

举个例子,从世界坐标系到像素坐标系的完整变换:

| u |   | fx  0  u0  0 | | R11 R12 R13 Tx | | Xw |
| v | = | 0  fy v0  0 | | R21 R22 R23 Ty | | Yw |
| 1 |   | 0   0   1  0 | | R31 R32 R33 Tz | | Zw |
                            | 0   0   0   1  | | 1  |

前面那个 3x4 矩阵是相机内参矩阵,后面那个 4x4 是外参矩阵。两者相乘,就是完整的投影矩阵 P。

我的建议:刚开始学的时候,不要死记硬背矩阵公式。先理解物理意义——旋转是「转方向」,平移是「挪位置」,内参是「相机自己的参数」,外参是「相机在哪」。理解了这些,公式自然就记住了。

避坑指南:坐标系变换中的常见错误

  • 坐标系方向搞反:比如把世界到相机的变换,当成了相机到世界的变换。记住,变换矩阵是有方向的,不能随便颠倒。
  • 单位不统一:世界坐标系用米,相机内参用毫米,结果算出来的坐标差三个数量级。我建议所有数据统一用毫米。
  • 忽略齐次坐标:有些同学直接用 3x3 旋转矩阵加 3x1 平移向量分开算,结果在连续变换时容易出错。用齐次坐标,一次搞定。
  • 工具坐标系没校准:TCP 位置不准,手眼标定结果一定不准。做标定前,先确认工具坐标系是准确的。

我曾经犯过的错:有一次做眼在手上的标定,标定结果看起来很好,重投影误差也很小。但实际抓取时,机器人总是差那么几毫米。查了两天,最后发现是工具坐标系的方向定义和机器人控制器里的定义不一致。从那以后,我每次做标定前都会先打印一份坐标系定义对照表,逐项确认。