4. 视觉基础
各位同学,欢迎来到视觉基础这一章。说实话,这部分内容看起来偏理论,但它是整个项目的基石。你想想看,机械臂要抓东西,首先得“看见”东西在哪儿。而“看见”这件事,背后就是相机模型和标定在起作用。
我刚开始做机器人抓取时,就吃过没搞懂相机模型的亏。当时相机拍出来的位置总偏几毫米,折腾了两天才发现是内参没标准。嗯,从那以后,我再也不敢跳过这一步了。
4.1 相机模型:小孔成像与针孔模型
相机成像,说白了就是小孔成像原理。光线从物体反射,穿过镜头中心(光心),投射到成像平面上。我们用的针孔模型,就是把这个过程数学化。
核心公式很简单:
X_image = f * (X_world / Z_world)
Y_image = f * (Y_world / Z_world)
其中 f 是焦距,单位是像素。这里有个坑:实际相机镜头不是理想针孔,所以我们需要引入内参来修正。
关键点:相机模型把三维世界点映射到二维像素点。这个映射关系,由内参和外参共同决定。
4.2 内参与外参:相机的“身份证”和“定位器”
内参是相机自己的属性,就像人的身份证。外参是相机在世界坐标系中的位姿,就像人的GPS定位。
内参矩阵 K:
K = [[fx, 0, cx],
[ 0, fy, cy],
[ 0, 0, 1]]
- fx, fy:焦距在x、y方向的像素值
- cx, cy:主点坐标(光心在像素平面的投影)
外参矩阵 [R|t]:
- R:旋转矩阵(3x3),描述相机朝向
- t:平移向量(3x1),描述相机位置
我习惯把外参理解为“相机在哪儿、朝哪儿看”。内参则是“相机怎么把光线变成像素”。
| 参数类型 | 含义 | 是否随相机移动变化 |
|---|---|---|
| 内参 | 焦距、主点、畸变系数 | 否(固定) |
| 外参 | 旋转矩阵R、平移向量t | 是(随位姿变化) |
我的经验:标定内参时,棋盘格要拍20张以上,覆盖不同角度和距离。只拍几张的话,标定结果容易飘。
4.3 畸变校正:让直线变直
实际镜头都有畸变,尤其是广角镜头。径向畸变让直线变弯,切向畸变让图像倾斜。
畸变模型:
x_distorted = x * (1 + k1*r^2 + k2*r^4 + k3*r^6) + [2*p1*x*y + p2*(r^2 + 2*x^2)]
y_distorted = y * (1 + k1*r^2 + k2*r^4 + k3*r^6) + [p1*(r^2 + 2*y^2) + 2*p2*x*y]
- k1, k2, k3:径向畸变系数
- p1, p2:切向畸变系数
- r:像素点到主点的距离
我曾经在一个项目中,因为没做畸变校正,机械臂抓取时边缘物体偏差达到5mm。校正后直接降到0.5mm以内。所以,这一步千万别省。
避坑指南:畸变校正后,图像边缘会被裁剪或拉伸。建议保留校正后的完整图像,不要直接裁剪,否则会丢失边缘信息。
4.4 手眼标定:让相机和机械臂“握手”
手眼标定,就是求相机坐标系和机械臂基坐标系之间的变换关系。说白了,就是让机械臂知道“相机看到的物体,在我自己的坐标系里在哪儿”。
两种主流方式:
- Eye-in-Hand(眼在手上):相机装在机械臂末端,随臂移动
- Eye-to-Hand(眼在手外):相机固定安装,不随臂移动
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Eye-in-Hand | 视野灵活,可近距离观察目标 | 标定复杂,需考虑末端位姿变化 | 抓取、装配、检测 |
| Eye-to-Hand | 标定简单,视野固定 | 视野受限,可能被遮挡 | 分拣、码垛、定位 |
标定方程:
对于 Eye-in-Hand:
AX = XB
其中 A 是机械臂末端位姿变化,B 是相机看到的标定板位姿变化,X 是待求的手眼矩阵。
对于 Eye-to-Hand:
AX = XB
形式一样,但 A 和 B 的含义不同。A 是机械臂基座到末端的变换,B 是相机到标定板的变换。
核心思路:手眼标定本质是解 AX=XB 方程。常用方法有 Tsai 两步法、Park 法等。我习惯用 OpenCV 的 calibrateHandEye() 函数,直接出结果。
4.5 知识体系总览
下面这张图,把本章的核心逻辑串起来了。你一看就明白:
4.6 实战步骤:手眼标定流程
我直接给你一个标准流程,照着做就行:
- 准备标定板:棋盘格或圆点阵,打印出来贴平板上
- 固定相机:如果是 Eye-in-Hand,把相机装在机械臂末端;如果是 Eye-to-Hand,固定安装
- 采集数据:移动机械臂到不同位姿,同时记录:
- 机械臂末端位姿(从控制器读取)
- 相机拍摄的标定板图像
- 提取角点:用 OpenCV 的 findChessboardCorners() 提取标定板角点
- 求解手眼矩阵:调用 calibrateHandEye(),输入机械臂位姿和相机位姿
- 验证精度:用标定结果反算,看误差是否在可接受范围内
我的习惯:采集数据时,让机械臂走 15-20 个不同姿态。姿态差异越大,标定结果越稳定。别偷懒只拍 5 个点,那会后悔的。
4.7 常见问题与避坑
- 标定结果不收敛:检查标定板是否平整,图像是否清晰
- 误差偏大:增加采集姿态数量,覆盖更大工作空间
- 手眼矩阵奇异:避免机械臂走直线或纯旋转,要混合运动
我曾经踩过的坑:有一次标定结果一直不对,折腾了两天。最后发现是标定板贴在了亚克力板上,反光导致角点提取不准。换成哑光纸打印,一次就过了。
好了,这一章的内容就这些。记住:相机模型是基础,内参外参是核心,畸变校正不能省,手眼标定是关键。把这些搞明白,后面的视觉定位和机械臂控制就顺了。