halcon核心-C# 联合编程(十一)

C# 联合编程

VM / VPP 对照

VM / VPP 操作 Halcon 方案 核心区别
VM 直接生成可执行程序或部署到工控机 HDevelop 调试 → 导出 .hdev → C# 调用 HDevEngine Halcon 脚本不能独立运行,必须封装到 C# 上位机才能交付

核心思路:两种集成方式

css 复制代码
* 方式A:HDevEngine 调用外部脚本(推荐,调试方便)
* 步骤1: 创建HDevEngine引擎实例
HDevEngine engine = new HDevEngine();
* 步骤2: 设置脚本搜索路径
engine.SetProcedurePath("./halcon_scripts");
* 步骤3: 加载指定脚本
HDevProcedure proc = new HDevProcedure("inspect_pill");
* 步骤4: 创建调用实例
HDevProcedureCall call = new HDevProcedureCall(proc);

* 步骤5: 传入输入参数
call.SetInputCtrlParamTuple("ImagePath", "pill_001.png");
call.SetInputCtrlParamTuple("MinArea", 800);

* 步骤6: 执行脚本
call.Execute();
* 步骤7: 获取输出结果
HTuple count = call.GetOutputCtrlParamTuple("Count");
HTuple row = call.GetOutputCtrlParamTuple("Row");

* 方式B:直接调用 HalconDotNet 算子(性能更好)
* 步骤1: 声明Halcon图像对象
HObject image, gray, region;
* 步骤2: 读取图像 ------ 调用Halcon算子的C#封装版本
HOperatorSet.ReadImage(out image, "pill_001.png");
* 步骤3: 转灰度
HOperatorSet.Rgb1ToGray(image, out gray);
* 步骤4: 阈值分割
HOperatorSet.Threshold(gray, out region, 128, 255);

🔬 接口详解与原理

核心思路: C#与Halcon联合编程的本质是"用C#做框架,Halcon做视觉"。C#负责UI界面、业务逻辑、数据通信、设备控制;Halcon负责图像采集、算法处理、结果输出。两者通过HalconDotNet.dll提供的.NET封装层交互,上层C#代码调用HOperatorSet中的静态方法直接执行Halcon算子,或通过HDevEngine加载执行外部.hdev脚本。VM/VPP将算法和界面封装为一体化平台,而C#+Halcon方案更灵活,适合需要深度定制UI和业务流程的项目。

接口/类 VM / VPP 对应 核心作用
HDevEngine 脚本引擎 → 加载外部算法 在C#程序中加载并执行.hdev脚本文件,实现算法与业务分离
HOperatorSet 算子调用 → 直接执行Halcon算子 提供所有Halcon算子的静态方法封装,C#中直接调用如HOperatorSet.ReadImage(...)
HWindowControl 图像显示控件 → 可视化结果 WinForms/WPF图像显示控件,用于在C#窗体中显示Halcon图像和Region
HTuple 数据类型 → 元组变量 Halcon的元组类型在C#中的封装,支持整数、浮点、字符串混合数组

① HDevEngine --- 脚本引擎

ini 复制代码
HDevEngine engine = new HDevEngine();
engine.SetProcedurePath(@"C:\HalconScripts");
HDevProcedureCall proc = new HDevProcedureCall(new HDevProcedure(engine, "detect_defects"));

参数说明:

  1. HDevEngine: Halcon脚本引擎类。管理.hdev脚本和外部过程的加载与执行。
  2. SetProcedurePath: 设置外部过程(.hdvp文件)的搜索路径。
  3. HDevProcedure: 表示一个Halcon过程(函数)。
  4. HDevProcedureCall: 过程调用实例,用于设置输入参数、执行过程、获取输出结果。

工作原理: HDevEngineC#进程中嵌入一个Halcon解释器,可以加载和执行.hdev脚本文件中的程序。这种方式将视觉算法封装为外部脚本,C#代码只需调用脚本并传递参数,无需在C#中写大量算子代码。优势是算法工程师可以在HDevelop中独立调试算法,调试完成后直接给C#调用,实现算法与软件的解耦。

