2. HALCON图像采集与相机接口

在工业缺陷检测系统中,图像采集是整条处理链的起点。无论后续的亚像素边缘提取、模板匹配还是深度学习分类算法多么精密,一旦进入 HALCON 的图像本身存在曝光不足、运动模糊、丢帧或色彩偏差,缺陷检测的稳定性就无从谈起。本节围绕 HALCON 的图像采集体系展开,从采集基础概念、GenICam 标准、GigE Vision 与 USB3 Vision 两类主流接口,到 open_framegrabber、grab_image 等核心算子的实际使用,最后完成一个可运行的实时采集与保存任务。

一、图像采集的基本概念

HALCON 将图像采集抽象为“图像采集接口(Image Acquisition Interface)”这一层。相机厂商的 SDK 被 HALCON 封装成统一的接口动态库(如 hAcqGigEVision2.dll、hAcqUSB3Vision.dll),上层算子通过接口名、相机标识和参数来访问硬件。这样做的价值在于:更换相机品牌或接口类型时,业务代码几乎不需要改动,只需替换 open_framegrabber 中的接口名与参数。

采集过程中需要理解几个关键量:曝光时间决定单帧积分时长,直接影响亮度与运动模糊;增益放大信号但同步放大噪声;帧率受曝光、读出速度和带宽共同约束;触发模式分为自由运行(free run)与外部硬触发,后者是产线同步的关键。此外,像素格式(Mono8、BayerRG8、RGB8 等)决定了 HALCON 中图像的通道数与后续算子的输入要求。

二、GenICam 标准与两种主流接口

GenICam(Generic Interface for Cameras)是由 EMVA 主导的通用相机编程标准,它定义了统一的寄存器访问方式(GenApi)、XML 描述文件(相机能力自描述)以及传输层标准。GigE Vision 与 USB3 Vision 都是 GenICam 的传输层实现,因此 HALCON 可以用相似的参数名(如 ExposureTime、Gain、AcquisitionFrameRate)去配置不同接口的相机。

GigE Vision 基于千兆/万兆以太网,线缆可长达 100 米,支持 PoE 供电,适合多相机分布式部署,但带宽受网卡与交换机限制,且需要正确设置巨帧(Jumbo Frame)与网卡缓冲区。USB3 Vision 基于 USB 3.0,带宽高、延迟低、即插即用,线缆通常不超过 3~5 米,适合单机紧凑型设备。选择时需权衡传输距离、相机数量、带宽需求与现场布线条件。

HALCON 图像采集链路与接口对比 工业相机 CMOS 传感器 曝光 / 增益 / 触发 GenICam 传输层 GigE Vision / USB3 Vision XML 描述 + 寄存器访问 HALCON 采集接口 hAcqGigEVision2 hAcqUSB3Vision HALCON 采集算子 open_framgrabber → grab_image / grab_image_async → close_framegrabber HObject 图像 Mono8 / RGB8 / Bayer 保存 / 处理 write_image / 缺陷算法 接口选择参考 GigE:≤100m,多相机 USB3:≤5m,高带宽 均支持 GenICam 参数 触发模式决定同步精度

三、核心采集算子与参数

open_framegrabber 是采集的入口,其典型调用形式如下:

open_framegrabber ('GigEVision2', 0, 0, 0, 0, 0, 0, 'progressive',
                   -1, 'default', -1, 'false', 'default',
                   '192.168.1.10', 0, -1, AcqHandle)

参数依次为:接口名、水平/垂直偏移与分辨率(0 表示使用相机默认)、起始场、半像、位深、色彩空间、宽高比、触发模式、端口、相机标识(此处为 IP)、超时等。实际工程中更推荐先用 open_framegrabber 打开,再用 set_framegrabber_param 逐项设置曝光、增益、触发源等,这样参数含义更清晰、便于调试。

采集单帧用 grab_image,连续采集用 grab_image_async 配合 grab_image_start 实现流水线式异步采集,可显著提升帧率。采集完成后必须调用 close_framegrabber 释放句柄,否则相机会被占用导致下次打开失败。

调试阶段建议先用 get_framegrabber_param 读取相机当前参数,确认曝光、增益、像素格式与预期一致,再进入算法开发,避免把采集问题误判为算法问题。

四、实时采集与保存任务

下面给出一个完整的实时采集与保存示例:以 GigE 相机为例,设置 10 ms 曝光、连续采集 20 帧,并将每帧保存为 PNG。示例参数属于教学假设,实际需根据现场光照与相机型号调整。

open_framegrabber ('GigEVision2', 0, 0, 0, 0, 0, 0, 'progressive',
                   -1, 'default', -1, 'false', 'default',
                   '192.168.1.10', 0, -1, AcqHandle)

set_framegrabber_param (AcqHandle, 'ExposureTime', 10000)
set_framegrabber_param (AcqHandle, 'Gain', 2.0)
set_framegrabber_param (AcqHandle, 'AcquisitionMode', 'Continuous')

for Index := 1 to 20 by 1
    grab_image (Image, AcqHandle)
    Filename := 'capture_' + Index$'02d' + '.png'
    write_image (Image, 'png', 0, Filename)
endfor

close_framegrabber (AcqHandle)

运行后应能在工作目录看到 capture_01.png 至 capture_20.png。判断采集是否正常,可从三方面检查:一是图像亮度是否落在合理区间(Mono8 下均值约 100~180 灰度);二是连续帧之间是否存在明显丢帧或重复帧;三是保存文件大小是否稳定,若某帧异常小往往意味着传输中断或图像为空。

GigE 相机务必确认网卡巨帧已开启、防火墙未拦截,且相机与网卡处于同一网段;USB3 相机应使用原装线缆并避免与高功耗 USB 设备共用控制器,否则容易出现带宽不足导致的丢帧。