2. 坐标系基础

做手眼标定,说白了就是搞清楚「眼睛」和「手」之间的位置关系。但在这之前,你得先把坐标系这关过了。我见过不少新手,标定程序跑通了,结果一换场景就崩,回头一看——坐标系搞混了。

今天咱们就把这六个坐标系掰开揉碎,一个一个讲清楚。

1. 四大视觉坐标系

视觉系统里,最核心的就是这四个坐标系。它们串起来,就是一条完整的成像链路。

坐标系 维度 单位 作用
世界坐标系 3D (Xw, Yw, Zw) mm 描述物体在真实空间中的位置
相机坐标系 3D (Xc, Yc, Zc) mm 以相机光心为原点,Z轴指向镜头前方
图像坐标系 2D (x, y) mm 物理成像平面上的坐标,原点在光轴与平面交点
像素坐标系 2D (u, v) pixel 图像数组中的行列索引,原点在左上角

1.1 世界坐标系

世界坐标系就是你的「参考系」。你可以在车间地板上画个原点,或者用标定板的角点作为原点。我个人习惯把世界坐标系建在标定板平面上,Z=0,这样计算会省很多事。

1.2 相机坐标系

相机坐标系的原点在光心,Zc轴沿着光轴方向。这里有个坑——Zc轴的正方向。不同厂家定义可能不一样,HALCON里默认Zc指向物体方向。我曾经在项目里没注意这个,结果标定出来的旋转矩阵符号全反了,折腾了两天才找到原因。

1.3 图像坐标系

图像坐标系是物理成像平面上的二维坐标,单位是毫米。它的原点在光轴与成像平面的交点——也就是主点。这个主点理论上在图像正中心,但实际相机装配会有偏差,所以标定的时候一定要把主点标出来。

1.4 像素坐标系

像素坐标系就是我们最终看到的图像数组。原点在左上角,u轴向右,v轴向下。注意,v轴是向下的,这和图像坐标系y轴方向相反。很多初学者在这里栽跟头。

关键转换关系:

世界 → 相机:刚体变换(旋转R + 平移t)

相机 → 图像:透视投影(针孔模型)

图像 → 像素:仿射变换(缩放 + 平移)

2. 两大机器人坐标系

搞视觉定位,最终是要让机器人动起来。所以机器人自己的坐标系也得搞明白。

坐标系 原点位置 用途
机器人基坐标系 机器人底座安装面中心 描述机器人本体在空间中的位置
工具坐标系 工具末端(TCP) 描述工具相对于法兰盘的位置

2.1 机器人基坐标系

基坐标系是机器人的「根」。所有机器人运动学计算,最终都要回到基坐标系。你想想看,视觉系统告诉机器人「物体在这里」,这个「这里」必须转换到基坐标系下,机器人才能理解。

2.2 工具坐标系

工具坐标系的原点就是TCP(Tool Center Point)。你装了个夹爪,或者装了个焊枪,TCP的位置就变了。标定工具坐标系,就是告诉机器人「我的工具末端在哪」。

我的经验:做手眼标定之前,先把工具坐标系标定好。否则你标出来的变换矩阵,误差会直接叠加到TCP的偏差上。我曾经在一个精密装配项目里,工具坐标系偏了0.5mm,结果视觉定位再准也装不进去。

3. 坐标系之间的转换链路

六个坐标系不是孤立的。它们通过一系列变换串联起来,形成完整的定位链路。

坐标系转换链路 世界坐标系 (Xw, Yw, Zw) 相机坐标系 (Xc, Yc, Zc) 图像坐标系 (x, y) 像素坐标系 (u, v) 刚体变换 R, t 透视投影 内参矩阵 仿射变换 缩放+平移 机器人基坐标系 (Xb, Yb, Zb) 工具坐标系 (Xt, Yt, Zt) 运动学正解 关节角度→位姿 手眼标定 求解相机与机器人之间的变换 外部标定 手眼变换 💡 核心思路 1. 视觉侧:世界→相机→图像→像素(成像链路) 2. 机器人侧:基坐标系→工具坐标系(运动学链路) 3. 手眼标定:建立视觉侧与机器人侧之间的变换关系 4. 最终目标:视觉检测到的物体位置 → 机器人可执行的位姿

4. 手眼标定中的坐标系关系

手眼标定,本质上就是求解相机坐标系和机器人坐标系之间的变换矩阵。根据相机安装方式不同,分为两种:

  • 眼在手上(Eye-in-Hand):相机固定在机器人末端,随机器人移动。标定求解的是 camHtool(相机到工具的变换)。
  • 眼在手外(Eye-to-Hand):相机固定在工作空间外,不随机器人移动。标定求解的是 camHbase(相机到基坐标系的变换)。

⚠️ 避坑指南:我曾经在一个Eye-in-Hand项目里,把标定板放在了机器人可达范围边缘。结果采集了20组数据,标定出来的旋转矩阵误差巨大。后来发现,标定板位置太偏,导致相机在不同角度下看到的特征点分布不均匀。建议标定板放在工作空间中心区域,且覆盖多个高度层。

5. HALCON中的坐标系操作

HALCON里处理坐标系变换,主要用这几个算子:

* 创建位姿(从平移向量和旋转角)
create_pose(TransX, TransY, TransZ, RotX, RotY, RotZ, 'Rp+T', 'gba', 'point', Pose)

* 位姿变换(将点从一个坐标系转换到另一个)
affine_trans_point_3d(Pose, PointIn, PointOut)

* 手眼标定(眼在手上)
calibrate_hand_eye(PosesCalib, PosesRobot, 'eye_in_hand', CamParam, PoseCamTool)

* 手眼标定(眼在手外)
calibrate_hand_eye(PosesCalib, PosesRobot, 'eye_to_hand', CamParam, PoseCamBase)

这里要注意,HALCON的位姿表示方式有几种:'Rp+T'、'R+T'、'gba'、'abg'。我个人习惯用 'Rp+T' 和 'gba',因为旋转顺序明确,不容易搞混。

小技巧:调试的时候,可以用 disp_pose 把位姿可视化出来。看一眼坐标系箭头方向,比盯着数字矩阵靠谱多了。

6. 坐标系对齐的常见问题

  1. 旋转方向不一致:机器人用欧拉角,HALCON用旋转矩阵。转换的时候注意顺序。
  2. 单位不统一:机器人给的是mm,HALCON默认也是mm,但有些第三方库用m。统一单位再算。
  3. 坐标系手性:大部分机器人用右手系,但有些特殊构型可能用左手系。确认清楚再标定。
  4. 标定板方向:标定板放在工作台上,Z轴朝上还是朝下?我建议统一让标定板Z轴朝上,和机器人基坐标系Z轴方向一致。

嗯,坐标系这部分就讲到这里。内容不少,但都是基础中的基础。你把这些坐标系之间的关系理清楚了,后面手眼标定的原理理解起来就顺了。