20、多Camera标定:内参/外参标定、多Camera联合标定、在线标定
说到车载摄像头的标定,我估计不少朋友第一反应就是「棋盘格」。没错,标定板确实是基础。但真正上了车,你会发现事情远没那么简单。尤其是多路摄像头系统——环视、前视、侧视、后视,每个摄像头都有自己的脾气。你想想看,如果它们各自的内参都不准,那融合出来的全景影像能看吗?
我个人习惯把标定分成三个层次:单摄像头内参标定、多摄像头外参联合标定、以及在线动态标定。今天咱们就一层层剥开来看。
20.1 内参标定:摄像头的「出厂校准」
内参标定,说白了就是搞清楚摄像头自己的「内在参数」。包括焦距、主点坐标、畸变系数这些。我遇到过不少项目,图像拼接出来边缘扭曲得厉害,查到最后发现是内参没标准。
常用的方法还是张正友标定法。用棋盘格在不同角度拍个十几张,然后解算内参矩阵和畸变系数。这里我贴一段核心代码,帮你理解流程:
// 使用OpenCV进行内参标定(C++示例)
std::vector<cv::Mat> rvecs, tvecs;
cv::Mat cameraMatrix, distCoeffs;
// 假设已经提取了所有图像中的角点坐标
cv::calibrateCamera(
objectPoints, // 世界坐标系中的棋盘格角点
imagePoints, // 图像坐标系中的角点
imageSize, // 图像尺寸
cameraMatrix, // 输出:内参矩阵
distCoeffs, // 输出:畸变系数
rvecs, tvecs, // 输出:每张图像的旋转和平移向量
cv::CALIB_FIX_ASPECT_RATIO | cv::CALIB_ZERO_TANGENT_DIST
);
标定完成后,记得做一步重投影误差验证。我一般要求误差小于0.5像素,超过这个值就说明标定板拍得不够好,或者摄像头本身有问题。
20.2 外参标定:摄像头之间的「相对位置」
内参搞定之后,接下来就是外参。外参描述的是每个摄像头相对于车辆坐标系(或者某个基准摄像头)的旋转和平移。说白了,就是搞清楚「这个摄像头装在车的哪个位置,朝哪个方向看」。
多摄像头联合标定,我常用的方法有两种:
- 基于标定板的方法:把一个大棋盘格放在所有摄像头的公共视野内,同时拍摄,然后解算两两之间的位姿关系。
- 基于自然特征的方法:利用场景中的特征点(比如车道线、路沿)进行匹配,适合在线标定。
下面这张图展示了多摄像头联合标定的基本流程:
联合标定的核心,是构建一个全局优化问题。把所有摄像头的内参、外参、以及标定板上的3D点都作为变量,最小化所有观测的重投影误差。这其实就是个大型的BA(Bundle Adjustment)问题。
20.3 在线标定:车辆运行中的「自校准」
出厂标定做得再好,车开久了也会出问题。摄像头支架松动、温度变化导致镜头位移、甚至洗车时被碰了一下——这些都会让外参发生变化。所以,在线标定就成了量产车上必不可少的能力。
在线标定的思路其实不复杂:利用车辆行驶过程中检测到的稳定特征(比如车道线、路沿、静止车辆),实时估计摄像头外参的变化量。我把它分为两个阶段:
- 初始化阶段:车辆启动后,利用出厂标定值作为初始值,快速收敛到当前真实位姿。
- 跟踪阶段:车辆行驶过程中,持续检测特征,微调外参,保证拼接效果始终在线。
这里有一个常见的工程陷阱——在线标定不能过度依赖单一特征。比如只用车道线,那在弯道或者无车道线路段就会失效。我建议至少融合三种特征:车道线、静止车辆、以及道路纹理。
20.4 标定结果的验证与评估
标定做完了,怎么知道它准不准?我一般用三个指标来评估:
| 指标 | 说明 | 合格标准 |
|---|---|---|
| 重投影误差 | 3D点投影到图像上的位置与实际检测位置的偏差 | < 0.5 像素 |
| 拼接缝误差 | 相邻摄像头图像在重叠区域的像素偏差 | < 3 像素 |
| 俯视图直线度 | 将标定板放置在车辆四周,检查俯视图中的直线是否笔直 | 直线弯曲 < 2 像素 |
这三个指标缺一不可。重投影误差只反映单摄像头的标定精度,拼接缝误差反映的是外参的准确性,而俯视图直线度则是最终用户体验的直接体现。
好了,关于多摄像头标定的内容就聊到这儿。从内参到外参,从离线到在线,每一步都有不少坑。但只要你把基础打牢了,后面做融合、做感知都会顺手很多。