HALCON 深度学习目标检测实战:数据标注、训练与评估全流程指南
2026/9/15 15:56:30 网站建设 项目流程

最近一个装配件外观缺陷检测项目,让我真正把 HALCON 的深度学习目标检测从“了解”推进到了“真刀真枪用”的阶段。接触之前,我也以为深度学习目标检测就是 PyTorch 加 YOLO 的事,但实际落地时才发现,标注工具、数据集格式、训练接口、部署授权,每一环都有坑。HALCON 虽然有自己的固执之处,但它在传统视觉和深度学习之间搭了一座很实的桥,尤其对于我这种主攻视觉应用、不打算维护一套训练框架的团队来说,闭环优势非常明显。

这篇笔记(一)先把环境安装、数据标注、训练评估的完整链路记录下来。内容覆盖我从零开始跑通 HALCON 目标检测的全过程,包括选型理由、安装授权、标注规范、训练参数、日志读法,以及第一次训练时踩进去的坑。如果你正准备用 HALCON 做目标检测,或者已经在传统视觉里挣扎了很久想转深度学习,这篇应该能帮你省下不少时间。

1. 为什么最终选了 HALCON:不是图省事,而是闭环短

1.1 传统视觉方案在哪些场景下被目标检测取代

先说项目背景。产线上要检测一个装配件上的多个部件是否齐全,包括螺丝、垫片、线缆连接器。这些部件的位置并不完全固定,因为来料本身有公差,装配过程中会有轻微偏移;同时产品还有好几个型号,每个型号的部件布局都不一样。

如果按传统思路做,最直接的办法是模板匹配加 Blob 分析。光源条件好、产品位置固定的时候,这套方案确实好用。但问题在于:换一个型号就要重新抓模板、重新调 ROI、重新写定位逻辑;一旦光照发生变化、背景出现干扰,匹配分数就开始飘。整个项目的维护成本大部分都耗在了这里。

深度学习目标检测的思路完全不同。我不需要告诉模型“螺丝长什么样”的具体灰度特征,只需要给一堆标注过的图片,让模型自己学出“螺丝”和“背景”的边界。面对多型号、多姿态、复杂背景这些情况,泛化能力比传统方案强很多。特别是缺陷形态不固定、目标本身有轻微形变的场景,深度学习的优势是压倒性的。

1.2 HALCON 相比纯开源训练方案的闭环优势

既然要做深度学习目标检测,为什么不直接用 PyTorch 加 YOLO?这是大部分人第一个会问的问题。我的取舍逻辑很简单:项目要的是“在最短时间内把检测能力集成到上位机里”,而不是“训练出一个 SOTA 模型”。

用 PyTorch 的话,训练阶段确实自由度高,但部署阶段的工程量不低。需要把模型转 ONNX,再写推理代码,处理预处理、后处理、NMS 这些逻辑。如果产线工控机环境复杂,还要考虑 CUDA 版本、推理框架的兼容性,以及和现有视觉系统的数据交换。整套下来,没两三周搞不定。

HALCON 把这些环节都封装成了算子。训练好的模型用write_dl_model保存成一个.hdl文件,现场部署时read_dl_model加载,再用apply_dl_model直接出检测结果,预处理、NMS 这些后处理逻辑全部内置。HDevelop 里调通之后,还能直接导出 C# / C++ 代码,和现有的上位机无缝衔接。

对于一个以视觉应用为主、不以算法研究为核心的团队来说,这个闭环的吸引力非常大。我不需要额外维护一套深度学习工程,只需要关注数据和业务逻辑。

1.3 这篇笔记适合谁读

如果你是以下几种情况,这篇笔记的参考价值最大:一是已经在用 HALCON 做传统视觉,遇到复杂识别需求,想往深度学习方向转;二是刚接触 HALCON 深度学习,被官方的各种工具、参数、术语搞得一头雾水;三是公司有 HALCON 授权,做项目时不想再引入一整套开源深度学习技术栈。

反过来,如果你已经有成熟的 PyTorch 训练平台,或者有专门算法工程师,那直接用开源方案即可,不需要绕到 HALCON 上来。

2. 环境准备实录:从下载到授权再到 GPU 验证

2.1 版本选择与安装包下载的细节

HALCON 的深度学习模块不是一开始就好用的。我印象里 19.11 之前的版本,深度学习部分主要集中在分类,目标检测能力还不完整。到 19.11 之后才真正把目标检测带进了正式功能。我自己用的是 20.11 这个版本,整体已经比较稳定,网上能查到的资料也相对多。

下载的时候有个容易忽略的地方:光装 HALCON 本体不够,深度学习工具要单独下载。MVTec 官网的下载页面里,除了主安装包,还有一个 Deep Learning Tool,里面包含了数据标注和模型管理相关的工具,这个必须一起下载安装。另外,官方预训练模型也在官网的 Deep Learning Model Zoo 区域,按需下载。

