
Halcon视觉项目实战HSmartWindowControl与WPF构建ROI模板截取工具在工业视觉检测领域快速提取图像中的关键区域是算法开发的第一步。传统Halcon开发往往停留在脚本层面而将核心功能封装为可视化工具能显著提升工程效率。本文将完整演示如何利用HSmartWindowControl控件与WPF框架构建一个具备交互式ROI绘制、图像截取与保存功能的桌面工具。1. 环境搭建与基础配置1.1 WPF项目初始化首先创建WPF项目并集成Halcon库!-- 在NuGet包管理器控制台执行 -- Install-Package HalconDotNetXAML前端需引入HSmartWindowControl控件Window xmlns:halconclr-namespace:HalconDotNet;assemblyhalcondotnet TitleROI截取工具 Height600 Width800 Grid halcon:HSmartWindowControlWPF NamehswControl HDoubleClickToFitContentTrue HZoomContentWheelForwardZoomsIn/ /Grid /Window1.2 图像加载基础逻辑后端代码实现图像加载与显示private HImage _currentImage new HImage(); private void LoadImage(string path) { _currentImage.ReadImage(path); hswControl.HalconWindow.DispImage(_currentImage); // 自动调整窗口适应图像 hswControl.SetFullImagePart(_currentImage); }提示HSmartWindowControl的SetFullImagePart方法能自动调整视窗比例避免图像显示不全的问题2. 交互式ROI绘制模块2.1 HDrawingObject动态创建支持多种ROI类型的选择创建public enum RoiType { Rectangle1, Rectangle2, Circle, Ellipse } private HDrawingObject CreateRoi(RoiType type, HTuple row, HTuple col) { var drawingObj type switch { RoiType.Rectangle1 HDrawingObject.CreateDrawingObject( HDrawingObject.HDrawingObjectType.RECTANGLE1, row, col, row100, col100), RoiType.Circle HDrawingObject.CreateDrawingObject( HDrawingObject.HDrawingObjectType.CIRCLE, row, col, 50), _ throw new NotImplementedException() }; hswControl.HalconWindow.AttachDrawingObjectToWindow(drawingObj); return drawingObj; }2.2 ROI交互事件处理为ROI添加动态响应事件private void SetupRoiCallbacks(HDrawingObject drawingObj) { drawingObj.OnDrag(OnRoiMoved); drawingObj.OnResize(OnRoiMoved); drawingObj.OnAttach(OnRoiAttached); drawingObj.OnSelect(OnRoiSelected); } private void OnRoiMoved(HDrawingObject sender) { var param sender.GetDrawingObjectParams(new HTuple(row1,column1,row2,column2)); Debug.WriteLine($ROI位置更新: {param}); }3. 图像截取与保存功能3.1 精确区域截取技术实现ROI区域图像提取public HImage ExtractRoiImage(HDrawingObject roi) { try { var coordinates roi.GetDrawingObjectParams(new HTuple(row1,column1,row2,column2)); using (var region new HRegion()) { region.GenRectangle1(coordinates[0], coordinates[1], coordinates[2], coordinates[3]); return _currentImage.ReduceDomain(region); } } catch (HalconException ex) { MessageBox.Show($截取失败: {ex.Message}); return null; } }3.2 多格式保存方案支持常见图像格式输出格式质量参数适用场景PNG0-100无损保存JPEG0-100有损压缩TIFF压缩类型高保真存档BMP无兼容性要求场景保存功能实现代码public bool SaveRoiImage(HImage roiImage, string path, string formatpng, int quality90) { try { roiImage.WriteImage(format, quality, path); return File.Exists(path); } catch { return false; } }4. WPF界面优化实践4.1 响应式布局设计优化工具操作流程的界面布局DockPanel ToolBar DockPanel.DockTop ComboBox x:NamecmbRoiType SelectedIndex0 ComboBoxItem Content矩形(平行轴)/ ComboBoxItem Content旋转矩形/ ComboBoxItem Content圆形/ /ComboBox Button Content截取ROI ClickOnExtractClick/ Button Content保存图像 ClickOnSaveClick/ /ToolBar StatusBar DockPanel.DockBottom TextBlock x:NametxtStatus/ /StatusBar halcon:HSmartWindowControlWPF NamehswControl/ /DockPanel4.2 异步操作处理防止图像处理阻塞UI线程private async void OnExtractClick(object sender, RoutedEventArgs e) { txtStatus.Text 正在处理...; var roiImage await Task.Run(() ExtractRoiImage(_currentRoi)); if (roiImage ! null) { _previewWindow?.Close(); _previewWindow new ImagePreviewWindow(roiImage); _previewWindow.Show(); txtStatus.Text ROI截取完成; } }5. 高级功能扩展5.1 ROI模板记忆功能实现ROI参数的保存与加载public class RoiTemplate { public string Name { get; set; } public RoiType Type { get; set; } public double[] Coordinates { get; set; } } public void SaveTemplate(string path, RoiTemplate template) { var json JsonConvert.SerializeObject(template); File.WriteAllText(path, json); } public RoiTemplate LoadTemplate(string path) { var json File.ReadAllText(path); return JsonConvert.DeserializeObjectRoiTemplate(json); }5.2 多ROI并行管理支持同时操作多个ROI区域private readonly Dictionarystring, HDrawingObject _roiDictionary new(); public void AddRoi(string name, RoiType type) { if (_roiDictionary.ContainsKey(name)) return; var roi CreateRoi(type, 100, 100); _roiDictionary.Add(name, roi); // 为每个ROI设置不同颜色 roi.SetDrawingObjectParams(color, GetUniqueColor(name)); } private string GetUniqueColor(string seed) { var hash seed.GetHashCode(); return $#{(hash 0xFF):X2}{(hash 8 0xFF):X2}{(hash 16 0xFF):X2}; }6. 性能优化技巧6.1 图像显示加速方案针对大尺寸图像的优化策略金字塔处理对大于4K的图像生成金字塔层区域渲染只重绘视窗可见区域缓存机制预存缩放级别的图像数据实现代码示例private void OptimizeForLargeImage(HImage image) { if (image.GetImageSize() 4096*4096) { var pyramid image.GenPyramidImages(2, reduce); hswControl.HalconWindow.DispImage(pyramid); } else { hswControl.HalconWindow.DispImage(image); } }6.2 内存管理最佳实践Halcon对象生命周期管理要点及时释放对临时HImage、HRegion等对象使用using语句批量处理减少Halcon引擎与.NET间的数据交换异常处理确保异常情况下资源仍被释放典型内存泄漏排查模式try { using (var tempImage _currentImage.CropPart(...)) { // 处理代码 } } finally { GC.Collect(); HalconAPI.GetThreadAllocatedMemory(out var allocated); Debug.WriteLine($当前内存使用: {allocated/1024}KB); }