4. 报错 2:find_calib_object 找到错误数量的标记点

这个报错,说白了就是 HALCON 在标定板图片里数错了圆点个数。你明明放的是 7×7 的标定板,它却告诉你只找到了 30 个点,或者突然多出来几个。我刚开始接触 HALCON 标定时,被这个问题卡了整整一个下午,后来才发现是车间灯光太强,把背景上的螺丝孔也当成标记点了。

核心现象:find_calib_object 返回的标记点数量与标定板实际编码点数量不一致,导致标定流程中断或生成错误的内参。

4.1 原因一:标记点提取阈值不当

这是最常见的原因,没有之一。HALCON 在找圆点时,会先根据图像灰度把候选区域分离出来。如果阈值设得太低,背景上的噪点、污渍都会被当成圆点;阈值设得太高,真正的标记点反而被过滤掉了。

我个人习惯把这个问题分成两类来看:

  • 阈值过低(mark_thresh 太小)——图像中任何比背景稍亮的区域都会被识别,结果就是找到一堆假点。我在一个反光严重的金属件检测项目里遇到过,阈值设成 30,结果 HALCON 把工件边缘的高光也当成了标定板圆点,数出来 80 多个。
  • 阈值过高(mark_thresh 太大)——只有极亮的区域才能通过,标定板上灰度正常的圆点反而被丢弃。特别是当标定板有些脏污或光照不均匀时,部分圆点灰度偏低,很容易被漏掉。
参数 作用 典型值范围 调大后果 调小后果
mark_thresh 标记点灰度阈值 30 ~ 120 漏掉真实点 引入大量假点
mark_size 标记点直径(像素) 10 ~ 50 过滤掉小圆点 把大块污渍当圆点
我的调试技巧:先用 inspect_calib_object 看一眼候选区域。如果 HALCON 画出的轮廓明显比实际圆点多,那就是阈值低了;如果轮廓残缺不全,那就是阈值高了。这个函数我几乎每次标定都会用,比肉眼猜靠谱得多。

4.2 原因二:标定板污损

标定板用久了,难免会沾上指纹、油污或者灰尘。这些污渍在图像里会形成额外的灰度变化,HALCON 很容易把它们当成标记点。我记得有一次在产线上做在线标定,操作员的手印印在了标定板边缘,结果 HALCON 每次都在那个位置多找到一个点。

污损带来的问题通常有两种表现:

  • 多出假点——污渍的灰度刚好落在阈值范围内,被当成圆点提取出来。
  • 遮挡真点——油污覆盖了部分标记点,导致该点无法被识别,数量变少。

你想想看,标定板上的圆点间距是固定的,HALCON 会按这个间距去校验。如果某个位置因为污损导致圆点缺失,整个空间关系就对不上了,报错是必然的。

4.3 原因三:反光干扰

这个坑在金属件或玻璃件检测中特别常见。标定板表面如果有反光,会在图像中形成高光区域。这些高光的形状和大小有时候跟圆点非常像,HALCON 根本分不清。

我做过一个手机玻璃盖板的项目,标定板放在玻璃旁边,结果玻璃的反光直接投射到标定板上,图像里多出来好几个亮斑。HALCON 数点的时候把这些亮斑也算进去了,报错信息显示找到 54 个点,而标定板明明是 7×7=49 个点。

注意:反光导致的假点通常出现在标定板的边缘或角落,因为那里更容易受到环境光的影响。如果你发现多出来的点总是集中在某个区域,先检查一下那个方向有没有强光源或反射面。

4.4 解决方案

4.4.1 调整 mark_size 和 mark_thresh 参数

这两个参数是解决阈值问题的核心手段。我的做法是:

  1. 先用默认值试跑一次——通常 mark_thresh 设为 60,mark_size 设为 20。看看报错信息里找到的点是多了还是少了。
  2. 多了就提高阈值——如果找到的点比实际多,把 mark_thresh 往上调 10~20,直到假点消失。
  3. 少了就降低阈值——如果找到的点比实际少,把 mark_thresh 往下调 10~20,同时检查 mark_size 是否匹配实际圆点直径。
* 调整参数示例
create_calib_data ('calibration_object', 1, 1, CalibDataID)
set_calib_data_calib_object (CalibDataID, 0, 'caltab_7x7.descr')
* 设置标记点提取参数
set_calib_data_param (CalibDataID, 'calib_object', 'mark_thresh', 45)
set_calib_data_param (CalibDataID, 'calib_object', 'mark_size', 18)
* 执行查找
find_calib_object (Image, CalibDataID, 0, 0, 0, [])
经验值参考:在均匀光照下,mark_thresh 设在 40~60 之间通常能稳定工作。如果现场光照变化大,我建议用 auto_threshold 先做一次自适应阈值,再根据结果手动微调。

4.4.2 清洁标定板

这个听起来简单,但很多人会忽略。标定板上的指纹和油污,用干净的镜头布轻轻擦拭就能解决。我建议每次标定前都做一次清洁,特别是多人共用的标定板。

  • 日常清洁:用无尘布蘸少量无水乙醇,从中心向外螺旋擦拭。
  • 深度清洁:如果标定板上有顽固污渍,可以用超声波清洗机,但要注意不要损坏表面涂层。
  • 存放:标定板用完后放回保护盒,避免暴露在灰尘环境中。

4.4.3 改善光照条件

反光问题,最直接的解决办法是改变光源角度。我一般会用漫射光源或者加装偏振片,把镜面反射变成漫反射。如果条件不允许,调整相机和光源的相对位置也能缓解。

快速验证方法:用手遮挡一下可疑的反光源,看看图像中多出来的亮斑是否消失。如果是,那就说明反光是罪魁祸首。

4.5 知识结构图

下面这张图梳理了 find_calib_object 找到错误数量标记点的完整排查逻辑,你可以对照自己的报错现象快速定位原因。

find_calib_object 标记点数量错误排查流程图 标记点数量 ≠ 预期值 阈值不当 标定板污损 反光干扰 点过多:阈值过低 点过少:阈值过高 多出假点或遮挡真点 污渍灰度接近圆点 高光区域被识别为圆点 多出现在标定板边缘 解决方案 调整 mark_thresh 点多调高,点少调低 配合 mark_size 微调 清洁标定板 无尘布 + 无水乙醇 定期清洁,妥善存放 改善光照 漫射光源 / 偏振片 调整光源角度 验证:重新运行 find_calib_object

4.6 避坑指南

最后分享几个我踩过的坑,希望能帮你少走弯路:

  • 不要只调一个参数——mark_thresh 和 mark_size 是联动的。调了阈值后,记得检查 mark_size 是否还匹配实际圆点直径。我曾经只调了阈值,结果圆点大小不对,折腾了半天才发现问题。
  • 标定板不要用手直接摸——手上的油脂很难彻底擦干净,而且会越擦越花。我后来养成了戴手套拿标定板的习惯,污损问题少了很多。
  • 反光问题别只靠软件——虽然可以调阈值来过滤高光,但这样可能会牺牲正常点的提取率。物理上改善光照才是治本的办法。
重要提醒:如果以上方法都试过了还是报错,建议用 gen_caltab 重新生成一份描述文件,有时候描述文件与标定板不匹配也会导致点数错误。这个我在第 7 章会详细讲。