简介:面向计算机视觉与机器视觉检测从业者,这份《Halcon参考手册英文直译中文版(无删减)》第六章“Calibration(标定)”聚焦相机模型建立、投影与反投影、镜头畸变补偿及内外参求解,适合需要提升测量与定位精度的初中级算法工程师查阅。资源为1个PDF文件,压缩包约813KB,按原文章节直译,涵盖校准板与校准对象、校准输入数据准备、calibrate_cameras实际标定、结果查询及RMSE误差评估,并延伸至单目、双目、多视图和手眼标定等配置。读者可系统理解区域扫描相机参数、针孔与远心等模型差异,以及校准图像采集和失败排查要点。已有362人学习,可作为Halcon标定流程的案头参考。
1. 换镜头后尺寸整体漂移:先翻第六章 Calibration 的标定链路
产线换了一支镜头,视觉检测算法跑出来的尺寸整体偏了 0.08 mm,操作员第一反应是调阈值、改模板,结果越调越乱。这种场景在计算机视觉项目里很常见,真正该先查的往往是 Halcon 标定参数有没有跟着镜头、光圈和工作距离一起更新。第六章 Calibration 的这份英文直译中文版,讲的就是从校准板、标定数据模型,到calibrate_cameras、RMSE 验收、内参外参和畸变模型的一条完整链路。
它解决的不是“怎么调一个算子”这种单点问题,而是把相机成像模型这个黑匣子拆开:3D 世界点怎么落到像素坐标,径向畸变和离心畸变在哪一步补偿,线扫相机的运动矢量为什么会影响标定成败。适合已经在做视觉检测算法、设备调试、测量方案落地的人,也适合刚接手 Halcon 标定、需要按算子名反查参数含义的新手。手册是直译稿,读的时候要带着“参数单位、固定项、适用相机类型”三件事去对照,不能只抄参数序列。
2. 标定对象与数据模型:从校准板到 CalibDataID 的六步准备
标定不是把标定板拍几张图再点一下运行就完事。手册 6.2 和 6.3 把输入数据的准备拆得很细:先要有度量属性已知的校准对象,再把相机类型、初始内参、标定板描述、观测点和排除参数依次塞进一个标定数据模型,最后才轮到calibrate_cameras做优化。这个顺序反了,后面看到的 RMSE 再小也没有意义。我一般会把采集和标定分成两段:现场只负责按覆盖要求抓图并记录镜头、光圈、工作距离,回到工位再离线建模型、换参数重跑,避免在设备上反复试错。
2.1 两种校准板的差异与选型
手册里明确区分了六边形排列标记板和矩形排列标记板。六边形板的查找器图案是特殊六边形标记组,其中一些标记带点状孔,图像里至少看到一个查找器图案就能定位,不要求整块板完全可见;矩形板的查找器图案是外围框架加三角形角标记,板子必须在图像中完全可见,否则框架断了就找不到。这个差异直接决定现场怎么拍:视野窄、镜头工作距离短的时候,六边形板更容易上手;要做高精度、覆盖要求严格的标定,矩形板更稳,但每张图都要把板子完整收进去。
| 对比项 | 六边形排列标记板 | 矩形排列标记板 |
|---|---|---|
| 生成算子 | create_caltab | gen_caltab |
| 查找器图案 | 六边形标记组,部分带点状孔 | 外围框架加三角形角标记 |
| 图像中可见性 | 至少一个查找器可见,不必全板可见 | 标定板必须完全可见 |
| 最少图像数 | 至少 6 张,至少 4 张倾斜 | 至少 15 张 |
| 坐标系原点 | 第一个查找器中心标记的中心 | 标定板表面的中间 |
| 镜像检测 | 至少两个查找器可见时可检测镜像 | 依赖完整框架和角标记 |
坐标系定义也要注意:两种板都是 z 轴指向校准板,x 轴向右,y 轴向下,视线方向沿 z 轴。区别在于原点位置不同,六边形板原点在第一个查找器中心标记的中心,矩形板原点在板面中间。手眼标定、多相机标定里只要涉及世界坐标系换算,这个原点差异就会放大成外参偏差。还有一条容易翻车的限制:六边形板在camera_calibration流程里不适用,选算子之前先确认自己走的是calibrate_cameras还是旧算子链路,别把板子买错了再回头改方案。
2.2 从 create_calib_data 到 set_calib_data:六步表
手册 6.3 给的步骤是固定的,但每一步的参数落位需要对照相机类型和标定板描述。下面这张表是我按手册顺序整理的落地版,关键输入栏写的是实际调用时要盯住的参数,不是完整签名。
| 步骤 | 算子 | 关键输入 | 作用 |
|---|---|---|---|
| 1 | create_calib_data | 相机数量、标定对象数量 | 创建CalibDataID,后续所有数据都挂在这个句柄上 |
| 2 | set_calib_data_cam_param | CalibDataID、相机索引、相机类型字符串、初始内参 | 告诉优化器用哪种相机模型,初值从镜头和传感器规格来 |
| 3 | set_calib_data_calib_object | CalibDataID、标定对象索引、标定板描述 | 把标记点的 3D 世界坐标和查找器结构告诉标定模型 |
| 4 | find_calib_object或set_calib_data_observ_points | 相机索引、标定对象索引、姿态索引、图像坐标和粗略姿态 | 收集观测数据,自动提取或手动输入 |
| 5 | set_calib_data | 'camera'、相机索引、'excluded_settings'、排除参数列表 | 锁定已知参数,避免优化器乱动 |
| 6 | calibrate_cameras | CalibDataID | 执行优化,回写内参、外参、标准差、协方差和 RMSE |
第 2 步的相机类型字符串必须和镜头匹配。常规镜头用area_scan_division或area_scan_polynomial,物侧远心镜头用area_scan_telecentric_division或area_scan_telecentric_polynomial,倾斜镜头要用带tilt的类型。初始内参不是随便填:Focus填镜头标称焦距,单位是米,比如 0.008;Magnification填远心镜头标称放大倍率,图像尺寸除以物体尺寸;Kappa和多项式系数初值一般全 0;Cx、Cy用半图像宽高;Sx、Sy从相机传感器规格取。这里填错不会立刻报错,但优化会往错误方向收敛,最后 RMSE 看起来还行、边缘测量却对不上。
第 5 步的排除参数是很多人忽略的“后悔药”。手册举的例子是:如果相机 0 的图像传感器单元尺寸精确已知,只需要标定其余参数,就调用set_calib_data (CalibDataID, 'camera', 0, 'excluded_settings', ['sx','sy'])。实际项目里,远心镜头、线扫相机、倾斜镜头都有固定项,手册用星号标出来了,这些参数不该让优化器自由估计。把已知项锁死,剩下的参数才有可比性;全放开让算法自己猜,容易得到一组“数学上拟合、物理上解释不通”的参数。
2.3 观测数据采集:find_calib_object 与手动点输入
观测数据有两种进法。第一种是find_calib_object,它直接从图像里提取标定标记,同时给出标定板相对于观测相机的粗略姿态;第二种是set_calib_data_observ_points,适合标记点已经由外部算法提取出来,或者需要把已有坐标灌进标定模型的情况。自动提取省事,但对图像质量敏感:标记直径、对比度、过曝、光照均匀性不达标,提取出来的点会跳,后面 RMSE 再优化也救不回来。
find_calib_object调用时要给相机索引、标定对象索引和姿态索引。姿态索引不是图像序号,而是同一块标定板在某个姿态下的编号,多相机多姿态时要把这个索引和图像文件对应关系记清楚。手动输入set_calib_data_observ_points时,行坐标、列坐标、标记索引和粗略姿态都要给,粗略姿态可以来自find_caltab加find_marks_and_pose的组合,也可以来自机械臂或转台读数。手动输入的好处是可控,坏处是姿态初值不准会把优化带偏,所以宁可多花几分钟检查姿态方向,也不要直接把单位矩阵塞进去。
提示:标定板描述文件里的单位要和相机参数单位一致。手册默认长度单位是米,标定板描述、焦距、平移量都按米走;如果测量软件按毫米出结果,换算放在后处理,不要在标定模型里混着填。
3. 相机参数怎么填:内参、外参与单位的三张表
相机参数分内部参数和外部参数。内参描述传感器尺寸、镜头投影特性和畸变,外参描述世界坐标系相对于相机坐标系的位置和方向。手册 6.6 把面阵相机、线扫相机、远心镜头、倾斜镜头的参数序列列得很全,但真正落地时最容易错的是三件事:哪些参数带星号不能估、Sy为什么经常固定、线扫相机的Vx/Vy/Vz到底按什么单位给。把这三件事搞清楚,参数表才不是死记硬背。
3.1 面阵相机内参:division 与 polynomial 的字段差异
面阵相机的内参数量按相机类型在 9 到 16 个之间。常规镜头的投影面阵相机用area_scan_division时,参数序列是相机类型、Focus、Kappa、Sx、Sy、Cx、Cy、ImageWidth、ImageHeight;用area_scan_polynomial时,Kappa换成了K1、K2、K3、P1、P2五个畸变系数。division 模型用一个参数模拟径向畸变,polynomial 模型用三个径向项加两个离心项,精度上限更高,但对标定图像覆盖要求也更高。
| 相机类型 | 参数序列(节选) | 固定项 | 适用场景 |
|---|---|---|---|
area_scan_division | 类型、Focus、Kappa、Sx、Sy、Cx、Cy、宽、高 | Sy | 常规镜头,径向畸变为主 |
area_scan_polynomial | 类型、Focus、K1、K2、K3、P1、P2、Sx、Sy、Cx、Cy、宽、高 | Sy | 需要更准的径向加离心畸变建模 |
area_scan_telecentric_division | 类型、Magnification、Kappa、Sx、Sy、Cx、Cy、宽、高 | Sy | 物侧远心镜头 |
area_scan_tilt_division | 类型、Focus、Kappa、ImagePlaneDist、Tilt、Rot、Sx、Sy、Cx、Cy、宽、高 | Sy | 倾斜镜头,像侧透视投影 |
Sy固定不是偷懒。手册解释得很清楚:射影相机用针孔模型描述时,Focus、Sx、Sy不能同时确定,所以算法保持Sy不变;远心镜头同理,Magnification、Sx、Sy不能同时确定。倾斜镜头还有额外限制:像侧远心倾斜镜头无法同时确定Focus、Sx、Sy、Tilt、Rot,除了Sy还会保持Sx不变;双侧远心倾斜镜头无法同时确定Magnification、Sx、Sy、Tilt、Rot,同样保持Sx和Sy。这些星号项在手册参数列表里标得很细,填初始值时按传感器规格和机构读数给,别指望优化器帮你解。
Cx、Cy是图像主点,也是径向畸变中心,初始值用半图像宽高。这里有个子采样坑:如果图像做了次采样,Cx、Cy、ImageWidth、ImageHeight都会变小,Sx、Sy反而会增加。很多人拿全分辨率参数去标定半分辨率图,RMSE 看着不大,实际主点偏了半个像素以上。手册在参数说明里反复提醒“如果图像是次采样的话,这些值会增加/减小”,这不是废话,是现场换分辨率时最容易漏的一步。
3.2 线扫相机的 Vx/Vy/Vz:运动矢量单位是米/行
线扫相机的内参除了常规的Focus、Kappa、Sx、Sy、Cx、Cy、图像宽高,还多出Vx、Vy、Vz三个运动矢量分量,单位是米/行。线扫成像不是一张图一个视角,而是相机和物体相对匀速运动、每条图像线从不同位置采出来的,所以标定模型必须知道运动方向和速度。手册假设相机沿直线匀速移动、方向恒定、所有图像的运动相等,运动矢量描述相机运动,等价于固定相机、物体沿-V移动。
线扫相机的坐标系定义也跟面阵不一样:原点是投影中心(针孔)或畸变中心(远心),z 轴沿光轴,y 轴垂直于传感器线且运动矢量有正 y 分量,x 轴与 y、z 构成右手系。每条图像线都有单独姿态,但 Halcon 只基于第一条图像线的姿态做世界坐标到相机坐标的转换,find_calib_object算的也是第一条线的姿态。这个简化意味着Vx/Vy/Vz的初始值质量直接决定标定能不能成,手册原文说“对整个校准的成功至关重要,如果不够精确,校准可能会失败”。
常见做法是先让相机看起来垂直于传送带并绕光轴旋转,使传感器线垂直于传送带,相机系统 y 轴与传送带平行,这时Vx=Vz=0,Vy可以用已知尺寸的标定板或尺子在线扫图像里估。如果相机绕光轴转了 30 度,或者绕相机坐标系 x 轴转了 -20 度,运动矢量不能照抄上面的初值,要按旋转关系把运动方向转到相机坐标系再填。远心线扫相机还有一条硬限制:Vz对 3D 点的图像位置没有影响,所以Vz无法确定,优化时保留初始值,初始值应该设 0。把Vz当普通参数反复调,是线扫标定里典型的白费功夫。
3.3 外参 pose 与单位换算
外参是 6 个参数:TransX、TransY、TransZ描述沿相机坐标系 x、y、z 轴的平移,RotX、RotY、RotZ描述绕三个轴的旋转。pose 元组还多一个元素,编码OrderOfTransform、OrderOfRotation、ViewOfTransform的组合,具体含义要对照create_pose。使用标准标定板时,世界坐标系由标定板坐标系定义,六边形板原点在第一个查找器中心标记的中心,矩形板原点在板面中间;如果用手眼标定或外部3D点,世界坐标系就要按实际工装来设。
| 参数类别 | 典型单位 | 注意点 |
|---|---|---|
Focus、TransX、TransY、TransZ、ImagePlaneDist | 米 | 标定板描述文件单位要统一 |
Cx、Cy、ImageWidth、ImageHeight | 像素 | 子采样后按实际图像尺寸改 |
Kappa | 米^-2 | division 模型的径向畸变系数 |
Tilt、Rot | 度 | Tilt在 0 到 90 度,Rot在 0 到 360 度 |
Vx、Vy、Vz | 米/行 | 线扫相机运动矢量 |
远心镜头有一个容易误读的边界:标定板与相机之间的距离无法确定,所以标定板姿态的 z 分量在测量结果里被设为 1 米。这不是算法没算好,是远心投影本身不带深度信息。拿远心标定结果去做绝对 Z 向测量,数值一定对不上;需要 Z 向绝对距离时,得靠已知工作距离、机械定位或额外测距传感器。倾斜镜头的Tilt、Rot也不是越大越准,手册特别提醒:透镜畸变越大,Tilt越能准确确定;畸变小的镜头,Tilt可能无法确定,优化值会和标称值差很多。这时候别盯着角度数值吵架,先看回投误差能不能在标定体积内一致描述成像几何。
4. 实际标定与结果验收:calibrate_cameras 之后看什么
calibrate_cameras不是“跑完就完”的算子。它用标定数据模型里的所有信息优化初始内参,计算并回写外参、标准差、协方差,以及后投影的均方根误差。手册 6.5 说得很直接:RMSE 以像素为单位返回,对应后投影校准点与提取图像坐标之间的平均距离。单相机标定,0.1 像素左右的误差说明优化和观测数据拟合得好;差得远,原因可能是图像质量差、标定图像数量不足、标定板不准确。问题是,很多人只盯总 RMSE,不看误差分布,最后把“总误差小、局部误差大”的模型直接上线。
4.1 RMSE 0.1 像素不是万能及格线
0.1 像素是手册给单相机标定的一个典型参考值,不是跨项目通用的及格线。不同镜头、不同视场、不同标定板尺寸、不同标记直径,RMSE 的绝对数值没有直接可比性。一个 0.08 像素的模型,如果误差集中在图像四角,边缘测量照样超差;一个 0.3 像素的模型,如果重复性好、误差分布均匀,某些粗测量场景反而能用。验收时至少看三层:总 RMSE、单张图像的残差、按图像区域统计的残差。
单张残差能抓到“某几张图拍坏了”的问题。标定图像集里只要有一张标定板倾斜角度不对、标记模糊或者局部过曝,优化会把这张图的误差摊到所有参数上,总 RMSE 可能只涨一点,但外参已经偏了。按区域统计能抓到覆盖不足:标定板只覆盖画面中间,四角没有观测点,畸变模型在边缘就是外推,RMSE 再小也不能证明边缘准。手册在 6.7.2 里要求视场每个部分至少被标定板覆盖一次,这不是建议,是验收前提。
4.2 用 get_calib_data 取结果并做投影回验
calibrate_cameras跑完后,用get_calib_data按类别查询结果。我一般按“相机内参、标定板姿态、观测残差、模型整体误差”四类取,先看内参有没有跑到物理上不可能的值,再看每张图的姿态和残差,最后才看总 RMSE。投影回验的做法不复杂:把标定板上已知 3D 坐标的标记点,用优化后的内参和外参投影回图像,和实际提取的像素坐标算距离,按图像、按区域统计平均误差和最大误差。
| 查询类别 | 主要看什么 | 异常信号 |
|---|---|---|
| 相机内参 | Focus、Magnification、Kappa或多项式系数、Cx、Cy | 焦距为负、主点跑出图像、畸变系数数量级离谱 |
| 标定板姿态 | 每张图的平移和旋转 | 某张图姿态和机械读数差太多 |
| 观测残差 | 单张图、单个标记的投影误差 | 误差集中在某一张或某个角点 |
| 模型整体 | RMSE、标准差、协方差 | 总 RMSE 小但最大残差很大 |
如果误差集中在某个角点,先查镜头畸变和标定板平整度,不要急着换 polynomial 模型。多项式模型参数多,拟合能力强,但也更容易把标定板不平、图像噪声一起拟合进去,标定板覆盖区域之外反而可能更不准。手册明确说,多项式模型在校准板覆盖的区域之外可能不准确地模拟变形,图像边界和视场内未被覆盖的区域都算。回验时把标记点按 3×3 网格分组,看哪一格最大误差超限,比只看一个总数字有用得多。
4.3 畸变模型选 division 还是 polynomial
面阵相机有两种畸变模型:division 和 polynomial。division 用一个Kappa模拟径向畸变,优点是畸变应用快,特别是逆畸变,把世界坐标投影到图像平面时解析可逆;标定图像少、视场覆盖不充分时,division 通常比 polynomial 更稳定。polynomial 用K1、K2、K3模拟径向畸变,用P1、P2模拟离心畸变,精度上限更高,但不能解析反转,逆畸变要迭代算,速度慢,而且对覆盖要求更高。
| 对比项 | division 模型 | polynomial 模型 |
|---|---|---|
| 参数数量 | 1 个径向畸变参数 | 3 个径向加 2 个离心参数 |
| 逆畸变 | 解析可逆,速度快 | 迭代计算,速度慢 |
| 稳定性 | 少图、覆盖不足时更稳 | 需要更好的视场覆盖 |
| 适用场景 | 常规检测、先跑通链路 | 畸变复杂、division 残差有系统弯曲 |
我一般先用 division 跑一版,看回验残差有没有明显的系统性弯曲;如果残差随半径单调变化、四角误差压不下去,再换 polynomial,并且补拍覆盖四角和边界的图像。不要一上来就 polynomial,参数多不等于精度高,覆盖不够时它只是把噪声拟合得更漂亮。线扫相机还有一条边界:倾斜镜头目前不支持线扫相机,选型时别把面阵的倾斜镜头方案直接搬到线扫上。
5. 标定现场避坑:五条从图像质量到参数锁定的排查记录
标定翻车很少是某一个算子写错,更多是图像质量、覆盖、模型限制三件事叠在一起。下面五条是按“现象→原因→解决”整理的现场记录,每条都能在手册 6.5、6.7、6.9 里找到对应依据。遇到标定结果不对,先按这五条过一遍,比盲目换模型、换标定板更快。
5.1 现象:RMSE 0.4 像素,图像肉眼看着很干净
现象是标定图像在屏幕上看着很清楚,标记边缘也不糊,但calibrate_cameras返回的 RMSE 到了 0.4 像素,换几张图重跑也差不多。原因通常不是“算法不行”,而是图像不满足标记提取的量化条件:标记直径小于 20 像素、明暗区域对比度低于 100 灰度值、浅色部分灰度超过 240 导致过曝、标定板光照不均使浅色区域灰度范围超过 45。人眼觉得清楚,是因为屏幕缩放和对比度增强;算法看的是标记边缘的梯度,标记一小、一糊、一过曝,提取坐标就会跳。
解决方法是回到采集端,不要在后处理里硬调。先把标记直径拍到至少 20 像素,再检查曝光:浅色部分灰度不要超过 240,尤其标记附近不能过曝;然后看对比度,明暗区域至少差 100 灰度值;最后看均匀性,标定板浅色部分的灰度范围不要超过 45。现场光照不均时,宁可加漫射板、调光源角度,也不要靠后期拉对比度。手册把这些值写在 6.7.2 里,是因为它们直接决定标记提取的重复性,RMSE 只是结果。
5.2 现象:标定板只拍中间区域,边缘测量不准
现象是标定 RMSE 只有 0.12 像素,看着不错,但一测画面边缘的工件,尺寸就偏,换到中间又正常。原因很直接:标定图像集只覆盖了视场中间,四角和边界没有观测点,畸变模型在边缘靠外推,RMSE 只统计了有标记的区域,自然看不出边缘问题。手册要求一组校准图像内视场每个部分至少被标定板覆盖一次,六边形板至少 6 张、其中至少 4 张倾斜,矩形板至少 15 张,倾斜角度约 30 到 45 度,目的就是让畸变模型在整個视场内有约束。
解决方法是重拍覆盖图,不是加几张中间区域的图凑数。把标定板分别放到左上、右上、左下、右下和中心,每个区域至少覆盖一次;倾斜方向也要变,不要所有图都朝同一个方向斜。六边形板不要求每张全可见,但至少一个查找器要可见,至少两个查找器可见时还能检测镜像;矩形板必须整板可见,拍的时候留边,别让框架出画。覆盖够了再跑标定,边缘残差才有意义。
5.3 现象:远心镜头标定后 Z 值始终是 1 米
现象是远心镜头标定完,查标定板姿态,z 分量总是 1 米,换工作距离、换图像都一样,于是怀疑标定失败。原因是远心投影本身不带深度信息,标定板与相机之间的距离无法确定,手册 6.9 明确说远心镜头下标定板姿态的 z 分量在测量结果中被设为 1 米。这不是优化没收敛,是模型的可观测性问题;远心镜头只能确定横向比例和畸变,不能从图像里解出绝对物距。
解决方法是不要在远心标定结果里找绝对 Z。需要 Z 向距离时,用已知工作距离、机械定位面或额外测距传感器;标定结果只用来做横向测量和畸变校正。如果项目必须做三维测量,选型阶段就要确认用针孔相机、线扫相机还是其他带深度约束的方案,别等标定做完才发现 Z 不可测。手册把这条写在“与特定相机类型相关的进一步限制”里,属于选型前就该读到的边界。
5.4 现象:线扫图像接缝错位,Vz 怎么调都不对
现象是线扫相机标定后,拼接图像有接缝错位,调Vz初始值、放开优化都不见效,甚至越调越差。原因有两个:远心线扫相机的Vz对 3D 点的图像位置没有影响,无法确定,优化时保留初始值,应该设 0;真正影响标定的是Vx、Vy的初始值质量,以及相机是否绕光轴旋转、传感器线是否垂直于传送带。手册说Vx/Vy/Vz初始值对整个校准成功至关重要,不够精确校准可能失败。
解决方法是先把运动矢量初值算对,再谈优化。让相机看起来垂直于传送带并绕光轴旋转,使传感器线垂直于传送带、相机 y 轴与传送带平行,此时Vx=Vz=0,Vy用已知尺寸的标定板或尺子在线扫图像里估;如果相机绕光轴转了 30 度或绕 x 轴转了 -20 度,按旋转关系把运动方向转到相机坐标系再填。远心线扫把Vz固定为 0,不要在这个参数上反复试。线扫每条图像线都有单独姿态,但 Halcon 只存第一条线的姿态,所以第一行的运动方向尤其要准。
5.5 现象:倾斜镜头 Tilt/Rot 优化后和铭牌差很多
现象是倾斜镜头标定后,Tilt、Rot的优化值和镜头机构铭牌或读数差了好几度,于是怀疑标定参数错了。原因是手册 6.9 的提醒:TILT 透镜畸变越大,Tilt越能准确确定;畸变较小的透镜,Tilt无法确定,优化后的Tilt参数可能和设定的标称值差很多。这不是优化器乱跑,是参数可观测性不足,角度和畸变在小畸变条件下互相补偿,数学上都能拟合观测数据。
解决方法是先看误差,不要先看角度数值。如果 RMSE 很小、投影回验在标定体积内一致,说明这组参数能一致描述成像几何,可以用于测量;如果回验误差大,再检查标定板覆盖、倾斜角度是否够、ImagePlaneDist初值是否合理。机构读数可靠时可以锁死Tilt、Rot再优化其余参数,但锁之前要确认镜头确实按标称角度安装。倾斜镜头的参数玄学感很强,血泪经验是:别拿角度数值和铭牌对账,拿回投误差和实际测量结果对账。
6. 标定结果落地:把参数固化、回验和复标条件写进流程
标定结果最怕“调完就忘”。我一般把内参、外参、RMSE、标定图像集、镜头型号、光圈值、工作距离写进一个版本记录,和视觉检测算法的参数文件分开存。每次换镜头、动光圈、动焦距、设备碰撞、温度剧变,或者测量结果连续超差,都触发复标,不靠记忆判断。复标不是重跑一遍calibrate_cameras就完事,要先拍覆盖图,再看单张残差,最后才改算法参数。这个顺序反过来,很容易把标定问题误判成算法问题。
6.1 用反投影误差分布看区域精度
把标定板标记点按图像 3×3 网格分组,统计每格的平均投影误差和最大误差,比只看总 RMSE 更能定位问题。中间格误差小而四角格误差大,说明覆盖不足或畸变模型外推;某一格突然变大,查该区域是否有反光、遮挡或标定板不平。这个表可以直接贴到调试记录里,下次复标时对比同一区域的误差变化。
| 区域 | 平均误差(像素) | 最大误差(像素) | 处理建议 |
|---|---|---|---|
| 中心 | 0.08 | 0.12 | 正常 |
| 左上 | 0.11 | 0.18 | 补拍该区域覆盖图 |
| 右下 | 0.23 | 0.41 | 查反光或标定板平整度 |
6.2 手眼标定前先锁内参
手眼标定把相机和机器人坐标系绑在一起,内参不稳,手眼结果一定漂。我的习惯是先做单相机标定,把Sx、Sy等已知项用set_calib_data排除,确认 RMSE 和回验通过后,再把内参固定,只优化手眼关系。内参和外参一起放开,优化器会用外参补偿内参误差,最后手眼矩阵看着能拟合,换一个姿态就偏。手册在标定数据模型那一步就给了排除参数的入口,别等到手眼结果不对才回头找。
6.3 标定文件版本化与复标触发条件
版本记录至少包含:标定日期、镜头和相机标识、光圈值、工作距离、标定板类型、图像数量、RMSE、复标触发原因。复标触发条件写进设备点检表:换镜头、动光圈、动焦距、碰撞、温度剧变、测量超差连续出现。标定文件按“相机编号_日期_版本”命名,和视觉检测算法的参数文件分开,避免一次误覆盖把旧模型冲掉。
从那以后我每次换镜头后都强制走一遍:先拍覆盖图,再看单张残差,最后才改算法参数。希望帮到你。
本文还有配套的精品资源,点击获取