坐标系与变换基础:世界坐标系、相机坐标系、图像坐标系、像素坐标系、刚体变换与齐次坐标
做视觉伺服这些年,我见过太多新手在坐标系上栽跟头。说白了,视觉伺服就是一套「坐标转换」的游戏。你从相机里看到的是一个像素点,但机器人要抓的是一个三维空间里的物体。这两者之间,隔着一整套坐标系变换链。
今天我们就来把这根链条彻底捋清楚。
1. 四个坐标系,一个都不能少
视觉伺服里,我们打交道的一共有四个坐标系。我习惯把它们想象成「俄罗斯套娃」——一层套一层,但每一层都有自己的使命。
核心链条: 世界坐标系 → 相机坐标系 → 图像坐标系 → 像素坐标系
1.1 世界坐标系 (World Coordinate System)
这是你定义整个场景的「绝对参考系」。机器人底座、工作台、目标物体——它们的位置都用世界坐标来描述。单位通常是米或毫米。
我记得有一次在现场调试,客户把世界坐标系的原点设在了车间角落,结果机器人每次回零都要绕一大圈。后来我建议他把原点改到机器人底座中心,问题立刻解决。嗯,原点位置的选择,直接影响后续所有计算的简洁性。
1.2 相机坐标系 (Camera Coordinate System)
相机坐标系的原点在相机的光心,Z轴沿着光轴指向场景前方。X轴向右,Y轴向下(符合图像处理惯例)。
这里有个坑:相机坐标系和世界坐标系之间,存在一个刚体变换(旋转+平移)。这个变换矩阵,就是我们常说的「外参」。
1.3 图像坐标系 (Image Coordinate System)
图像坐标系是二维的,原点在图像平面的中心(主点),单位是毫米。它描述的是物体在成像平面上的物理位置。
为什么要有这个坐标系?因为相机坐标系里的三维点,通过透视投影会落到这个平面上。说白了,就是把三维世界「拍扁」成二维。
1.4 像素坐标系 (Pixel Coordinate System)
这是最终你看到的那个坐标系。原点在图像左上角,单位是像素。u轴向右,v轴向下。
从图像坐标系到像素坐标系,就是一个缩放+平移的过程——把毫米变成像素。这个变换矩阵,就是「内参」的一部分。
我的经验: 调试时最容易出错的地方,就是混淆图像坐标系和像素坐标系。记住:图像坐标系的原点在中心,像素坐标系的原点在左上角。差一个平移量,结果就全错了。
2. 刚体变换与齐次坐标
坐标系之间的转换,本质上就是刚体变换。刚体变换包含两部分:旋转和平移。它不改变物体的形状和大小——所以叫「刚体」。
2.1 旋转矩阵
三维空间中的旋转,可以用一个3x3的正交矩阵表示。绕X、Y、Z轴的旋转矩阵长这样:
// 绕Z轴旋转θ角度
R_z(θ) = [
cosθ -sinθ 0
sinθ cosθ 0
0 0 1
]
// 绕X轴旋转α角度
R_x(α) = [
1 0 0
0 cosα -sinα
0 sinα cosα
]
// 绕Y轴旋转β角度
R_y(β) = [
cosβ 0 sinβ
0 1 0
-sinβ 0 cosβ
]
你想想看,如果旋转顺序搞错了,结果会差多少?我见过一个项目,工程师用了XYZ顺序,但实际系统是ZYX顺序,结果机械臂抓取时偏了十几度。嗯,旋转顺序一定要和标定时的约定一致。
2.2 齐次坐标
为什么要引入齐次坐标?因为用普通坐标表示变换时,旋转和平移是分开的:
P' = R * P + t
这种形式在连续变换时非常麻烦。齐次坐标把三维点变成四维向量 (x, y, z, 1),把旋转和平并到一个4x4矩阵里:
| P' | = | R t | * | P |
| 1 | | 0 1 | | 1 |
这样一来,多次变换就可以通过矩阵乘法串联起来。我在写视觉伺服控制代码时,所有变换都用齐次矩阵表示——代码简洁,逻辑清晰,不容易出错。
避坑指南: 我曾经在项目中直接用3x3旋转矩阵加平移向量做变换,结果连续变换了三次后,精度损失严重。改用齐次坐标后,误差完全可控。记住:工程上,能用4x4就别用3x3+向量。
3. 坐标系变换的完整流程
从世界坐标到像素坐标,完整的变换流程如下:
- 世界 → 相机: 刚体变换(外参矩阵)
- 相机 → 图像: 透视投影(针孔模型)
- 图像 → 像素: 缩放+平移(内参矩阵)
用齐次坐标表示,整个流程就是一个矩阵连乘:
| u | | fx 0 cx 0 | | R t | | X |
| v | = | 0 fy cy 0 | * | 0 1 | * | Y |
| 1 | | 0 0 1 0 | | | | Z |
| 1 |
其中 fx, fy 是焦距(像素单位),cx, cy 是主点坐标。这个3x4矩阵,就是相机的「投影矩阵」P。
调试技巧: 当你怀疑标定结果有问题时,可以做一个简单验证:把一个已知世界坐标的点投影到图像上,看看和实际像素位置是否吻合。误差超过2个像素,就该重新标定了。
4. 知识体系总览
下面这张图,是我自己总结的坐标系变换知识体系。每次带新人时,我都会先让他们看这张图——把整体框架搭起来,细节才不会乱。
5. 实战中的坐标系管理
在实际项目中,我一般会这样做:
- 统一单位: 所有坐标系都用毫米,避免米和毫米混用。我见过一个项目,世界坐标用米,相机坐标用毫米,结果投影矩阵算出来全是错的。
- 明确约定: 旋转顺序、坐标轴方向,这些必须在项目一开始就定死。写在文档里,贴在墙上。
- 可视化验证: 把坐标系画出来,用OpenCV或Matplotlib实时显示。看到的东西,比算出来的数字更可靠。
我曾经踩过的坑: 有一次标定完相机,发现投影误差总是偏大。查了两天,最后发现是标定板上的角点顺序和代码里的不一致。一个角点顺序,浪费了我两天时间。从那以后,我每次标定都会先手动验证几个点。
好了,坐标系变换这块内容,说白了就是「从三维到二维」的数学映射。把四个坐标系的关系理清楚,把齐次坐标用熟练,视觉伺服系统的稳定性就有了第一块基石。