安装时有一个经验:安装路径不要带中文和空格,否则后面跑训练时可能出现比较玄学的报错。虽然不一定每次都触发,但没必要冒这个风险。

2.2 License 的授权范围:开发版和运行版的差异

License 这块是新手最容易卡住的环节。HALCON 的授权分几种,开发用的 Developer License 和部署用的 Runtime License 里,深度学习相关 feature 并不是默认都带的。开发阶段我直接用官方试用 License,申请下来之后一个月内可以用完整功能,先把项目跑通最重要。

有一个非常典型的坑:训练正常,但部署到客户现场时,Runtime License 里没有包含目标检测的 feature,程序跑起来直接报错。所以采购授权的时候,一定要和供应商确认是否包含 Deep Learning / Object Detection 模块。这个确认动作放在项目启动前,比放在上线前再处理要省心得多。

GPU 方面,HALCON 深度学习对显卡有要求,官方一般要求 NVIDIA 显卡,且算力不能太低。我用的是一块 6GB 显存的卡,训练小模型勉强够用。如果数据量再大一些,建议直接上 8GB 或更高显存的显卡。显存不足的后果不是简单地报错,有时是整个训练过程卡死,特别难排查。

2.3 安装完成之后建议立刻做的三件事

第一件事,确认 HALCON 能识别 GPU。最简单的方法不是去看各种系统参数,而是直接打开 HDevelop 自带的深度学习示例,挑一个目标检测的 demo,跑一次推理。如果能正常出结果,说明环境基本没问题。如果这一步就跑不通,后面都是白折腾。

第二件事,把 HALCON 的 bin 目录加入系统 PATH 环境变量。这一步现在看着没什么用,但等后面写 C# 调用时,如果 DLL 找不到,报错会非常隐蔽。提前做好,后面省事。

第三件事,把预训练权重提前下载好。HALCON 下载模型的机制和 PyTorch 很像,第一次跑会自动下载,但在国内网络环境下经常很慢,甚至直接失败。我提前准备好官方权重文件放到本地,再把环境变量或模型路径指过去,训练启动就非常顺。

3. 标注环节:最耗时也最影响模型上限

3.1 图像采集的数量、命名与质量要求

标注是整个深度学习目标检测流程里最耗时的一步,但也是决定模型上限的一步。模型效果不好,大部分时候不是网络结构的问题,而是数据量和标注质量的问题。

先说图像数量。我的经验是,每一类目标至少要有 200 到 500 个独立的目标框。如果场景单一、变化小,200 个框也能跑出一个能用的模型;但如果目标形态复杂、光照变化大,500 个框只是起点。宁可少跑几轮实验,也要先把数据量做足。

命名规范也要提前想好。我习惯用“日期_型号_序号”这种格式,比如20240601_A_model_001.png。千万不要用中文文件名或带空格的命名,后续跑脚本、写代码处理数据时非常容易出问题。

图像内容要尽量覆盖真实场景中的各种变化。同一个产品,至少要有不同光照、不同角度、不同距离的样本。如果目标是装配件上的螺丝,那么“装好的”和“漏装的”都要拍,“装歪的”也要拍。要是只拍理想状态下的图,模型到现场立刻暴露问题。

小目标检测是工业场景里绕不开的痛点。如果目标在整幅图里只占很小一块,直接缩放训练会对小目标很不友好。这时有两个思路:一是提高输入分辨率,把整幅图放大后再训练;二是做 patch 切图,把大图切成多块小图,再对包含目标的小图进行标注和训练。后者的效果通常更好,但标注工作量也会相应增加。

3.2 标注工具对比:HALCON 自带工具、CVAT、LabelImg

图像准备好之后,下一个问题是“用什么工具标注”。标注工具的选择会直接影响数据流转的效率。我整理了三种常用方案的对比:

工具优势劣势适用场景
HALCON 自带 DL Tools与 HALCON 数据集格式无缝衔接,不需要写转换脚本界面功能相对朴素,多人协作困难个人或小团队,追求链路最短
CVATWeb 端多人协同,支持半自动标注、自动插值,可导出 COCO / VOC 格式需要部署环境,导出后还要写脚本转成 HALCON 格式有独立标注员,数据量较大
LabelImg轻量级,操作简单,导出 VOC / YOLO 格式功能比较少,同样需要格式转换数据量不大,临时标注用

我自己第一轮标注用的是 LabelImg,因为我熟悉它的操作习惯,标起来快。但后来发现,导入 HALCON 时要写转换脚本,把 VOC 格式的 XML 转成 HALCON 能读的标注结构,虽然不难,但多了一步就多了一个出错的可能。第二轮开始我改用 HALCON 自带的 DL Tools 标注,直接生成数据集,链路最简单。

