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"));
参数说明:
HDevEngine: Halcon脚本引擎类。管理.hdev脚本和外部过程的加载与执行。SetProcedurePath: 设置外部过程(.hdvp文件)的搜索路径。HDevProcedure: 表示一个Halcon过程(函数)。HDevProcedureCall: 过程调用实例,用于设置输入参数、执行过程、获取输出结果。
工作原理: HDevEngine在C#进程中嵌入一个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);
参数说明:
HOperatorSet:静态类。包含所有Halcon算子的.NET封装方法。方法名与Halcon算子名一致(首字母大写,下划线保留)。HTuple:Halcon元组类型。可以存储单个值或数组,支持整数、浮点、字符串、句柄等多种类型。C#中所有Halcon变量都使用HTuple。out:C#输出参数关键字。Halcon算子的输出参数在C#中对应out参数。
工作原理: HalconDotNet.dll是Halcon C++库的.NET COM封装。HOperatorSet中的每个静态方法对应一个Halcon算子,方法内部将.NET数据类型转换为Halcon内部类型,调用C++库执行算子,再将结果转换回.NET类型。由于使用了P/Invoke或COM互操作,调用有一定开销,但对于大多数工业视觉应用,性能影响可忽略。
最佳实践: 使用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);
参数说明:
HWindowControl:WinForms图像显示控件,继承自UserControl。HalconWindow: 控件内部的Halcon窗口句柄(HWindow类型),用于DispImage、DispRegion、DispCircle等显示算子。
工作原理: HWindowControl在WinForms窗体中创建一个Halcon原生渲染窗口,支持Halcon的所有显示功能(图像、Region、XLD、文字、几何图形)。显示操作通过HalconWindow句柄执行,渲染由Halcon原生完成,效率高且与HDevelop中的显示效果一致。
关键技巧: 使用set_part设置显示区域(缩放/平移);使用set_color、set_draw设置显示颜色/样式;多窗口场景可为每个HWindowControl分配独立的HalconWindow句柄。WPF项目可使用HSmartWindowControlWPF控件。