坐标系基础:世界坐标系、相机坐标系、图像坐标系、像素坐标系及其转换关系

做光学标注这些年,我见过太多人一上来就调算法、标参数,结果标出来的数据全是错的。为什么?坐标系没搞明白。说白了,你连点在哪儿都说不清楚,怎么指望机器能找准?

这一章,咱们就把四个坐标系彻底捋清楚。世界坐标系、相机坐标系、图像坐标系、像素坐标系——它们之间怎么转,每一步的坑在哪儿,我都会用自己的实战经验给你讲透。

1. 四个坐标系,各管一摊

先记住一句话:世界坐标系是“真实世界”,相机坐标系是“相机眼里”,图像坐标系是“底片上”,像素坐标系是“电脑里”。咱们一个一个看。

坐标系 英文 维度 单位 一句话理解
世界坐标系 World Coordinate System 3D (Xw, Yw, Zw) mm / m 物体在真实空间里的位置
相机坐标系 Camera Coordinate System 3D (Xc, Yc, Zc) mm / m 以相机光心为原点看到的场景
图像坐标系 Image Coordinate System 2D (x, y) mm 物理成像平面上的位置
像素坐标系 Pixel Coordinate System 2D (u, v) pixel 图像数组里的行列号

嗯,这里要注意:世界坐标系和相机坐标系都是三维的,但图像和像素坐标系是二维的。从三维到二维,就是“投影”的过程,也是误差最容易放大的地方。

2. 坐标系之间的转换关系

我习惯把整个转换链条画成一张图,这样脑子里的逻辑就清楚了。下面这张 SVG 就是我自己一直在用的“坐标系转换路线图”。

坐标系转换关系图 坐标系转换路线图 世界坐标系 (Xw, Yw, Zw) 相机坐标系 (Xc, Yc, Zc) 图像坐标系 (x, y) 像素坐标系 (u, v) 刚体变换 R, t 透视投影 f 离散化 dx, dy, u0, v0 关键说明: 1. 世界→相机:外参矩阵(旋转R + 平移t),描述相机在世界中的位姿。 2. 相机→图像:内参矩阵中的焦距f,将3D点投影到2D成像平面。 3. 图像→像素:内参中的像元尺寸dx/dy和主点偏移(u0,v0),完成离散化。

3. 每一步转换,都有坑

3.1 世界坐标系 → 相机坐标系(刚体变换)

这一步说白了就是“把世界搬到相机跟前”。用旋转矩阵 R 和平移向量 t 就能搞定。公式长这样:

| Xc |   | R11 R12 R13 | | Xw |   | tx |
| Yc | = | R21 R22 R23 | | Yw | + | ty |
| Zc |   | R31 R32 R33 | | Zw |   | tz |

我曾经在一个项目里,标定板放歪了 2 度,结果重建出来的工件尺寸差了 0.5mm。你想想看,2 度而已,但到了 500mm 远的物体上,误差就放大了。所以,外参标定一定要用高精度靶标,别图省事。

避坑指南: 旋转矩阵必须是正交矩阵。如果你自己算出来的 R 不满足 R^T * R = I,那一定是算错了。我曾经用数值优化硬算,结果矩阵不正交,后面全崩了。

3.2 相机坐标系 → 图像坐标系(透视投影)

这一步是“把三维压成二维”。用的是小孔成像模型:

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

注意,这里 Zc 在分母上。Zc 越小,物体在图像上看起来越大。我见过有人把 Zc 和 Zw 搞混,结果投影出来的点全飞了。记住:Zc 是相机坐标系下的深度,不是世界坐标系的。

实战技巧: 如果你的镜头畸变比较大(比如广角镜头),这一步之后一定要加畸变校正。我一般用 Brown 模型,先校正再往下走。

3.3 图像坐标系 → 像素坐标系(离散化)

这一步是把物理尺寸(毫米)变成像素坐标(行列号)。公式很简单:

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

其中 dx、dy 是每个像素的物理尺寸,u0、v0 是图像中心(主点)的像素坐标。嗯,这里有个坑:dx 和 dy 不一定相等。如果传感器像素不是正方形,你直接取相等就会导致图像变形。

我记得有一次帮客户标定一个工业相机,厂家给的 datasheet 上 dx=dy,但实际标出来发现差了 0.3%。后来一查,是传感器封装时微米级的偏差。从那以后,我再也不敢完全相信 datasheet,每次都自己标定。

4. 完整转换公式(齐次坐标形式)

把上面三步串起来,用齐次坐标写,就是相机标定里最核心的公式:

| 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 矩阵,左边 3x3 是内参(fx, fy, u0, v0),右边 3x4 是外参(R, t)。标定的本质,就是解出这 11 个未知数(内参 4 个 + 外参 6 个 + 畸变参数若干)。

核心要点: 这个公式是光学标注的“宪法”。所有后续操作——手眼标定、三维重建、投影验证——都建立在这个公式之上。不理解它,后面的课你会越听越懵。

5. 实战中的坐标系检查清单

我每次做项目,都会按这个清单过一遍,避免低级错误:

  1. 世界坐标系原点在哪儿? 是标定板角点?还是工件基准面?必须明确。
  2. 相机坐标系 Z 轴指向哪儿? 是朝向场景还是朝向相机后方?不同软件约定不同。
  3. 图像坐标系 x 轴朝右还是朝左? 有些库用左上角为原点,有些用中心。
  4. 像素坐标系 (u, v) 对应 (列, 行) 还是 (行, 列)? OpenCV 和 Halcon 的约定不一样。
  5. dx, dy 的单位是 mm 还是 μm? 差 1000 倍,算出来全错。

你想想看,如果上面任何一条搞混了,后面的标注结果就是废的。我见过一个团队花了三周做三维重建,最后发现是坐标系方向反了——全部重来。

6. 一个小练习

假设世界坐标系下有一个点 P = (100mm, 50mm, 200mm)。相机外参为:无旋转(单位矩阵),平移 t = (0, 0, 0)。内参:fx = fy = 1000 pixel,u0 = 640,v0 = 512,dx = dy = 0.005mm/pixel。请计算该点在像素坐标系下的坐标 (u, v)。

答案我就不给了,你自己算一遍。算完你会发现,纸上得来终觉浅——动手算一次,比看十遍公式都管用。

好了,坐标系这块就讲到这里。记住那张转换路线图,后面的章节我们会反复用到它。