如果你和团队配合,数据量大且需要多人同步标注,CVAT 是最合适的。它支持多人同时标注、任务分配和自动标注辅助,效率比单人工具高很多。只是要注意,CVAT 导出的 COCO 格式和 HALCON 之间需要一个转换脚本,这个脚本要提前写好并验证。

3.3 我的标注规范:四个反复强调的原则

不管用哪个工具,标注规范如果不统一,后面训练出来的模型一定会有问题。以下四条是我在实际项目里反复强调的:

第一,标注框要紧贴目标边缘,不要留大块背景。目标检测输出的是矩形框,框越大,里面包含的背景就越多,模型学着学着就会把背景也当成目标的一部分,定位自然不准。这个道理说起来简单,但人一累、目标一多,框画得就比较随意。

第二,关于遮挡和边缘截断的目标,要么标可见部分,要么直接过滤。如果目标被遮挡了一部分,标注完整框会引入大量非目标区域;只标可见部分,模型学到的是实际能看到的内容。如果这类样本占比很小,干脆先过滤掉,避免干扰模型。

第三,类别不能太碎。同一个目标,在外观上可能有不同颜色或不同角度,但只要它在业务上属于同一类,就一定要用同一个标签。有人习惯把不同颜色的同一种部件标成不同类别,结果类别爆炸,每个类别样本数量都不足,效果反而更差。

第四,漏标是最大的危害。漏标的目标会被模型当成背景,学出来的结果是“明明在那里却检测不到”。误标最多是学歪,漏标则直接教错。第一轮标注完成后,我建议找另一个人抽查,抽检率不低于 10%,重点看有没有漏掉小目标。

3.4 数据集划分:信息泄漏是最隐蔽的错误

标注完成之后,要把数据集划分成训练集、验证集和测试集。HALCON 的 DLDataset 里可以设置划分比例,参考标准是训练集 70%~80%,验证集 10%~20%,测试集 10%。

有一个很容易被忽略的问题:信息泄漏。划分数据集时要按照图像为单位来划分,不能按目标框为单位划分。同一张图上的多个目标框,如果一部分进了训练集,一部分进了验证集,那么训练时模型已经见过这些目标位置附近的特征了,验证指标的参考价值就会大打折扣。所以正确做法是按图像文件名随机划分,保证同一张图的全部目标框都归入同一集合。

测试集只能用来做最终评估,不能参与调参。HALCON 训练过程中的 early stopping 会参考验证集的指标,如果测试集和验证集没有严格分开,最后评估出来的指标会偏乐观,部署到现场就会发现差距。

4. 训练之前必查的五个检查点

4.1 模型创建与预训练权重加载

数据准备好之后,先别急着训练。创建模型时,HALCON 并不需要你自己搭网络,用深度学习的相关接口直接创建目标检测模型即可。这里最关键的一点是:是否进入了预训练权重。

预训练权重的价值非常大。工业场景下,数据量通常不会特别大,从零训练一个检测网络很容易欠拟合;而加载官方在大型数据集上预训练好的权重,再在自己的数据上微调,收敛速度快,最终精度也高得多。我第一次跑的时候没有确认权重是否真正加载成功,只看代码路径没报错就开始了,结果训练到十几个 epoch 时 loss 还下不去,回头检查才发现权重文件路径写错,模型实际上是从零开始训练的。这个浪费非常可惜。

4.2 预处理参数:分辨率、通道与增广

HALCON 的预处理阶段需要设置输入网络的图像尺寸。这个参数直接影响训练效果和速度。

如果原图分辨率很高,而目标本身又比较小,那么输入尺寸不能降得太狠。比如 1920×1080 的原图缩到 512×512,一个原本只有 20×20 像素的小螺丝,缩完之后只剩 5×5 像素左右,特征基本就丢了。反过来,如果把输入尺寸设得很大,显存占用和训练时间会成倍增加。

增广参数方面,HALCON 支持镜像翻转、旋转等基础操作。工业场景下,水平镜像通常是安全的,垂直翻转就要看目标语义了。比如螺丝、垫片这类对称部件,翻转影响不大;但如果有方向性要求的部件,翻转就会把语义搞乱。增广能提升泛化能力,但一定要结合业务场景判断是否合理。

4.3 训练超参数的起点值

超参数设置是另一个容易迷茫的地方。HALCON 的深度学习和主流框架类似,核心超参数就是学习率、动量、权重衰减、批大小和训练轮数。

我的起点一般是这样:学习率 1e-4 到 1e-3 之间,先用 1e-4 稳一点;动量 0.9,这是通用值;权重衰减 1e-4 到 5e-4;批大小从 2、4 开始试,主要受显存限制。训练轮数先设 20 到 50,目的是先把链路跑通,再根据验证集表现决定是否加轮数。

