2. 标定流程标准化:图像采集规范、标定板位姿要求、标定算子选择策略
标定这件事,很多人觉得就是拍几张照片,跑个算子就完事了。但我在项目里见过太多「标定结果挺好,一上产线就偏」的情况。说白了,问题往往出在流程上——采集不规范、位姿随意、算子选错,这三座大山不倒,后面优化再努力也白搭。
这一章,我就把这三块掰开揉碎讲清楚。你按这个流程走,至少能保证标定结果可复现、可追溯、可落地。
2.1 图像采集规范:拍好一张图,标定成功一半
图像采集不是按快门那么简单。我见过有人用手扶着标定板拍,结果板子晃了0.5mm,标定误差直接翻倍。下面这几条,是我踩坑踩出来的硬规矩。
2.1.1 光照条件
- 均匀性优先:标定板表面光照不均匀,圆心提取精度会下降。我建议用漫射光源或环形光源,避免点光源直射产生高光斑。
- 避免过曝:标定板白色区域灰度值最好控制在200-240之间,不要超过250。过曝会让圆点边缘模糊,提取亚像素精度打折。
- 环境光稳定:如果产线有频闪灯或自然光变化,标定结果会漂。我习惯在标定前用
grab_image连续抓几帧,看灰度波动是否在±5以内。
2.1.2 相机参数设置
| 参数 | 推荐值 | 为什么 |
|---|---|---|
| 增益 | 最低(0或1) | 增益引入噪声,影响圆心提取精度 |
| 曝光时间 | 手动固定 | 自动曝光会导致不同图像亮度不一致,标定结果不稳定 |
| 光圈 | F8-F11 | 景深适中,像差较小,边缘清晰 |
| 分辨率 | 全分辨率 | 降采样会丢失亚像素信息,标定精度打折扣 |
我曾经踩过的坑:有一次标定结果反复跳动,查了两天才发现是相机自动增益没关。环境光稍微一变,增益跟着变,等效焦距就漂了。从那以后,我所有标定项目都强制手动固定曝光和增益。
2.1.3 图像数量与覆盖
最少拍多少张?我的经验是:15-20张。少于10张,畸变参数容易过拟合;多于30张,边际收益递减,还增加计算时间。
关键不是数量,是覆盖。你要让标定板出现在视场的:
- 四个角(各1-2张)
- 中心区域(3-4张)
- 边缘中间位置(各1张)
- 不同倾斜角度(绕X轴和Y轴各倾斜15-30°,各2-3张)
- 不同工作距离(如果景深较大,在近端和远端各拍几张)
小技巧:拍完一组后,用
calib_data_points查看每张图的平均投影误差。如果某张图误差明显偏大(超过0.5像素),大概率是那张图拍糊了或者标定板没放稳,直接删掉重拍。
2.2 标定板位姿要求:角度、距离、姿态,一个都不能少
标定板的位姿,直接决定了标定结果的稳定性和精度。我见过有人把标定板平放在桌面上拍了15张,结果畸变参数完全没约束——因为所有图像里标定板都在同一个平面,畸变模型根本解不出来。
2.2.1 位姿多样性原则
标定板在每张图中的位姿,应该尽量覆盖以下自由度:
- 平移:X、Y方向覆盖整个视场
- 旋转:绕Z轴(图像平面内)旋转0-360°,绕X/Y轴(倾斜)旋转0-30°
- 距离:Z方向覆盖工作距离的±10%
为什么要倾斜?因为畸变参数需要不同深度的约束才能解稳。如果所有图像都是正对相机拍的,径向畸变和切向畸变会耦合在一起,解出来全是错的。
2.2.2 位姿禁忌
| 禁忌行为 | 后果 | 正确做法 |
|---|---|---|
| 标定板与像平面平行 | 畸变参数不可解 | 至少倾斜15°以上拍3-5张 |
| 标定板超出景深范围 | 圆点模糊,提取精度下降 | 保持标定板在景深范围内 |
| 标定板边缘被遮挡 | 识别失败或提取不全 | 确保所有圆点完整可见 |
| 标定板反光严重 | 圆点灰度异常,提取偏移 | 调整光源角度或使用哑光标定板 |
我的经验法则:每张图里,标定板面积占视场面积的1/4到1/3。太小了,圆点数量不够,约束不足;太大了,边缘圆点靠近视场边缘,畸变影响大,容易引入误差。
2.2.3 标定板选择建议
- 圆点阵列板:HALCON推荐使用
caltab系列,圆点间距已知,圆心提取精度高。我习惯用7×7或9×9的圆点板。 - 棋盘格:角点提取速度快,但亚像素精度略低于圆点板。适合对速度要求高、精度要求一般的场景。
- 尺寸选择:标定板边长约为视场短边的1/3到1/2。太小了,圆点间距测量误差占比大;太大了,边缘畸变严重。
2.3 标定算子选择策略:选对算子,事半功倍
HALCON里标定相关的算子不少,但核心就几个。我按使用场景给你梳理一下。
2.3.1 核心算子一览
| 算子 | 用途 | 适用场景 |
|---|---|---|
find_calib_object | 在图像中查找标定板并提取标记点 | 所有标定流程的起点 |
camera_calibration | 单目相机标定 | 标准单目视觉系统 |
binocular_calibration | 双目立体标定 | 双目视觉、3D测量 |
hand_eye_calibration | 手眼标定 | 机器人引导、抓取 |
calibrate_cameras | 多相机联合标定 | 多目系统、全景拼接 |
2.3.2 算子选择逻辑
我一般按这个流程走:
- 先确定相机模型:面阵相机用
area_scan_division或area_scan_polynomial;线阵相机用line_scan。 - 再选标定类型:单目标定用
camera_calibration;双目标定用binocular_calibration;手眼标定用hand_eye_calibration。 - 最后调参数:
camera_calibration里有个EstimateParams参数,我建议第一次跑时设为'all',让算法自动估计所有参数。如果结果稳定,再固定部分参数(比如主点)减少自由度。
我个人习惯:先用
find_calib_object把所有图像跑一遍,检查每张图的提取质量。如果某张图提取失败或误差过大,我会先排查图像质量,而不是直接调算子参数。算子本身很稳定,问题多半出在输入数据上。
2.3.3 参数调优要点
- 初始值:焦距和主点给个合理初值(比如焦距≈镜头焦距×像元尺寸的倒数),能加速收敛。我给初值时,误差从没超过5次迭代。
- 畸变模型:
division模型参数少(1个畸变系数),适合大多数镜头;polynomial模型参数多(3-5个系数),适合大畸变镜头(如鱼眼)。我一般先用division,如果残差大于0.3像素再换polynomial。 - 优化方法:默认的
'nonlinear'优化就够了。如果标定板位姿覆盖很好,结果通常一次收敛。
2.4 标定流程标准化框架
把上面三块串起来,我总结了一个标准流程。你按这个走,基本不会出大问题。
核心原则:标定流程标准化不是为了增加工作量,而是为了可复现。你今天标的结果,三个月后换台相机,按同样流程再标一次,结果应该基本一致。如果做不到,说明流程里还有变量没控制住。