第二章 相机模型与标定:针孔相机模型、内参与外参矩阵、畸变模型、张正友标定法
各位同学,欢迎来到第二章。
上一章我们聊了视觉伺服的整体框架,说白了就是「看-想-动」的闭环。但有个关键问题:相机看到的世界,怎么变成机器人能理解的数学量?
嗯,这就是本章要解决的——相机模型与标定。
我个人习惯把相机标定比作「给眼睛配眼镜」。你想想看,如果不知道镜片的参数,你看到的物体位置就是错的。机器人也一样,没有准确的相机参数,视觉伺服就是空中楼阁。
2.1 针孔相机模型:最朴素的成像原理
先聊最经典的针孔模型。说白了,就是一个小孔成像。
光线从物体表面反射,穿过一个小孔,投射到后面的成像平面上。这个模型虽然简单,但足够描述大多数工业相机的成像过程。
核心公式:
从三维世界点 (X, Y, Z) 到二维像素点 (u, v) 的映射,可以写成:
s * [u, v, 1]^T = K * [R | t] * [X, Y, Z, 1]^T
其中 s 是尺度因子,K 是内参矩阵,[R | t] 是外参矩阵。
我在项目中遇到过一件事:有次用了一个廉价USB摄像头做抓取实验,怎么调参数都抓不准。后来发现,针孔模型假设光轴严格垂直于成像平面,但廉价镜头根本做不到。这就是为什么我们需要更复杂的模型。
2.2 内参矩阵:相机的「基因」
内参矩阵 K 描述了相机内部的几何特性。它长这样:
K = [fx, 0, cx;
0, fy, cy;
0, 0, 1]
这里 fx, fy 是焦距(以像素为单位),cx, cy 是主点坐标(光轴与成像平面的交点)。
我建议你记住一个直觉:fx 和 fy 决定了「放大倍数」,cx 和 cy 决定了「画面中心在哪」。你想想看,如果主点偏了,你看到的物体位置就会整体偏移。
避坑指南:
我曾经在标定一个广角镜头时,发现 cx, cy 偏离图像中心很多。一开始以为是标定错了,后来查资料才知道,广角镜头的主点偏移是正常现象。所以别一看到主点偏移就觉得标定失败。
2.3 外参矩阵:相机在哪儿?
外参矩阵 [R | t] 描述了相机坐标系相对于世界坐标系的位姿。R 是旋转矩阵,t 是平移向量。
说白了,外参就是回答两个问题:
- 相机朝哪个方向看?(R)
- 相机在哪儿?(t)
在视觉伺服中,外参矩阵特别重要。因为我们要把目标点的坐标从世界坐标系转换到相机坐标系,才能计算误差。
注意:
外参矩阵不是固定的!每次移动相机,外参都会变。而内参矩阵,只要不换镜头、不变焦距,就是固定的。
2.4 畸变模型:现实总是不完美的
针孔模型是理想情况。现实中的镜头,尤其是广角镜头,会产生畸变。
畸变主要分两种:
- 径向畸变:光线穿过镜头时,边缘弯曲更严重。像鱼眼镜头那种效果。
- 切向畸变:镜头和成像平面不平行导致的。
数学上,我们用多项式来修正畸变:
x_corrected = x * (1 + k1*r^2 + k2*r^4 + k3*r^6) + [2*p1*x*y + p2*(r^2 + 2*x^2)]
y_corrected = 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 是切向畸变系数。
我记得第一次做畸变矫正时,看到矫正后的图像边缘被拉伸得不成样子,吓了一跳。后来才明白,畸变矫正的本质是把弯曲的像素「掰直」,边缘区域像素被拉伸是正常的。
经验之谈:
对于大多数工业应用,只标定 k1, k2 两个径向畸变系数就够了。k3 通常用于大畸变镜头(比如鱼眼)。切向畸变 p1, p2 一般很小,可以忽略。
2.5 张正友标定法:业界标准
好了,前面讲了这么多参数,怎么得到它们?
张正友标定法是目前最流行的相机标定方法。它的核心思想是:用一张棋盘格,从不同角度拍几张照片,就能算出所有参数。
为什么用棋盘格?因为棋盘格的角点容易检测,而且我们知道每个角点的物理坐标(比如格子边长30mm)。
标定流程大致如下:
- 打印一张棋盘格,贴在平面上
- 从不同角度拍摄10-20张照片
- 检测每张照片中的角点坐标
- 用最小二乘法求解内参、外参和畸变系数
- 用最大似然估计优化所有参数
关键点:
张正友标定法假设棋盘格是平面(Z=0),这样就把三维问题简化成了二维问题。这个假设大大降低了标定的复杂度。
我建议你标定时注意几点:
- 照片要覆盖整个视场,尤其是边缘
- 棋盘格要倾斜,不要总是正对着相机
- 光照要均匀,避免反光
我曾经因为偷懒只拍了5张照片,结果标定出来的畸变系数完全不对。后来老老实实拍了15张,效果就好了很多。
2.6 知识体系总览
下面这张图总结了本章的核心逻辑:
2.7 标定实操要点
最后,分享几个标定时的实操经验:
| 步骤 | 要点 | 常见错误 |
|---|---|---|
| 准备棋盘格 | 格子数量7×9或8×10,边长30-50mm | 格子太小或太大,导致角点检测失败 |
| 拍摄照片 | 10-20张,覆盖视场各区域 | 照片太少,标定结果不稳定 |
| 角点检测 | 确保亚像素精度 | 光照不均导致角点偏移 |
| 参数优化 | 使用重投影误差评估 | 忽略重投影误差,盲目相信结果 |
重要提醒:
标定完成后,一定要验证。我的做法是:用标定好的参数去测量一个已知尺寸的物体,看看误差在不在可接受范围内。如果误差超过0.5像素,建议重新标定。
好了,这一章的内容就到这里。相机模型和标定是视觉伺服的基础,就像盖房子的地基。地基打不好,上层建筑再漂亮也没用。