十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Halcon目标检测实战:数据标注与DLS数据集构建全解析

Halcon目标检测实战:数据标注与DLS数据集构建全解析 自己动手做深度学习项目时最容易被卡住的往往不是模型训练而是数据准备。尤其是用Halcon做目标检测很多人一上来就研究网络结构、调参结果在标注环节就折腾了好几天。这篇笔记是《Halcon deep learning之目标检测》系列的第一篇我先把整个项目的框架和最关键的数据标注环节完整梳理一遍。Halcon的深度学习目标检测模块本质上是把深度学习目标检测的完整流程——数据准备、模型训练、评估、推理——全部封装在机器视觉套件里。你不需要自己写Python脚本搭网络不需要处理TensorFlow或PyTorch的模型转换只要按它的规范准备数据调好参数就能训练出可用于工业场景的检测模型。这个定位决定了它的核心工作重心不在算法创新而在数据工程和工程化落地。这篇文章适合谁看想用Halcon做缺陷检测、物体定位、分类计数但还没搞清楚标注格式、数据集结构、训练流程的人。我会把Halcon目标检测的原理框架、标注工具操作细节、数据集格式规范、数据划分策略、常见坑全部讲透并且按照实际操作顺序来组织内容——先讲为什么这样设计再讲怎么做最后讲踩了什么坑。1. 目标检测项目整体思路与任务拆解1.1 Halcon深度学习目标检测到底能做什么先明确一个概念Halcon的Deep Learning目标检测模块做的是“目标定位分类”的联合任务。输入一张图输出的是每个目标对象的边界框Bounding Box位置、类别标签和置信度。它跟图像分类最大的区别在于分类只回答“图里有什么”目标检测还要回答“在哪”。在工业场景里这个功能对应着大量的真实需求。比如检测电路板上的元件是否贴装正确定位产品表面的划痕区域统计传送带上的零件数量并判断种类或者识别字符区域供后续OCR处理。我做过的项目里最典型的一个是药盒包装检测——需要同时定位药盒上的生产日期喷码区域和条码区域然后分别交给后续的识别模块处理。这种多目标、多类别的定位需求就是目标检测的标准应用场景。1.2 Halcon深度学习的技术架构与设计思路Halcon的深度学习目标检测模块底层网络结构是一个类似Faster R-CNN的检测架构。它包含特征提取的主干网络Pretrained Backbone、区域建议网络RPN和检测头Detection Head。不过这些细节Halcon封装得很深你在界面里能看到的主要是几个预训练模型文件比如pretrained_dl_classifier.hdl用于分类pretrained_dl_object_detection.hdl用于目标检测。这种封装带来的好处很明显你不用关心锚点Anchor怎么设置、NMS阈值怎么调、特征金字塔怎么设计Halcon的自动调参流程会根据你的数据集特性去适配这些超参数。但坏处也有——出了问题排查起来比开源框架难很多中间变量看不到。所以我的建议是用Halcon做深度学习一定要把它当成黑盒工具来用把精力集中在数据质量和参数策略上不要试图去改它的内部结构。1.3 完整的工作流程概要一个标准的Halcon深度学习目标检测项目完整流程如下数据采集用工业相机拍摄或收集历史图片覆盖各类正负样本。数据整理与标注用Halcon的标注工具或第三方工具标注边界框和类别。数据划分按一定比例划分训练集、验证集和测试集。创建DLS数据集把标注结果转成Halcon深度学习所需的.dls数据格式。模型训练基于预训练模型做迁移学习。模型评估查看mAP、混淆矩阵等指标判断模型是否可用。推理部署导出模型集成到视觉项目中处理实际图像。这一篇笔记我重点拆解第2到第4步也就是数据标注和数据集构建这是整个项目中最耗时、最影响最终效果的环节。训练、评估、部署会在后续笔记里单独展开。2. 环境准备Halcon深度学习工具部署2.1 运行环境与硬件要求Halcon深度学习对硬件的要求比传统机器视觉要高不少。官方推荐的配置是NVIDIA显卡支持CUDA和cuDNN显存建议至少8GB。这个不是随便说的——目标检测训练时图像会以batch形式送进网络每张图还要做缩放和归一化显存不够根本无法启动训练。CPU可以训练吗理论可以但实际体验很差。我用CPU训练一个300张图片的小数据集一个epoch要将近20分钟而用NVIDIA RTX 3060跑同样的数据一个epoch不到1分钟。所以如果你是要认真做项目一块入门级NVIDIA显卡是刚需。软件方面Halcon版本建议使用19.11以上因为深度学习模块从那个版本开始才比较成熟。需要安装对应版本的Halcon深度学习扩展包通常是一个额外的安装组件在Halcon安装器里勾选“Deep Learning”相关选项即可。2.2 安装过程中的关键细节安装Halcon深度学习组件时有几个容易被忽略的细节CUDA和cuDNN版本匹配是最大的坑。Halcon不同版本对CUDA版本有严格要求安装前务必确认Halcon对应版本的Release Notes里写明的CUDA版本号。我见过太多人装了新版CUDA导致Halcon无法调用GPU最后只能重装系统。环境变量配置Halcon需要把HALCONROOT和HALCONARCH环境变量正确设置否则深度学习训练时无法找到依赖的DLL和模型文件。Windows下建议在系统环境变量里明确设置不要依赖安装程序的默认配置。License授权深度学习模块在Halcon的License体系里属于单独的功能类别保证License中包含深度学习的权限项否则训练时会报HALCON error #5100或类似的授权错误。2.3 快速验证环境是否可用环境配置完成后我建议先用一个最简单的脚本验证深度学习模块能否正常调用GPU。打开HDevelop执行以下代码* 查询可用设备 query_available_dl_devices(DeviceHandles, DeviceIdentifiers) * 显示设备信息 for i : 0 to |DeviceIdentifiers| - 1 by 1 get_dl_device_param(DeviceHandles[i], type, DeviceType) get_dl_device_param(DeviceHandles[i], name, DeviceName) get_dl_device_param(DeviceHandles[i], compute_capability, ComputeCapability) disp_message(WindowHandle, Device i : DeviceType - DeviceName (CC ComputeCapability ), window, 12, 12, black, white) endfor如果能看到类似gpu - NVIDIA GeForce RTX 3060的输出说明环境正常。如果只看到cpu则说明CUDA配置有问题需要回头检查驱动和CUDA版本。3. 数据集设计与标注实操3.1 标注工具选型Halcon官方推荐的标注工具是HDevelop自带的DL Tooldeep learning tool在HDevelop的菜单栏里通过Deep Learning菜单点击Label Data即可打开。这个工具专门用于标注目标检测和分割数据可以直接导出Halcon原生支持的格式。除了官方工具CVAT、LabelImg、labelme这些第三方工具也经常被用来做标注。我用过之后总结一下各自的优劣工具优势劣势推荐场景Halcon DL Tool原生支持DLS格式导出标注规范自动匹配界面简陋功能单一小数据集、快速验证CVAT功能强大支持团队协作、自动标注需要搭建服务格式转换略复杂中大型数据集、多人标注LabelImg轻量简单XML格式通用单机使用效率一般快速标注少量图片labelme支持多边形标注JSON格式需要转换实例分割或复杂形状标注我个人偏好是200张以内的数据集直接用Halcon DL Tool减少格式转换的麻烦超过500张的图像尤其是有多人协作需求时用CVAT更合适因为它的效率工具更完善比如自动标注、跟踪标注这些功能能省不少时间。3.2 Halcon DL Tool标注操作全流程下面以Halcon DL Tool为例把标注流程完整走一遍。第一步新建标注任务打开DL Tool后选择Create Project填写项目名称选择标注类型为目标检测Object Detection。然后导入图像文件夹工具会自动加载所有图片。这里有个重要设置Classes类别的定义。如果项目里有多个类别比如既要检测划痕又要检测脏污那就需要分别定义scratch和contamination两个类别。类别的命名用英文因为后面训练生成的文件、日志都会引用这个名字中文容易出编码问题。第二步图像筛选与预处理在标注之前先过一遍所有图像把质量太差的剔除掉。模糊、过曝、严重反光的图片要么在采集阶段重新拍要么直接删除。这个环节容易被忽略但影响很大——深度学习模型学到的是标注框内图像的纹理特征如果训练集里混入大量模糊图模型推理时会对模糊图产生误检。另外还要考虑图像的尺寸统一性。Halcon训练时会将所有图像缩放到固定尺寸如果你的图片尺寸差异过大小图被放大后细节丢失大图缩小后小目标可能被压没。建议在采集阶段就统一分辨率或者至少保证目标对象在图像中的相对大小不要差异太大。第三步绘制边界框选中一张图点击Draw Rectangle按钮在目标对象上拖动鼠标绘制矩形框。需要注意几个原则边界框要贴合目标不要留太多背景。留白过多会让模型学到背景特征影响定位精度。遮挡目标的处理如果目标被部分遮挡仍然标注整个目标但置信度会受影响。如果遮挡超过50%建议不标注该目标或者在标注规范中统一约定。紧贴排列的密集目标比如药板上的胶囊每个都要单独标注不能合并成一个框。Halcon目标检测支持密集目标的检测关键是标注要准确分离。第四步类别分配每个边界框绘制完都要指定对应的类别。在DL Tool中点击已绘制的矩形框在右侧属性面板中选择类别。类别分配的准确性直接决定模型分类能力这步必须人工仔细核对。第五步导出标注全部标注完成后通过Export Project导出。Halcon DL Tool会生成一个.hdict文件里面包含了所有标注信息包括图像路径、每个目标的边界框坐标和类别ID。后续用read_dict读取再通过create_dl_dataset_from_dict创建正式的数据集。3.3 标注规范的制定标注这件事最大的坑不是工具不会用而是标准不统一。尤其是多人协作的项目每个人对“什么样的框算贴合”理解不同最后出来的训练数据五花八门。我建议在项目启动前花半小时写一份简单的标注规范文档至少包含边界框绘制标准要求框紧贴目标边缘误差不超过2个像素目标的旋转框暂用外接正矩形表示。困难样本处理模糊、遮挡、截断目标的标注规则是标注还是不标注要有明确约定。类别定义与边界两个相似类别之间的判定标准比如“划痕”和“裂纹”怎么区分必须给定义或示例图。目标最小尺寸小于某个像素尺寸比如20×20的目标不标注因为小目标在缩放后几乎不可见标注了反而增加噪声。这些规范看起来繁琐但能避免后面返工。我在一个外观检测项目里吃过亏前期标注没规范三个人标了600张图训练后发现模型在“划痕”和“污渍”上频繁混检回查数据才发现这两个类别的判定标准不一致。最后花了三个晚上重新过了一遍标注才解决。4. 数据集格式与DLS文件构建4.1 Halcon深度学习数据集内部结构Halcon深度学习的标准数据集格式是.dls文件它实际上是一个包含图像字典和标注字典的压缩文件。理解这个结构很重要因为很多高级操作——比如合并数据集、剔除坏样本、手工补充标注——都需要直接操作底层字典。一个标准的Halcon目标检测数据集包含三个核心部分图像字典Image Dictionary保存图像文件名、图像ID、尺寸信息等。样本字典Sample Dictionary每个样本对应一张图像记录该图像包含的所有目标边界框坐标和类别ID。类别字典Class Dictionary记录所有类别名称和ID的映射关系。在HDevelop中用代码来构建数据集的逻辑如下所示* 读取标注字典 read_dict(LabelingDict, labeling_result.hdict, [], []) * 创建空数据集 create_dl_dataset(DatasetHandle) * 将标注字典转换为数据集 create_dl_dataset_from_dict(DatasetHandle, LabelingDict, [], []) * 设置类别名称列表 set_dl_dataset_param(DatasetHandle, class_names, [scratch, contamination]) * 设置预处理参数 set_dl_dataset_param(DatasetHandle, image_width, 512) set_dl_dataset_param(DatasetHandle, image_height, 512) * 保存数据集 write_dl_dataset(DatasetHandle, detection_dataset.dls)4.2 DLS格式与第三方标注格式的转换如果你用的是CVAT或LabelImg就需要把标注结果转换为Halcon的DLS格式。这个转换逻辑不复杂主要是把不同工具的坐标体系映射到Halcon的坐标系。以LabelImg的Pascal VOC XML格式为例坐标信息保存在每个object节点下包含xmin、ymin、xmax、ymax四个值这是典型的左上角右下角坐标表示。而Halcon的create_dl_dataset_from_dict需要的是每个目标的row、column、width、height也就是中心点坐标加宽高。转换公式为row (ymin ymax) / 2 column (xmin xmax) / 2 width xmax - xmin height ymax - ymin转换后写入一个字典再通过Halcon的Python接口生成DLS文件。Halcon提供Python接口后这种跨工具的数据转换方便很多。我们看一个Pascal VOC转DLS的Python示例import os import xml.etree.ElementTree as ET from halcon import HOperatorSet # 假设voc_annotations目录下存放所有XML标注文件 annotations_dir voc_annotations image_dir images # 构建Halcon识别所需的数据结构 halcon_dict HOperatorSet.create_dict() class_names [] samples [] for xml_file in sorted(os.listdir(annotations_dir)): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(annotations_dir, xml_file)) root tree.getroot() image_name root.find(filename).text # 记录图像路径 image_path os.path.join(image_dir, image_name) # 提取所有目标框 boxes [] for obj in root.findall(object): name obj.find(name).text if name not in class_names: class_names.append(name) class_id class_names.index(name) bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) # 转Halcon坐标 row (ymin ymax) / 2 column (xmin xmax) / 2 width xmax - xmin height ymax - ymin boxes.append([row, column, width, height, class_id]) samples.append({image_path: image_path, boxes: boxes}) # 写入Halcon字典并创建数据集 # 这里省略具体的dict写入代码核心是调用create_dl_dataset_from_dict这个过程看起来简单但有几个细节容易踩坑。第一图像路径在DLS里保存后训练时会按照路径去读取图像所以路径必须写成绝对路径或者保证数据集和图像目录的相对关系不变。否则换一台电脑训练就会报找不到图像的错。第二类别ID必须从0开始连续编号Halcon不会帮你自动做类别映射如果某个类别的ID是空的训练时会报错。4.3 数据划分策略数据集准备好后需要按比例划分为训练集、验证集和测试集。Halcon提供了split_dl_dataset算子来自动划分典型比例为70%训练、15%验证、15%测试。这个比例不是固定的需要根据数据量调整。当数据总量少于100张时建议采用8:1:1的比例并且要保证测试集的数据分布与训练集接近。我在实践中发现很多项目最终的评估指标“虚高”是因为测试集碰巧与训练集高度相似比如同一批次、同一光照下拍的图。真实场景里光照变化、摆放位置变化都很大所以测试集要尽量选择不同时间、不同条件下采集的图像。划分时的另一个原则是同一对象的不同图像不能同时出现在训练集和测试集中。比如在一张传送带上拍的10连拍其中8张进训练集2张进测试集这会导致测试集泄漏——模型在训练时“见过”该对象的特征测试指标虚高。Halcon的split_dl_dataset默认按图像文件随机划分不会感知对象关系所以需要在划分前手动把同一对象的批次捆绑或者调整划分算法。* 按指定比例划分数据集 split_dl_dataset(DatasetHandle, 0.7, 0.15, 0.15, [], [], RandomSeed)4.4 数据增强到底做不做Halcon的深度学习训练流程里set_dl_dataset_param可以设置augmentation相关的参数。Halcon内置的数据增强包括水平翻转、随机裁剪、颜色扰动等。但在目标检测任务中数据增强要谨慎使用。水平翻转是相对安全的增强方式。物体检测中物体水平翻转后仍然是合法的目标语义不变。但垂直翻转要慎重——你不能把药盒倒过来学因为真实场景中不会出现倒置的药盒。旋转增强同样要结合场景如果是圆形零件旋转没问题如果是文字区域旋转90度后字符都变形了反而引入噪声。我的经验是先用原始数据训练一个baseline再看数据量决定是否增强。如果某些类别只有几十个样本可以考虑对该类别做过采样或针对性增强。如果每个类别样本都超过200个增强带来的收益有限反而增加训练时间。5. 常见问题与排查技巧实录5.1 标注阶段的高频问题问题一标注框导出后坐标偏移DL Tool导出后在图像上叠加显示发现标注框明显偏移。排查发现原因是标注时图像被缩放显示但导出时坐标没有按缩放比例还原。解决办法是在标注前先确认DL Tool的显示缩放状态标注完成后完全退出工具再导出或者检查导出字典里的image_width和image_height字段是否与原图尺寸一致。问题二类别名称大小写不统一同一类别的标注有的写Scratch有的写scratch导致Halcon认为是两个类别训练时类别数翻倍。这个问题在手工编辑字典、或从不同工具合并数据时特别常见。建议在标注结束后统一检查一次类别字段。问题三图像路径是相对路径导致训练时报错用CVAT导出数据后图像路径经常是相对路径或者带有前缀的URL直接转成DLS后训练时报image file not found。解决方法是转换时用os.path.abspath将所有相对路径转成绝对路径。5.2 环境配置的高频问题CUDA not availableHalcon无法调用GPU训练时只走CPU。通常原因是CUDA驱动版本低于Halcon要求或者显卡驱动未更新到支持CUDA的版本。用nvidia-smi查看驱动版本对照Halcon Release Notes检查。LICENSE错误报HALCON error #5100授权问题时先确认License文件中是否包含deep_learning相关模块。Halcon的License是按功能模块划分的基础授权不包含深度学习模块。内存不足标注大图分辨率5000×5000以上时Halcon需要把整张图加载到显存显存不够会报内存错误。解决思路是降低训练时的图像尺寸或者在标注阶段就对大图做切块处理。5.3 数据集质量的自查方法在正式训练前一定要做一次数据质量自查。我总结了一套快速检查流程类别数量统计用get_dl_dataset_param获取每个类别的样本数确认没有类别严重不平衡。边界框尺寸分布统计所有边界框的宽高比和面积分布看是否有异常值比如框宽为0、面积为负。可视化抽查随机抽取50张图像把标注框叠加显示肉眼检查标注是否有明显的漏标、错标。训练-验证分布对比分别统计训练集和验证集中各类别的目标数量占比看是否大致一致。这个自查流程看起来简单但能有效避免训练到一半才发现数据集存在严重问题的尴尬。我做过一个项目训练跑了20多个epoch看损失曲线一直不收敛排查半天发现是数据集里混入了几张标注类别ID错误大于类别总数的坏样本。6. 这篇笔记之外的延伸思考写到这里《Halcon deep learning之目标检测笔记一》的核心内容就告一段落了。这个系列后续还会覆盖两个关键主题一是模型训练的参数策略与损失曲线解读二是模型评估与工业现场的部署优化。在数据标注这个环节我个人实际操作的体会是标注质量对最终模型效果的影响往往大于网络结构和训练参数的调整。很多人花大量时间研究Halcon的参数设置却不愿意在数据标注上花功夫最后模型效果不理想还以为是工具不行。实际上Halcon的目标检测模块经过多年的工业项目验证算法本身是可靠的效果不理想大概率是数据问题。最后再分享一个小技巧标注完成后我习惯用Halcon自带的read_dl_dataset配合gen_dl_dataset_preview做一次标注可视化预览边滚动边检查比在标注工具里逐张看高效得多。这个过程能发现很多隐蔽的问题——比如某张图的标注框跑到图像边缘外或者某个类别的框明显比其他同类别的框大一圈。把这些小问题在训练前解决掉后面能省下大量的调试时间。下一篇笔记我会重点讲训练参数——包括learning_rate、batch_size、momentum这些关键参数在Halcon里的配置逻辑以及怎么通过训练日志判断模型是否收敛。等那个部分写完你就能完整跑通一个从标注到部署的目标检测项目了。
返回列表