3. Halcon深度学习基础

在正式使用Halcon进行深度学习模型部署之前,我们必须先建立对深度学习核心机制的正确认知。很多工程师在初次接触Halcon的DL工具时,容易陷入“只调API、不懂原理”的误区,导致在模型精度不足或推理异常时无从下手。本章将围绕卷积、池化、全连接三个核心概念展开,并系统梳理Halcon中分类、检测、分割三类任务的架构差异与适用场景。

3.1 深度学习核心概念:从像素到语义的逐层抽象

深度神经网络之所以能完成图像识别、目标定位等复杂任务,本质上是将原始像素矩阵通过一系列非线性变换,逐步抽象为高层语义特征。这一过程主要依赖三种基本层结构:卷积层、池化层和全连接层。

3.1.1 卷积层:局部感受野与参数共享

卷积层是特征提取的核心。它通过一组可学习的卷积核(Filter/Kernel)在输入图像上滑动,计算局部区域的加权和。每个卷积核关注一种特定模式,例如边缘、纹理或颜色渐变。其关键设计思想有两个:

  • 局部感受野:每个输出神经元只与输入的一个局部窗口相连,而非全图。这符合图像中邻近像素相关性强的自然属性。
  • 参数共享:同一个卷积核在整个图像上滑动时权重不变,极大减少了参数量。例如一个3×3×64的卷积核,无论输入图像多大,参数量仅为576个。

在Halcon中,卷积操作被封装在create_dl_layer_convolution等算子中,但理解其数学本质对调整超参数至关重要。以下是一个简化的卷积计算示意(单通道、单卷积核):

输入图像 I (5×5)          卷积核 K (3×3)          输出特征图 O (3×3)
[1 0 1 0 1]              [1 0 1]                O[0,0] = 1*1+0*0+1*1
[0 1 0 1 0]              [0 1 0]                        +0*0+1*1+0*0
[1 0 1 0 1]              [1 0 1]                        +1*1+0*0+1*1 = 6
[0 1 0 1 0]
[1 0 1 0 1]

实际部署中,我们更关心卷积层的两个衍生参数:步长(Stride)和填充(Padding)。步长控制卷积核滑动的间隔,步长为2时特征图尺寸减半;填充则在输入边缘补零,用于控制输出尺寸。Halcon的create_dl_layer_convolution算子中通过'stride'和'padding'参数直接设置。

3.1.2 池化层:降采样与平移不变性

池化层(Pooling)通常紧跟在卷积层之后,其作用是对特征图进行下采样。最常用的是最大池化(Max Pooling),即取局部窗口内的最大值作为输出。池化层带来三个好处:

  1. 降低计算量:特征图尺寸减半,后续层的计算复杂度大幅下降。
  2. 扩大感受野:经过多层池化后,高层神经元能看到输入图像的更大区域。
  3. 增强平移不变性:微小的位置偏移不会显著改变池化输出,使模型对目标位置变化更鲁棒。

需要特别注意的是,池化层没有可学习参数,它只是一个固定的下采样操作。在Halcon中,create_dl_layer_pooling算子支持'max'和'mean'两种模式,默认使用最大池化。对于检测任务,过度池化可能导致小目标特征丢失,因此Halcon的预训练模型通常只在网络前半部分使用池化。

3.1.3 全连接层:特征到类别的映射

全连接层(Fully Connected Layer)将卷积和池化得到的二维特征图展平为一维向量,然后通过矩阵乘法与偏置项进行线性变换,再经过激活函数实现非线性映射。其核心作用是将分布式特征表示整合为全局语义信息,最终输出每个类别的得分。

以分类任务为例,假设经过卷积池化后得到特征图尺寸为7×7×512,展平后得到25088维向量。全连接层将其映射到类别数(如10类),输出10个实数。Halcon中,create_dl_layer_dense算子用于创建全连接层,其'num_outputs'参数决定输出维度。

工程提示:在Halcon的预训练模型中,全连接层通常只出现在分类网络的末端。对于检测和分割网络,为了保留空间位置信息,往往使用1×1卷积替代全连接层,这种设计称为“全卷积网络”(FCN)。如果直接修改Halcon分类模型为检测用途,必须移除全连接层,否则会破坏空间结构。

3.2 Halcon中的深度学习架构:三大任务范式

Halcon 19.11版本之后,将深度学习功能整合为三大类:图像分类(Classification)、目标检测(Detection)和语义分割(Segmentation)。三者共享底层卷积特征提取器,但在输出层和损失函数上存在本质差异。

3.2.1 分类架构:全局特征决策

分类任务回答“图像中是什么”的问题。Halcon的分类网络基于ResNet或DenseNet等经典架构,输入固定尺寸图像(如224×224),输出一个概率向量。其典型结构如下:

输入图像 (224×224×3)
    ↓
卷积块1 (Conv+BN+ReLU) → 池化
    ↓
卷积块2 (Conv+BN+ReLU) → 池化
    ↓
...
    ↓
全局平均池化 (Global Average Pooling)
    ↓
全连接层 (输出维度 = 类别数)
    ↓
Softmax激活 → 概率分布

Halcon中,classify_dl_model算子接收图像并返回DLResult句柄,其中包含每个类别的置信度。实际部署时,我们通常设置一个置信度阈值(如0.7),低于该阈值的样本判定为“未知类别”。

3.2.2 检测架构:定位与分类并行

检测任务需要同时回答“物体在哪里”和“物体是什么”。Halcon的检测模型基于Faster R-CNN或YOLO架构,输出为一系列边界框(Bounding Box)及其类别和置信度。与分类不同,检测网络不会将特征图全局池化,而是保留空间分辨率,通过区域提议网络(RPN)或锚点机制生成候选框。

