标定板设计:选对板子,标定就成功了一半

说实话,标定板这东西,看着简单,坑却不少。我见过太多项目,算法调了半天,最后发现是标定板本身有问题。这一章,咱们就把标定板的类型选择和描述文件生成讲透。

圆点标定板 vs 棋盘格标定板

HALCON 支持两种主流标定板:圆点阵列和棋盘格。很多人问我哪个更好,我的回答是——看场景。

对比维度 圆点标定板 棋盘格标定板
特征提取 圆心亚像素精度高,抗噪能力强 角点提取速度快,但对模糊敏感
适用场景 高精度测量、远距离、大视场 近距、小视场、实时性要求高
光照鲁棒性 圆形轮廓对光照变化不敏感 棋盘格边缘易受反光影响
标定板制作 需要高精度打印,中心定位要求严 普通打印即可,角点位置天然准确
HALCON 算子 find_caltab + find_marks_and_pose find_chessboard + find_corners_chessboard
我的经验: 如果项目要求重复精度在 0.01mm 以内,我首选圆点板。如果是做机器人手眼标定,棋盘格更方便,因为角点数量多,标定结果更稳定。

标定板描述文件(.descr)到底是什么?

说白了,.descr 文件就是标定板的「身份证」。它告诉 HALCON:你的板子长什么样、圆点多大、间距多少、排列方式如何。没有这个文件,HALCON 根本不知道你在拍什么。

文件内容其实是个文本,结构清晰。我拆开给你看:

# 圆点标定板描述文件示例
# 文件编码:UTF-8

calibration_object_type = 'calibration_object'
calibration_object_name = 'my_caltab_30mm'

# 标定板参数
num_marks = 7          # 每行/列圆点数量
mark_distance = 0.03   # 圆点间距(米)
mark_diameter = 0.015  # 圆点直径(米)

# 排列方式
pattern_type = 'circular'  # 圆点阵列
pattern_rows = 7
pattern_cols = 7

# 坐标系定义
coordinate_system = 'world'
origin = 'center'      # 原点在标定板中心
注意: 所有长度单位都是米!我见过有人写成毫米,结果标定出来的内参完全不对,折腾了两天才找到原因。

如何生成 .descr 文件?

HALCON 提供了两种方式,我分别说说。

方式一:使用 HALCON 自带工具 gen_caltab

这是最推荐的方式。打开 HALCON 的 HDevelop,运行以下代码:

* 生成圆点标定板描述文件
gen_caltab(
    7,           // X方向圆点数量
    7,           // Y方向圆点数量
    0.03,        // 圆点间距(米)
    0.5,         // 圆点直径与间距的比值
    'caltab_30mm.descr',  // 输出描述文件
    'caltab_30mm.ps'      // 输出打印文件(PostScript)
)

运行后,你会得到两个文件:

  • .descr 文件:给 HALCON 读的标定板参数
  • .ps 文件:打印用的矢量图,直接发给印刷厂
避坑指南: 我曾经直接用普通打印机打标定板,结果纸张受潮变形,标定精度直接崩了。后来我都是找专业印刷厂,用菲林片或铝基板制作,热膨胀系数小,精度才有保障。

方式二:手动编写 .descr 文件

如果你需要自定义标定板(比如非标准排列、异形板),可以手动写。但我不建议新手这么做,格式要求很严格,少一个字段 HALCON 就报错。

手动编写时,必须包含以下字段:

字段名 说明 示例值
calibration_object_type 对象类型,固定值 'calibration_object'
num_marks 每行/列圆点数量 7
mark_distance 圆点间距(米) 0.03
mark_diameter 圆点直径(米) 0.015
pattern_type 排列类型 'circular' 或 'chessboard'
coordinate_system 坐标系 'world'

标定板设计核心流程

下面这张图,是我做项目时脑子里始终绷着的一根弦——标定板设计不是随便画几个点就完事的。

标定板设计核心流程 1. 需求分析 2. 选择标定板类型 3. 确定物理参数 4. 生成 .descr 文件 5. 制作物理标定板 关键:标定板物理尺寸必须与 .descr 文件完全一致,否则标定结果全是错的

参数设计的关键原则

我总结了几条铁律,照着做基本不会翻车:

  1. 圆点数量:7×7 或 9×9 最常用。太少标定精度不够,太多容易拍到不完整的板子。
  2. 圆点直径 = 间距 × 0.4~0.6。太大会粘连,太小提取不到。
  3. 标定板尺寸占视场的 1/3~2/3。太小了特征点不够,太大了边缘畸变严重。
  4. 背景用白色,圆点用黑色。对比度高,提取稳定。

实际案例: 去年做一个 500 万像素的视觉定位项目,客户自己做了个 5×5 的圆点板,间距 10mm。结果标定出来的畸变系数波动很大。我换成 7×7、间距 30mm 的板子,一次就过了。说白了,特征点数量不够,算法再牛也救不了。

棋盘格标定板的特殊之处

棋盘格和圆点板最大的区别在于:棋盘格不需要知道角点的物理直径,只需要知道格子边长。这听起来省事,但有个坑——棋盘格的角点对图像模糊非常敏感。

我做过对比测试:同样的镜头,棋盘格标定出来的焦距波动在 ±0.5%,而圆点板只有 ±0.1%。所以,如果你的项目对精度要求极高,别偷懒,用圆点板。

棋盘格的 .descr 文件生成方式类似:

* 生成棋盘格标定板描述文件
gen_chessboard_calibration_object(
    8,           // 内角点行数
    6,           // 内角点列数
    0.025,       // 格子边长(米)
    'chessboard_25mm.descr',
    'chessboard_25mm.ps'
)
注意: 棋盘格的 num_corners 是内角点数量,不是格子数量。比如 8×6 的棋盘格,实际有 9×7 个格子。这个搞反了,标定出来的结果会完全错位。

总结一下

标定板设计,说白了就是三个字:准、稳、对。准——物理尺寸要准;稳——特征提取要稳;对——描述文件参数要对。这三条做到了,标定就成功了一半。

嗯,这一章就到这里。记住,别在标定板上省钱,它决定了你整个视觉系统的精度上限。