适用场景: 算法频繁变更的项目;算法由视觉工程师维护、软件由开发工程师维护的团队协作模式。

注意: HDevEngine需要Halcon Runtime许可证,且脚本执行效率略低于直接调用HOperatorSet

② HOperatorSet --- 直接算子调用

ini 复制代码
HTuple hv_Image = new HTuple();
HOperatorSet.ReadImage(out hv_Image, "pcb_board.png");
HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
HOperatorSet.GetImageSize(hv_Image, out hv_Width, out hv_Height);

参数说明:

  1. HOperatorSet: 静态类。包含所有Halcon算子的.NET封装方法。方法名与Halcon算子名一致(首字母大写,下划线保留)。
  2. HTuple: Halcon元组类型。可以存储单个值或数组,支持整数、浮点、字符串、句柄等多种类型。C#中所有Halcon变量都使用HTuple。
  3. out: C#输出参数关键字。Halcon算子的输出参数在C#中对应out参数。

工作原理: HalconDotNet.dllHalcon C++库的.NET COM封装。HOperatorSet中的每个静态方法对应一个Halcon算子,方法内部将.NET数据类型转换为Halcon内部类型,调用C++库执行算子,再将结果转换回.NET类型。由于使用了P/InvokeCOM互操作,调用有一定开销,但对于大多数工业视觉应用,性能影响可忽略。

最佳实践: 使用using HTuple = HalconDotNet.HTuple;简化代码;对于大量重复调用,考虑用HDevEngine批量执行;注意HTuple的内存释放,及时调用.Dispose()或使用using语句。

③ HWindowControl --- 图像显示控件

ini 复制代码
HWindowControl hWindow = new HWindowControl();
hWindow.Dock = DockStyle.Fill;
this.Controls.Add(hWindow);
HOperatorSet.DispImage(hv_Image, hWindow.HalconWindow);

参数说明:

  1. HWindowControl: WinForms图像显示控件,继承自UserControl
  2. HalconWindow: 控件内部的Halcon窗口句柄(HWindow类型),用于DispImageDispRegionDispCircle等显示算子。

工作原理: HWindowControlWinForms窗体中创建一个Halcon原生渲染窗口,支持Halcon的所有显示功能(图像、Region、XLD、文字、几何图形)。显示操作通过HalconWindow句柄执行,渲染由Halcon原生完成,效率高且与HDevelop中的显示效果一致。

关键技巧: 使用set_part设置显示区域(缩放/平移);使用set_colorset_draw设置显示颜色/样式;多窗口场景可为每个HWindowControl分配独立的HalconWindow句柄。WPF项目可使用HSmartWindowControlWPF控件。

相关推荐
元界metalite2 小时前
SpringBoot整合Druid-连接池参数为什么不能照抄
后端
fatcoder2 小时前
玩转Nginx 09 — 运维排障:三场"火灾"实战演练
前端·后端·nginx
元界metalite2 小时前
MyBatis通用查询如何避免SELECT *?MetaLite如何按需返回字段
后端
Flynt2 小时前
Go 1.27 升了一波,泛型方法和 JSON v2 真香但有个坑
后端·go
我会冲击波3 小时前
vibe coding 一个多月,我把 Claude Code + Pi 做成了桌面 IDE,还给它移植了 VS Code 的编辑体验
前端·javascript·后端
我是谁的程序员3 小时前
Windows / Linux / Mac 上不用 Xcode 把 IPA 上传到 App Store,upload 命令详解
后端·ios
凌涘3 小时前
JWT 登录鉴权 Demo 拆解
后端
JimmtButler3 小时前
从 Java 到 JS:我终于把闭包想明白了
javascript·后端
掘金者阿豪4 小时前
Codex 怎么突然变慢了?一个需求跑几十分钟,我才发现它的工作方式已经变了
前端·后端