2. 坐标系与变换
做机器视觉,说白了就是让计算机看懂三维世界。但计算机只能处理二维图像。这中间差了什么呢?就是坐标系变换。
我个人习惯把这件事想成“翻译”。世界坐标系是客观存在的三维空间,相机坐标系是相机眼中的三维空间,图像坐标系是成像平面上的二维投影,像素坐标系是最终的数字图像。每一步都是一次翻译。
嗯,咱们一个一个来看。
2.1 四个坐标系,一个都不能少
先搞清楚这四个坐标系分别长什么样:
| 坐标系 | 维度 | 单位 | 原点位置 | 典型用途 |
|---|---|---|---|---|
| 世界坐标系 | 3D (Xw, Yw, Zw) | mm / m | 用户自定义 | 描述物体在真实空间中的位置 |
| 相机坐标系 | 3D (Xc, Yc, Zc) | mm / m | 相机光心 | 描述物体相对于相机的位置 |
| 图像坐标系 | 2D (x, y) | mm | 图像中心(主点) | 描述投影点在成像平面上的物理位置 |
| 像素坐标系 | 2D (u, v) | pixel | 图像左上角 | 描述像素在数字图像中的行列位置 |
你想想看,一个三维点要变成像素坐标,得走四步。每一步都有对应的数学公式。我刚开始学的时候,总觉得这些公式很枯燥。直到有一次项目里标定板放歪了,结果测量尺寸差了2毫米……从那以后,我再也不敢轻视这些变换了。
2.2 世界坐标系 → 相机坐标系(刚体变换)
这一步是三维到三维的变换。说白了,就是把世界坐标系下的点,通过旋转和平移,挪到相机坐标系下。
公式很简单:
| Xc | | R11 R12 R13 | | Xw | | Tx |
| Yc | = | R21 R22 R23 | * | Yw | + | Ty |
| Zc | | R31 R32 R33 | | Zw | | Tz |
写成齐次坐标形式更简洁:
| Xc | | R T | | Xw |
| Yc | = | 0 1 | * | Yw |
| Zc | | | | Zw |
| 1 | | | | 1 |
这里的 R 是 3×3 旋转矩阵,T 是 3×1 平移向量。合起来叫外参矩阵。
2.3 相机坐标系 → 图像坐标系(透视投影)
这一步是三维到二维的投影。用的是小孔成像模型。
公式也很直观:
x = f * Xc / Zc
y = f * Yc / Zc
其中 f 是焦距,单位是 mm。
这里有个关键点:Zc 在分母上。这意味着距离越远,成像越小。这就是透视效应。
2.4 图像坐标系 → 像素坐标系(离散化)
这一步是把连续的物理坐标,变成离散的像素坐标。
公式:
u = x / dx + u0
v = y / dy + v0
其中 dx、dy 是每个像素的物理尺寸(mm/pixel),(u0, v0) 是主点坐标(图像中心)。
写成矩阵形式:
| u | | 1/dx 0 u0 | | x |
| v | = | 0 1/dy v0 | * | y |
| 1 | | 0 0 1 | | 1 |
这部分叫内参矩阵的一部分。内参还包括焦距 f 和畸变参数。
2.5 完整变换链:从世界到像素
把上面三步串起来,就是完整的投影方程:
| u | | fx 0 u0 0 | | R T | | Xw |
| v | = | 0 fy v0 0 | * | 0 1 | * | Yw |
| 1 | | 0 0 1 0 | | | | Zw |
| | | | | 1 |
其中 fx = f/dx,fy = f/dy,是像素焦距。
这个公式,就是整个相机标定的数学基础。你想想看,一个三维点,经过旋转、平移、投影、离散化,最终变成一个像素坐标。反过来,如果我们知道像素坐标和深度信息,就能反推出三维坐标。这就是三维重建的原理。
2.6 知识体系图
下面这张图,把四个坐标系和它们之间的变换关系画清楚了:
2.7 避坑指南
做坐标系变换时,有几个坑我踩过,分享给你:
- 坐标系方向搞反:我曾经在写代码时,把旋转矩阵的转置和逆搞混了。结果重建出来的点云,全部镜像了。后来我养成了一个习惯:每次写完变换代码,先用一个已知点验证一下。
- 单位不统一:世界坐标系用毫米,焦距用米,像素尺寸用微米……这种混乱我见过太多次了。建议统一用毫米。
- 主点位置想当然:不是所有相机的图像原点都在左上角。有些工业相机可以配置原点位置。一定要确认。
- 忽略畸变:实际镜头都有畸变,尤其是广角镜头。不做畸变校正,后面的测量全是错的。
2.8 小结
这一章我们讲了四个坐标系和它们之间的变换关系。从世界坐标系到像素坐标系,经历了刚体变换、透视投影、离散化三步。每一步都有对应的数学公式和物理意义。