三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

工业视觉多相机同步采集与Halcon实时处理实践

工业视觉多相机同步采集与Halcon实时处理实践

1. 项目背景与核心需求

在工业视觉检测领域,多相机同步采集是一个经典而高频的需求场景。我最近接手的一个半导体元件外观检测项目,就需要同时控制3台海康工业相机进行连续拍摄,并通过Halcon实时处理图像。这种方案在PCB板检测、液晶屏瑕疵识别、食品包装质检等场景中非常常见。

传统单线程轮询取图方式存在明显瓶颈:

  • 采集帧率受限于线程切换开销
  • 内存拷贝频繁导致延迟波动
  • 多相机时间戳难以精确对齐

而采用回调函数机制(Callback)的优势在于:

  1. 事件驱动模式避免空轮询
  2. 硬件触发时可获得更精确的时间同步
  3. 内存零拷贝提升传输效率
  4. 天然支持多相机并行处理

2. 环境搭建与SDK准备

2.1 硬件连接方案

以3台海康MV-CE060-10GC相机为例,典型连接拓扑如下:

设备型号连接方式
相机1MV-CE060-10GC网口→交换机
相机2MV-CE060-10GC网口→交换机
相机3MV-CE060-10GC网口→交换机
主机带千兆网卡的工控机网口→交换机
同步信号源PLC或信号发生器IO线并联至各相机

关键提示:务必确保交换机支持IGMP Snooping功能,避免组播风暴导致丢包

2.2 软件依赖安装

  1. 海康SDK:从官网下载MVS 3.3.1或更新版本

    # 验证驱动安装 lsusb | grep Hikvision modinfo hikvision
  2. Halcon配置

    // 在app.config中添加runtime配置 <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="halcon\dlls"/> </assemblyBinding> </runtime>
  3. C#项目NuGet包

    Install-Package HalconDotNet -Version 20.11.0 Install-Package HikDeviceSDK.Net

3. 回调函数核心实现

3.1 海康SDK回调注册

// 相机初始化代码示例 public class CameraWrapper { private IntPtr m_hDevice; private CHCNetSDK.MV_CC_DEVICE_INFO m_stDevInfo; public void InitCamera(uint nIndex) { CHCNetSDK.MV_CC_CreateDevice_NET(ref m_stDevInfo, out m_hDevice); CHCNetSDK.MV_CC_RegisterImageCallBackEx_NET( m_hDevice, new CHCNetSDK.cbOutputExdelegate(ImageCallback), IntPtr.Zero); } private void ImageCallback(IntPtr pData, ref CHCNetSDK.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser) { // 图像处理线程 byte[] imageData = new byte[pFrameInfo.nFrameLen]; Marshal.Copy(pData, imageData, 0, (int)pFrameInfo.nFrameLen); // 生成Halcon对象 HObject ho_Image; HOperatorSet.GenImage1(out ho_Image, "byte", pFrameInfo.nWidth, pFrameInfo.nHeight, new HTuple(imageData)); // 触发显示事件 ImageReceived?.Invoke(this, new ImageEventArgs(ho_Image)); } }

3.2 多相机同步策略

实现硬件同步的三种方案对比:

方案精度复杂度适用场景
软件触发±5ms非精密测量
IO硬件触发±100μs常规产线检测
PTP网络同步±1μs高速运动分析

推荐采用硬件触发接线方式:

信号发生器(+) → 相机1 TRIG IN → 相机2 TRIG IN → 相机3 TRIG IN 信号发生器(-) → 共地端子

3.3 Halcon显示优化技巧

// 高性能显示方案 private HWindowControl m_hWindow; private Thread m_dispThread; private Queue<HObject> m_imgQueue = new Queue<HObject>(); void StartDisplayThread() { m_dispThread = new Thread(() => { while(!m_shutdown) { if(m_imgQueue.Count > 0) { lock(m_imgQueue) { HObject img = m_imgQueue.Dequeue(); m_hWindow.HalconWindow.DispObj(img); img.Dispose(); } } Thread.Sleep(1); } }); m_dispThread.Priority = ThreadPriority.AboveNormal; m_dispThread.Start(); }

4. 性能优化与异常处理

4.1 内存管理黄金法则

  1. 双缓冲策略

    private ConcurrentQueue<byte[]> m_bufferPool = new ConcurrentQueue<byte[]>(); void PreAllocBuffers() { for(int i=0; i<10; i++) m_bufferPool.Enqueue(new byte[10*1024*1024]); }
  2. Halcon对象生命周期

    using(HObject ho_Image = new HObject()) { // 图像处理代码 } // 自动调用Dispose()

4.2 常见故障排查表

现象可能原因解决方案
回调不触发网络MTU设置不当设置交换机MTU=9000
图像撕裂显示线程阻塞提升显示线程优先级
内存泄漏未释放Halcon对象使用using语句块
帧率不稳定硬盘写入瓶颈启用RAMDisk临时存储
时间戳不同步未启用PTP配置IEEE 1588协议

4.3 实测性能数据

在i7-11800H平台上的测试结果:

相机数量分辨率帧率(触发)CPU占用率
13088×206458fps12%
33088×206454fps38%
34096×300032fps63%

注:测试条件为GigE接口、Jumbo Frame=9014、Windows实时内核模式

5. 高级应用扩展

5.1 与ROS系统集成

通过HikVision的ROS驱动实现:

# 启动相机节点 roslaunch hikrobot_camera hikrobot_camera.launch camera_name:=cam1 serial_number:=KE100101

5.2 深度学习集成方案

Halcon深度学习模块调用示例:

HDict dlModel = new HDict(); HOperatorSet.ReadDict("defect_detection.hdict", new HTuple(), out dlModel); HObject ho_Image, ho_Result; HOperatorSet.ApplyDlModel(ho_Image, dlModel, out ho_Result);

5.3 多语言混合编程

通过C++/CLI桥接Halcon与C#:

// NativeWrapper.cpp public ref class HalconBridge { public: static void ProcessImage(array<byte>^ imgData) { pin_ptr<byte> pData = &imgData[0]; HImage image("byte", width, height, (Hlong)pData); // 处理代码 } };

6. 工程实践建议

  1. 许可证管理:Halcon运行时许可证建议采用网络浮动授权,避免多设备冲突

  2. 异常恢复机制

    private void SafeRestartCamera() { try { m_camera.StopGrabbing(); Thread.Sleep(1000); m_camera.StartGrabbing(); } catch { // 记录日志并通知运维 } }
  3. 日志记录规范

    NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); logger.Info($"相机{index}采集启动,序列号:{serial}");

在实际项目中,我们发现当相机数量超过4台时,建议采用分布式采集方案——用多台工控机分别处理部分相机数据,再通过MQTT或gRPC进行结果汇总。这种架构在汽车零部件全检系统中已得到成功验证,可稳定支持12相机同步采集需求。

← 返回列表