有一点要知道:HALCON 里的 loss 数值和 PyTorch 里看到的 loss 量级不一定一样,不需要追求某个人为设定的理想最小值。只要 train loss 在整体趋势上平滑下降,就说明模型在学习。

4.4 可视化数据集:训练前的人工校验

训练之前,必须做一件事:把标注框可视化到原图上,人工检查一遍。很多人调完参数直接开训,跑完才发现标注坐标错位、类别名写错、数据集划分有问题,白等了几十个小时。

HALCON 提供了显示检测结果的例程,可以把图片、标注框、类别标签一起画出来,翻页浏览。这一步确实要花时间,但值得做。我一般会盯着看三类问题:一是标注框是否紧贴目标,二是类别名称是否和标签定义一致,三是某些目标是否明显漏标。宁可在这个环节多花一小时,也不要让训练浪费几十个小时。

5. 训练日志的读法:第一次踩坑记录与评估经验

5.1 train loss 下降缓慢,先别急着调学习率

第一次正式训练时,我遇到了一个很典型的“假问题”。训练到第 10 个 epoch,train loss 看起来只是从 2.3 降到 2.1,曲线非常平缓。我的第一反应是学习率太小,想直接把学习率调大一个量级。

但后来冷静下来检查,发现真正的坑在数据侧:原本 1920×1080 的输入被缩到了 416×416,里面几个小目标的面积在缩放后只有几个像素,网络根本提取不到有效特征。不管学习率怎么调,效果都有限。后来我把输入分辨率提高到 640×640,同时把训练集中小目标明显的图片单独保底,loss 才开始平稳下降。

这个经历给我的教训是:loss 不降时先看数据和预处理,不要一上来就动超参。数据和标注的问题不解决,调参只是白费时间。

5.2 验证集表现与测试集表现之间的鸿沟

训练跑到中后期,验证集指标已经不错了,train loss 和 validation loss 的差距也在正常范围。但把模型拿到单独的测试集上评估时,发现测试指标比验证指标明显差一截。

这个现象有两层原因。一层是验证集会参与调参和 early stopping,模型多多少少会对验证集产生过拟合;另一层是,我的测试集是在不同批次、不同光照条件下采集的,分布本身和训练/验证数据就有一些偏移。

要应对这个问题,唯一可靠的办法是建立真正独立的测试集。测试集最好从现场重新采集,不经过任何筛选,直接拿去评估。如果现场条件暂时不允许,至少也要保证测试集图像不是从训练集同一条流水线上截出来的。

5.3 中断续训、显存不足与训练时间估算

训练周期通常很长,中途会因为各种原因中断。我最开始没有养成定期保存模型参数的习惯,结果一次断电解散之后发现模型文件还是十几个 epoch 之前的,几个小时的训练等于白跑了。HALCON 中模型参数可以通过保存模型来持久化,建议每隔一定轮数就保存一次,同时保留当前优化器状态,这样即使中断也能从最近的存档续上。

显存不足是另一个新手常见问题。一开始用的 6GB 显卡,跑了几个 epoch 之后训练直接卡住,不报 OOM,看起来就像死机了一样。后来开着任务管理器盯着显存占用,才确认是显存被打满。遇到这种情况,先把批大小调小,再把输入分辨率适当降低,两者要平衡。不要一开始就把分辨率拉满,给后续迭代留一点余量。

训练时间的估算也一样:先用一个 epoch 跑一次,看单轮耗时,乘上计划训练轮数,就能大概知道总时长。如果时间不可接受,优先调整输入分辨率和批大小,而不是盲目砍数据量。

5.4 评估结果分析:precision 和 recall 怎么指导下一步

训练完成后,用 HALCON 的评估接口可以得到一组指标,包括 precision、recall、IOU 等。看指标不能只看总的 mAP,要分两个方向看。

如果 precision 低,说明误检多。模型把一些背景区域当成了目标,常见原因是背景和真实目标在特征上太像了。解决办法是增加负样本——也就是不包含目标的图像,让模型见一见“什么不是目标”。

如果 recall 低,说明漏检多。常见原因是标注漏标、目标太小、或者某些形态的目标样本数量太少。先检查标注是否完整,再检查小目标样本数量;必要时提高输入分辨率或用 patch 切图训练。

在工业场景里,我更看重 recall 而不是 precision。漏检会带来客诉,而误检通常可以在后续逻辑里过滤。所以在评估结果不理想时,我会优先把 recall 拉上来,再通过增加负样本、调整置信度阈值来控制误检。

最后再分享一个小技巧:在正式花几十个小时跑大训练之前,先用 5 个 epoch 做一次小规模验证。这个阶段不追求精度,只看链路是否通畅、loss 是否下降、显存是否够用。跑完 5 个 epoch 如果一切正常,再启动正式训练。这样能提前暴露绝大多数配置问题,避免跑了几十个小时之后才发现错误,白白浪费时间和电费。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询