3. 单相机标定实战
单相机内参标定是多相机系统标定的基础环节。它的目标很明确:求出相机的内参矩阵 CameraMatrix(焦距、主点)和畸变系数 DistortionCoeffs(径向畸变 K1、K2、K3,切向畸变 P1、P2),并给出像素当量 PixelSize。这些参数一旦确定,后续多相机之间的外参求解、三维重建、手眼标定才有可靠的几何基础。本节以 HALCON 的标定助手(Calibration Assistant)和标定算子为主线,完整走一遍从采集图像到误差评估的流程。
一、标定前的物理准备
HALCON 标定依赖一块已知几何的标定板。常用的是 .descr 描述文件配套的圆点阵列标定板,例如 caltab_30mm.descr,其外框尺寸 30 mm、圆点直径 1.5 mm、圆点间距 3 mm。标定板必须平整、无划痕,且描述文件中的参数要与实物严格一致——如果描述文件写的是 30 mm 而实物是 50 mm,标定出的焦距会整体偏差约 1.67 倍。
采集时要注意三点:一是标定板在整幅图像中要占据足够大的面积,通常建议覆盖图像对角线的 1/3 以上;二是标定板要覆盖视场的各个区域,包括四角和中心,否则畸变系数无法被有效约束;三是标定板姿态要多样,既要有正对相机的,也要有倾斜 30°~45° 的,倾斜姿态对焦距和畸变的解算贡献最大。一般采集 12~20 张图像即可,少于 8 张时参数稳定性会明显下降。
二、标定助手与算子两条路径
HALCON 提供两条等价路径。标定助手是图形化界面,适合快速上手和参数试错;标定算子适合脚本化、批量化和集成到多相机流程中。两者底层调用的是同一组算子,理解算子流程后,助手界面上的每一步都能对应上。
核心算子流程如下:先用 find_calib_object 在每张图像中提取标定板上的标记点,得到 CalibDataID 中记录的观测;再用 calibrate_cameras 一次性求解所有内参;最后用 get_calib_data 取出结果,并用 camera_calibration 或 gen_radial_distortion_map 做可视化验证。下面是一段可直接参考的 HALCON 代码骨架:
* 1. 创建标定数据模型,指定相机数量为 1
create_calib_data ('calibration_object', 1, 1, CalibDataID)
* 2. 设置相机类型与标定板描述文件
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', [])
set_calib_data_calib_object (CalibDataID, 0, 'caltab_30mm.descr')
* 3. 逐张读取图像并提取标定板
for Index := 1 to 15 by 1
read_image (Image, 'calib_' + Index$'02d')
find_calib_object (Image, CalibDataID, 0, 0, Index, [], [])
get_calib_data_observ_contours (Contours, CalibDataID, 'marks', 0, 0, Index)
endfor
* 4. 求解内参
calibrate_cameras (CalibDataID, Error)
* 5. 取出结果
get_calib_data (CalibDataID, 'camera', 0, 'params', CameraParam)
get_calib_data (CalibDataID, 'camera', 0, 'params_deviations', Deviations)
其中 'area_scan_division' 是面阵相机的除法畸变模型,适合大多数工业镜头;若镜头畸变较大,可改用 'area_scan_polynomial' 多项式模型。相机参数向量 CameraParam 的顺序为 [焦距, K1, K2, P1, P2, 中心行, 中心列, 像元宽, 像元高],这一点在读取结果时务必核对,顺序错位会导致后续外参求解完全错误。
三、误差评估与结果可视化
标定完成后,calibrate_cameras 返回的 Error 是重投影误差的均方根值,单位是像素。工程上通常要求单相机重投影误差小于 0.1 像素,0.1~0.3 像素可接受但需检查是否有姿态分布不均的问题,超过 0.5 像素则说明采集或提取环节存在明显问题,应重新采集。
除了整体误差,还要看每张图像的单独误差。用 get_calib_data 取 'calib_obj_pose' 和观测点,可以逐张计算残差,找出误差偏大的图像。常见原因是标定板在该姿态下部分圆点被遮挡、反光或超出视场边缘。把这些图像剔除后重新标定,误差往往能明显下降。
可视化方面,最直观的是畸变校正前后对比:用 gen_radial_distortion_map 生成映射图,再用 map_image 对原图做校正,观察直线是否被拉直。另一种方式是把标定板的理论投影点与实际提取点叠加显示,残差向量用短线段画出,一眼就能看出误差集中在图像哪个区域。
四、常见问题与排查思路
标定误差偏大时,按以下顺序排查通常能快速定位:第一,检查标定板描述文件与实物是否一致,这是最容易被忽略也最致命的问题;第二,检查图像中标定板是否完整、清晰,圆点是否被反光或阴影干扰;第三,检查姿态分布,如果所有图像都是正对相机的,畸变系数会严重欠约束;第四,检查相机参数模型是否选错,大畸变镜头用除法模型可能拟合不足,应改用多项式模型。
另一个常见现象是标定结果中主点偏离图像中心很远。正常情况下主点应在图像中心附近(偏差几十像素以内)。如果主点跑到图像边缘,通常说明标定板姿态过于单一,或者提取的标记点存在系统性偏移。此时应增加倾斜姿态的图像,并检查 find_calib_object 的提取参数是否合适。
CameraParam 和 Error 一起保存到工程配置中,并记录标定日期、镜头型号、焦距档位。多相机系统中,每台相机的内参都应独立标定并归档,后续外参标定直接读取这些参数,避免重复标定引入不一致。五、从单相机到多相机的衔接
单相机内参标定完成后,得到的 CameraParam 就是多相机系统的输入之一。在多相机标定中,每台相机先用本节方法独立求出内参,然后再用 calibrate_cameras 的多相机模式或 stereo_calibration 求解相机之间的外参。如果单相机内参不准,外参求解会把误差放大到三维重建结果中,表现为深度方向上的系统性偏差。因此,单相机标定阶段把重投影误差压到 0.1 像素以内,是后续多相机集成质量的第一道保障。
实际工程中,建议把本节流程封装成一个可复用的标定脚本:输入图像目录和标定板描述文件,输出 CameraParam、Error 和一份包含逐张残差的报告。这样在多相机系统中,每台相机只需替换图像目录即可完成标定,既保证流程一致,也便于追溯每台相机的标定质量。