首页 / 资讯中心 / 文章详情

C#与Halcon工业相机图像显示:三层架构解决平移缩放与回调线程问题

C#与Halcon工业相机图像显示:三层架构解决平移缩放与回调线程问题 ★ FEATURED ARTICLE
简介这份压缩包面向使用C#进行机器视觉上位机开发的初中级开发者围绕调用Halcon读取海康相机图像并在HSmartWindowControlHsmartHwind中显示与实现鼠标平移、缩放这一典型需求给出可参考的工程实现。包内共46个文件以10个cs源码、5个dll依赖、sln与csproj工程文件、config配置、resx资源及exe/pdb运行调试文件为主压缩包约22.53MB兼顾源码查阅与直接运行验证。已有929人学习说明该主题在工业视觉、检测设备界面开发中较受关注。读者可据此梳理Halcon .NET引用、相机取流、图像窗口显示及交互操作的组织方式并结合窗体代码理解平移缩放的事件处理与资源释放思路适合作为课程设计、项目原型或二次开发的基础样例。1. 项目定位C# Halcon 的相机显示链路难点不在 DispObj很多机器视觉项目里C# 调 Halcon 读取工业相机再把图像显示到 HSmartWindowControl 上看上去只是 Open、GrabImage、DispObj 三步真到现场加平移缩放图像坐标系、控件句柄和相机回调线程就会一起找麻烦。这个工程要解决的不是“能不能显示”而是把某品牌工业相机的采集回调、Halcon 的 HObject 生命周期、HSmartWindowControl 的 SetPart 变换拆成可复用的三层让鼠标拖拽、滚轮缩放和连续刷新不打架。适合正在做视觉工控上位机、需要把相机画面嵌进 WinForms 界面的开发者。2. 工程架构相机采集层、HObject 转换层和 HSmartWindowControl 显示层怎么分这份模拟项目我一般按三层拆相机采集层只负责调厂商 SDK、注册回调、拿到原始帧信息HObject 转换层负责把 SDK 返回的 IntPtr 变成 Halcon 能用的图像并且把生命周期管住显示层只认 HObject负责 SetPart、DispObj、鼠标交互。三层分开之后换相机品牌时只改采集层换显示控件时只改显示层HObject 的释放点也不会散落在各个事件里。最怕的写法是相机回调里直接hSmartWindowControl1.HWindow.DispObj(image)。SDK 回调线程不是 UI 线程轻则跨线程异常重则界面卡住而且 SDK 的缓冲区往往在回调返回后就被复用HObject 如果还引用那块内存画面就会花屏或闪黑。下面这种分层不是“架构洁癖”是现场调试时少熬夜的底线。模块主要职责需要盯住的点Camera打开设备、设置像素格式、注册回调回调线程、缓冲区复用、断线重连VisionIntPtr 转 HObject、CopyImage、释放stride、像素格式、HObject 生命周期UIHSmartWindowControl 显示、平移缩放只在 UI 线程操作控件、SetPart 边界目录不用花哨能一眼看出数据往哪走就行。我习惯把相机适配和显示控制分开放MainForm 只做组装VisionDemo/ Camera/ ICameraSource.cs CameraFrameEventArgs.cs VendorCameraSource.cs Vision/ HObjectFactory.cs UI/ MainForm.cs MainForm.Designer.cs DisplayController.cs Program.cs采集层先定义一个接口把厂商 SDK 的具体类型挡在外面。这样 MainForm 不关心你用的是 GigE 相机还是 USB3 相机也不关心 SDK 是回调式还是轮询式public interface ICameraSource : IDisposable { event EventHandlerCameraFrameEventArgs FrameArrived; void Start(); void Stop(); } public sealed class CameraFrameEventArgs : EventArgs { public IntPtr Data { get; set; } // SDK 返回的图像首地址 public int Width { get; set; } // 图像宽 public int Height { get; set; } // 图像高 public int Stride { get; set; } // 一行占多少字节可能大于 Width public bool IsColor { get; set; } // 黑白还是彩色 public long FrameId { get; set; } // 帧号方便丢帧排查 }Data只在回调期间有效订阅方必须在回调返回前完成拷贝或转成 HObject。Stride不能想当然等于Width不少相机为了对齐会补几字节后面GenImage1之前要按行整理。FrameId在排查“画面不动”时很有用日志里帧号一直涨说明相机在出图问题在显示帧号不涨问题在采集或触发。依赖上别贪多WinForms 工程选 x64HalconDotNet 和相机 SDK 的位数必须一致。Halcon 的HSmartWindowControl放在 WinForms 里就是普通控件但它的HWindow句柄要在窗体句柄创建之后再用WPF 下换成HSmartWindowControlWPF坐标逻辑一样事件挂法略有差别。相机 SDK 的 .NET 封装通常要求先初始化 SDK、再枚举设备、再打开设备顺序反了就会报“设备不存在”或者“访问被拒绝”这类错误在日志里只给一个错误码血泪经验是先把 SDK 示例跑通再往工程里搬。3. 相机取图从厂商 SDK 回调到 HObject 的安全转换3.1 初始化与回调只投递帧不在回调里画图相机初始化这一步不同厂商的 API 名字不一样但动作差不多初始化 SDK、枚举设备、打开第 0 台、设置像素格式为 Mono8、关闭硬触发、注册帧回调、开始抓流。下面本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站