4、内参标定方法:相机内参标定(张正友法)、雷达内参标定、IMU内参标定、标定板设计与使用
内参标定,说白了就是搞清楚传感器自己的“脾气”。
相机镜头有畸变,雷达点云有偏移,IMU有零偏和噪声。你不把这些摸清楚,后面做外参联合标定就是白搭。我见过太多团队,外参怎么调都对不上,最后发现是内参根本没标准。
这一章,我把三种主流传感器的内参标定方法掰开揉碎讲清楚。还有标定板的设计要点——这东西看着简单,坑其实不少。
4.1 相机内参标定:张正友法
张正友法是目前最主流的相机内参标定方法。它只需要你打印一张棋盘格,拍十几张不同角度的照片,就能算出内参矩阵和畸变系数。
核心原理:利用棋盘格上已知的角点坐标(世界坐标系),与图像上检测到的角点坐标(像素坐标系)建立对应关系,通过最小二乘法求解内参。
具体步骤我总结为五步:
- 打印标定板——棋盘格,角点数量要明确,比如 9×6 内角点。
- 拍摄图像——至少 15-20 张,覆盖不同角度、距离、倾斜。别只拍正面的,那样解不出畸变。
- 角点检测——用 OpenCV 的
findChessboardCorners()提取亚像素角点。 - 求解内参——调用
calibrateCamera(),得到内参矩阵 K 和畸变系数 D。 - 评估结果——看重投影误差,一般小于 0.5 像素就算合格。
这里给出一段我常用的标定代码框架:
import cv2
import numpy as np
# 棋盘格内角点数量
pattern_size = (9, 6)
objp = np.zeros((pattern_size[0]*pattern_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2)
objpoints = [] # 世界坐标系点
imgpoints = [] # 图像坐标系点
for fname in image_files:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, corners = cv2.findChessboardCorners(gray, pattern_size, None)
if ret:
objpoints.append(objp)
imgpoints.append(corners)
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(
objpoints, imgpoints, gray.shape[::-1], None, None)
print("内参矩阵:\n", mtx)
print("畸变系数:\n", dist)
print("重投影误差:", ret)
我的经验:拍摄时尽量让标定板占画面 1/3 以上。太小了角点检测不准。还有,别用手拿着拍,贴在一个平板上效果更好。
避坑指南:我曾经遇到一个项目,标定结果重投影误差只有 0.3 像素,但实际测距偏差很大。后来发现是标定板打印尺寸不准确,导致世界坐标系的尺度错了。记住:标定板的方格尺寸必须精确测量,用游标卡尺量到 0.1mm 精度。
4.2 雷达内参标定
激光雷达的内参标定,很多人容易忽略。其实雷达也有自己的“内参”——比如每个激光发射器的水平偏角、垂直偏角、距离偏移。
雷达内参标定主要解决两个问题:
- 角度偏差——每个激光束的实际发射角度与理论角度之间的误差。
- 距离偏差——由于温度、老化等因素导致的测距偏移。
标定方法一般有两种:
| 方法 | 原理 | 适用场景 |
|---|---|---|
| 平面标定法 | 用已知平面(如白墙)作为参考,通过点云拟合平面,反算每个点的角度和距离误差 | 16线、32线雷达 |
| 球体标定法 | 用标准球体作为目标,通过点云拟合球心,计算每个激光束的偏差 | 64线、128线高线束雷达 |
我个人习惯用平面标定法,操作简单,成本低。具体做法:
- 找一面平整的大白墙,用全站仪或激光测距仪测量墙面的精确位置。
- 将雷达正对墙面,采集点云数据。
- 对每个激光束的点云做平面拟合,计算拟合平面与真实平面的偏差。
- 将偏差值写入雷达的校准参数文件。
关键指标:标定后,每个激光束的距离误差应小于 2cm,角度误差应小于 0.1°。如果偏差过大,说明雷达硬件可能有问题,不是标定能解决的。
4.3 IMU内参标定
IMU的内参标定,说白了就是搞清楚加速度计和陀螺仪的“零偏”和“噪声”。
IMU的误差模型可以简化为:
a_meas = a_true + b_a + n_a
w_meas = w_true + b_g + n_g
其中:
b_a、b_g是零偏(bias)n_a、n_g是随机噪声
标定方法主要有两种:
| 方法 | 原理 | 精度 | 设备要求 |
|---|---|---|---|
| 六位置法 | 将IMU分别放置在6个正交方向,利用重力加速度标定加速度计 | 中等 | 无特殊设备 |
| 转合法 | 使用高精度转台,提供精确的角度和角速度参考 | 高 | 需要转台 |
在量产项目中,我建议用六位置法做初标,再用转合法做精标。六位置法虽然精度不如转台,但胜在成本低、操作快,适合产线批量标定。
我的经验:IMU标定最关键的是“静止”。每次采集数据时,必须保证IMU完全静止至少 10 秒。我曾经因为产线振动太大,标出来的零偏全是错的。后来加了减震垫才解决。
避坑指南:IMU的零偏会随温度变化。量产时一定要做温度补偿标定。我见过一个项目,冬天标定的IMU,夏天直接漂移了 3 倍。后来我们在标定流程里加入了温箱环节,从 -20°C 到 60°C 每 10°C 采一组数据,拟合温度补偿曲线。
4.4 标定板设计与使用
标定板是内参标定的“尺子”。设计得好,标定事半功倍;设计得差,数据全废。
我总结了几条核心设计原则:
- 尺寸精度——方格边长必须精确,误差控制在 0.1mm 以内。建议用铝基板或玻璃基板,不要用纸板(容易变形)。
- 角点数量——内角点建议 9×6 或 11×8。太少解不出畸变,太多检测容易漏。
- 对比度——黑白格对比度要高,白色反光率 > 80%,黑色 < 10%。亚光材质最好,避免反光。
- 尺寸选择——标定板大小根据相机视场角决定。一般让标定板在画面中占 1/3 到 1/2 为宜。
下面这张图展示了标定板在标定流程中的核心位置:
标定板的使用也有一些讲究:
- 拍摄距离——从 0.5m 到 5m 都要覆盖,这样才能标定出不同距离下的畸变。
- 角度变化——标定板平面与相机光轴的夹角从 0° 到 45° 都要有。只拍正面的,畸变系数标不准。
- 光照条件——避免强光直射和反光。我一般在室内用漫射光源,或者阴天室外拍摄。
量产部署建议:在产线上,标定板要固定在一个机械臂或滑台上,保证每次位置重复精度在 1mm 以内。标定板表面要定期清洁,灰尘和划痕会影响角点检测精度。