Halcon视觉项目实战:5分钟打造高效ROI模板工具
在工业视觉项目开发中,快速创建和调整ROI(Region of Interest)区域是每个工程师的日常需求。传统方法往往需要反复修改代码参数,而借助Halcon的HSmartWindowControl控件与HDrawingObject对象,我们可以实现所见即所得的交互式ROI操作。本文将带您从零开始构建一个完整的模板创建工具,涵盖图像加载、ROI绘制、参数提取到模板保存的全流程。
1. 环境搭建与基础配置
1.1 WPF项目初始化
首先创建一个WPF项目,通过NuGet添加HalconDotNet包引用。在MainWindow.xaml中配置HSmartWindowControlWPF控件:
<Window xmlns:HalconDotNet="clr-namespace:HalconDotNet;assembly=halcondotnet" Title="Halcon ROI工具" Height="600" Width="800"> <Grid> <HalconDotNet:HSmartWindowControlWPF Name="hswControl" HDoubleClickToFitContent="True" HZoomContent="MouseWheel" Margin="5"/> <StackPanel Orientation="Vertical" HorizontalAlignment="Right"> <Button Content="创建矩形ROI" Click="BtnCreateRect_Click"/> <Button Content="保存模板" Click="BtnSaveTemplate_Click"/> </StackPanel> </Grid> </Window>1.2 核心对象初始化
在代码后台声明关键对象并实现图像加载:
private HImage _currentImage = new HImage(); private HDrawingObject _drawingObject; private void Window_Loaded(object sender, RoutedEventArgs e) { _currentImage.ReadImage("demo.png"); hswControl.HalconWindow.DispImage(_currentImage); }2. 交互式ROI创建与调整
2.1 动态ROI生成
传统DrawRectangle1方法在HSmartWindowControl中不可用,改用HDrawingObject实现:
private void BtnCreateRect_Click(object sender, RoutedEventArgs e) { // 清除现有ROI if (_drawingObject != null && _drawingObject.IsInitialized()) _drawingObject.Dispose(); // 获取图像尺寸 _currentImage.GetImageSize(out int width, out int height); // 创建居中矩形ROI(占图像面积50%) _drawingObject = HDrawingObject.CreateDrawingObject( HDrawingObject.HDrawingObjectType.RECTANGLE1, height * 0.25, width * 0.25, height * 0.75, width * 0.75); // 绑定到显示窗口 hswControl.HalconWindow.AttachDrawingObjectToWindow(_drawingObject); }2.2 ROI交互优化
通过HDrawingObject的回调机制增强用户体验:
_drawingObject.OnDrag(OnDrawingObjectMoved); _drawingObject.OnResize(OnDrawingObjectMoved); private void OnDrawingObjectMoved(HDrawingObject sender) { // 实时显示ROI坐标 var param = sender.GetDrawingObjectParams(new HTuple("row1","column1","row2","column2")); Debug.WriteLine($"当前ROI位置: ({param[0]},{param[1]}) - ({param[2]},{param[3]})"); }3. 模板提取与保存
3.1 区域提取技术
获得ROI参数后,可进行多种图像处理操作:
private void BtnSaveTemplate_Click(object sender, RoutedEventArgs e) { if (_drawingObject == null || !_drawingObject.IsInitialized()) { MessageBox.Show("请先创建ROI区域"); return; } // 获取ROI参数 HTuple param = _drawingObject.GetDrawingObjectParams( new HTuple("row1","column1","row2","column2")); // 生成区域并裁剪图像 HRegion roiRegion = new HRegion(); roiRegion.GenRectangle1(param[0].D, param[1].D, param[2].D, param[3].D); HImage templateImage = _currentImage.ReduceDomain(roiRegion); // 保存模板 string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss"); templateImage.WriteImage("png", 0, $"template_{timestamp}.png"); MessageBox.Show("模板保存成功!"); }3.2 性能优化技巧
对于高分辨率图像,建议添加以下优化:
// 在图像加载时添加 hswControl.SetFullImagePart(_currentImage); hswControl.HalconWindow.SetPart(0, 0, -2, -2); // 自动适应窗口大小 // 在ROI操作时临时关闭图形更新 hswControl.HalconWindow.SetWindowAttr("flush","false"); // ...ROI操作代码... hswControl.HalconWindow.SetWindowAttr("flush","true"); hswControl.HalconWindow.DispImage(_currentImage);4. 项目实战扩展
4.1 多ROI支持
通过列表管理多个ROI对象:
private List<HDrawingObject> _roiList = new List<HDrawingObject>(); private void AddNewROI(HDrawingObject.HDrawingObjectType type) { var roi = HDrawingObject.CreateDrawingObject(type, 100, 100, 200, 200); hswControl.HalconWindow.AttachDrawingObjectToWindow(roi); _roiList.Add(roi); // 为每个ROI设置唯一颜色 roi.SetDrawingObjectParams("color", GetRandomColor()); } private string GetRandomColor() { var colors = new[] {"green", "blue", "red", "yellow", "cyan"}; return colors[_roiList.Count % colors.Length]; }4.2 高级形状支持
除了矩形,还可扩展其他ROI类型:
| ROI类型 | 创建方法 | 典型应用场景 |
|---|---|---|
| RECTANGLE1 | CreateDrawingObject(RECTANGLE1, row1, col1, row2, col2) | 常规物体定位 |
| RECTANGLE2 | CreateDrawingObject(RECTANGLE2, row, col, phi, length1, length2) | 旋转物体检测 |
| CIRCLE | CreateDrawingObject(CIRCLE, row, col, radius) | 圆形特征检测 |
| ELLIPSE | CreateDrawingObject(ELLIPSE, row, col, phi, radius1, radius2) | 椭圆匹配 |
实现多形状选择界面:
<ComboBox x:Name="cmbRoiType" SelectedIndex="0"> <ComboBoxItem Content="矩形"/> <ComboBoxItem Content="旋转矩形"/> <ComboBoxItem Content="圆形"/> </ComboBox> private void CreateSelectedRoi() { var type = cmbRoiType.SelectedIndex switch { 0 => HDrawingObject.HDrawingObjectType.RECTANGLE1, 1 => HDrawingObject.HDrawingObjectType.RECTANGLE2, _ => HDrawingObject.HDrawingObjectType.CIRCLE }; AddNewROI(type); }5. 工程化实践建议
5.1 配置保存与加载
实现ROI配置的序列化存储:
public class RoiConfig { public string Type { get; set; } public double[] Parameters { get; set; } public string Color { get; set; } } private void SaveConfig(string filePath) { var configs = _roiList.Select(roi => new RoiConfig { Type = roi.GetDrawingObjectParams("type").S, Parameters = (double[])roi.GetDrawingObjectParams("all"), Color = roi.GetDrawingObjectParams("color").S }).ToList(); File.WriteAllText(filePath, JsonConvert.SerializeObject(configs)); }5.2 异常处理机制
关键操作添加健壮性处理:
try { _currentImage.GetImageSize(out width, out height); // ...ROI操作代码... } catch (HalconException hex) { MessageBox.Show($"Halcon错误: {hex.Message}"); } catch (Exception ex) { MessageBox.Show($"系统错误: {ex.Message}"); } finally { hswControl.HalconWindow.SetWindowAttr("flush","true"); }在实际项目中,这套工具帮助我们将模板创建时间从原来的15-20分钟缩短到2-3分钟。特别是在需要反复调整ROI位置的场景中,交互式操作比传统代码修改效率提升显著。