Halcon检测模型的输出格式为:

DLResult['bbox']      : 边界框坐标 (行, 列, 高度, 宽度)
DLResult['class_ids'] : 类别索引
DLResult['confidences']: 每个框的置信度 (0~1)

在部署检测模型时,apply_dl_model算子会返回所有候选框,我们需要通过非极大值抑制(NMS)去除重叠框。Halcon提供了dl_nms算子,其'overlap_threshold'参数控制去重力度,默认0.5。

3.2.3 分割架构:像素级密集预测

分割任务对每个像素进行分类,输出与输入同尺寸的标签图。Halcon的分割模型基于U-Net或DeepLab架构,其特点是存在编码器-解码器结构:编码器逐步下采样提取语义,解码器逐步上采样恢复空间细节,并通过跳跃连接(Skip Connection)融合高低层特征。

分割模型的输出是一个三维张量(H×W×C),其中C为类别数。Halcon通过apply_dl_model得到DLResult['segmentation'],这是一个H×W的整数矩阵,每个像素值代表该位置的类别ID。后处理时,我们常将其转换为可视化掩膜或计算各区域面积。

任务类型 输出粒度 典型网络 Halcon关键算子 适用场景
分类 整图一个标签 ResNet, DenseNet classify_dl_model 产品缺陷有无、材质识别
检测 多个边界框 Faster R-CNN, YOLO apply_dl_model + dl_nms 零件定位、多目标计数
分割 每个像素一个标签 U-Net, DeepLab apply_dl_model + 掩膜转换 表面缺陷区域提取、道路分割

3.3 方法流程:从模型选择到推理部署

在Halcon中完成一个深度学习部署项目,通常遵循以下标准化流程。该流程适用于所有三类任务,差异仅体现在具体算子和参数上。

  1. 模型选择与加载:使用read_dl_model读取预训练模型文件(.hdl)。Halcon提供了针对不同任务的预训练模型,如pretrained_dl_classifier.hdl。
  2. 数据预处理:调用preprocess_dl_model将输入图像调整到模型要求的尺寸和格式。Halcon会自动处理均值减除和归一化。
  3. 推理执行:使用apply_dl_model或classify_dl_model执行前向计算。对于批量推理,可设置'batch_size'参数提高GPU利用率。
  4. 后处理:根据任务类型解析输出。分类取最大概率索引;检测执行NMS;分割将标签图转为区域(Region)。
  5. 结果可视化与输出:使用dev_display_dl_data叠加显示结果,或通过get_dl_model_param提取数值供PLC通信。
// Halcon推理核心代码片段(检测任务)
read_dl_model ('pretrained_dl_detector.hdl', DLModelHandle)
read_image (Image, 'part.png')
preprocess_dl_model (DLModelHandle, Image, DLPreprocessed)
apply_dl_model (DLModelHandle, DLPreprocessed, [], DLResult)
// 提取边界框并执行NMS
get_dl_model_param (DLModelHandle, 'class_names', ClassNames)
get_dl_result (DLResult, 'bbox', BBox)
get_dl_result (DLResult, 'confidences', Confidences)
dl_nms (BBox, Confidences, 0.5, SelectedBBox, SelectedConfidences)

3.4 典型应用场景与选型建议

理解三类架构的差异后,实际项目中的选型就变得清晰。以下通过三个工业场景说明:

  • 场景A:电子元件引脚缺失检测。每个元件只需判断“合格/不合格”,属于二分类问题。使用分类模型即可,推理速度最快,可在CPU上实时运行。
  • 场景B:流水线上的多品种零件分拣。需要同时定位多个零件并识别其类型,必须使用检测模型。Halcon的检测模型在遮挡场景下表现优于传统Blob分析。
  • 场景C:电池表面划痕区域提取。需要精确到像素的缺陷区域,用于后续测量划痕长度和宽度,应选择分割模型。分割模型对边缘精度要求高,建议使用带跳跃连接的U-Net。
常见误区复盘:很多初学者试图用分类模型裁剪图像区域来模拟检测功能。这种做法在目标尺寸一致、背景简单时勉强可行,但一旦目标大小变化或存在重叠,分类模型的固定输入尺寸会导致严重的信息丢失。正确做法是直接使用检测模型,让网络自己学习目标的位置和尺度。另外,分割模型并非“更高级”的检测模型,其训练数据标注成本远高于检测框标注,如果业务只需要目标位置和类别,不要盲目选择分割。

3.5 本章小结与关键参数速查

本章建立了Halcon深度学习的三大支柱:卷积层负责特征提取,池化层负责降维与鲁棒性,全连接层负责决策输出。Halcon将这三者组合为分类、检测、分割三种标准架构,分别对应图像级、目标级和像素级的预测粒度。在实际部署中,务必根据业务需求选择正确的任务类型,并理解各架构在输出格式、后处理流程上的差异。

以下为本章涉及的关键参数速查表,供后续章节实战时参考:

参数/算子 所属任务 典型值/说明
create_dl_layer_convolution 所有 'stride'=1, 'padding'='same'
create_dl_layer_pooling 所有 'mode'='max', 'stride'=2
create_dl_layer_dense 分类 'num_outputs'=类别数
dl_nms 检测 'overlap_threshold'=0.5
apply_dl_model 检测/分割 'batch_size'=1, 'gpu'=0
classify_dl_model 分类 返回'confidence'列表

在下一阶段的实战中,我们将基于这些基础概念,逐步构建一个完整的Halcon深度学习推理系统。届时,你会看到这些抽象概念如何转化为具体的算子调用和性能调优策略。