C#与Halcon联合编程实现鼠标控制图像缩放、拖动及ROI绘制

一、核心功能实现原理

1. 技术架构

graph TD A[WinForm界面] --> B[HSmartWindowControl控件] B --> C[Halcon图像对象] C --> D[鼠标事件处理] D --> E[缩放/拖动/ROI操作]

2. 关键类库

  • HalconDotNet.dll:Halcon .NET接口
  • hSmartWindowControl:图像显示与交互控件
  • HOperatorSet:图像处理算法集合

二、完整代码实现

1. 环境配置

// 引用Halcon命名空间
using HalconDotNet;
using System.Drawing;
using System.Windows.Forms;

// 初始化Halcon环境
public partial class MainForm : Form {
    private HObject image;
    private HSmartWindowControl hWindow;
    
    public MainForm() {
        InitializeComponent();
        hWindow = new HSmartWindowControl();
        hWindow.Dock = DockStyle.Fill;
        this.Controls.Add(hWindow);
    }
}

2. 图像加载与显示

private void LoadImage(string path) {
    HOperatorSet.ReadImage(out image, path);
    hWindow.HalconWindow.DispObj(image);
    hWindow.HalconWindow.SetPart(0, 0, image.Height, image.Width);
}

3. 鼠标事件处理

// 缩放功能(滚轮事件)
private void hWindow_HMouseWheel(object sender, HMouseEventArgs e) {
    double zoomFactor = e.Delta > 0 ? 1.1 : 0.9;
    hWindow.ZoomImageFactor(zoomFactor, zoomFactor, "constant");
    hWindow.Refresh();
}

// 平移功能(鼠标拖拽)
private Point dragStart;
private void hWindow_MouseDown(object sender, MouseEventArgs e) {
    if (e.Button == MouseButtons.Left) {
        dragStart = e.Location;
    }
}

private void hWindow_MouseMove(object sender, MouseEventArgs e) {
    if (e.Button == MouseButtons.Left) {
        Point delta = new Point(e.X - dragStart.X, e.Y - dragStart.Y);
        hWindow.SetPart(
            hWindow.ActiveWindow.Row1 + delta.Y,
            hWindow.ActiveWindow.Col1 + delta.X,
            hWindow.ActiveWindow.Row2 + delta.Y,
            hWindow.ActiveWindow.Col2 + delta.X
        );
        hWindow.Refresh();
    }
}

4. ROI绘制与管理

// 创建ROI
private void CreateRectangleROI() {
    HOperatorSet.GenRectangle1(out HObject roi, 100, 100, 200, 200);
    hWindow.AttachDrawingObjectToWindow(roi);
    hWindow.SetColor("red");
    hWindow.DispObj(roi);
}

// ROI事件处理
private void hWindow_DrawingObjectSelected(object sender, HDrawingObjectEventArgs e) {
    HObject selectedROI = e.DrawingObject;
    double row, col;
    HOperatorSet.GetRectangle1(selectedROI, out row, out col, out _, out _);
    MessageBox.Show($"选中ROI位置:({row}, {col})");
}

// ROI拖拽移动
private void hWindow_DrawingObjectDragged(object sender, HDrawingObjectEventArgs e) {
    HObject movedROI = e.DrawingObject;
    HOperatorSet.SetRectangle1(movedROI, 150, 150, 250, 250);
    hWindow.Refresh();
}

三、高级功能扩展

1. 双缓冲防闪烁

public class DoubleBufferedHWindow : HSmartWindowControl {
    public DoubleBufferedHWindow() {
        this.DoubleBuffered = true;
        this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
    }
}

2. ROI属性保存

[Serializable]
public class ROIData {
    public string Type { get; set; }
    public double[] Coordinates { get; set; }
    public Color Color { get; set; }
}

// 保存ROI到XML
public void SaveROI(ROIData data) {
    XmlSerializer serializer = new XmlSerializer(typeof(ROIData));
    using (FileStream fs = new FileStream("roi.xml", FileMode.Create)) {
        serializer.Serialize(fs, data);
    }
}

3. 批量ROI操作

public void BatchProcessROI(List<HObject> rois) {
    foreach (var roi in rois) {
        HOperatorSet.ReduceDomain(image, roi, out HObject subImage);
        // 执行图像处理操作
    }
}

四、性能优化策略

1. 图像分块加载

private void LoadLargeImage(string path) {
    using (FileStream fs = new FileStream(path, FileMode.Open)) {
        byte[] buffer = new byte[1024 * 1024]; // 1MB分块
        int bytesRead;
        while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) {
            HOperatorSet.GenImage1(out image, "byte", 
                (Hlong)(fs.Length / 1024), (Hlong)1024, 
                (Hlong)(fs.Position / 1024), buffer);
            hWindow.Refresh();
        }
    }
}

2. 异步处理

private async Task ProcessImageAsync() {
    await Task.Run(() => {
        HOperatorSet.Threshold(image, out HObject region, 128, 255);
        this.Invoke((MethodInvoker)delegate {
            hWindow.DispObj(region);
        });
    });
}

五、调试与测试

1. 坐标转换工具

public void ShowMousePosition() {
    int x, y;
    hWindow.HalconWindow.GetMposition(out x, out y, out _);
    lblPosition.Text = $"坐标:({x}, {y})";
}

2. 性能监控

Stopwatch sw = new Stopwatch();
sw.Start();
hWindow.Refresh();
sw.Stop();
Console.WriteLine($"刷新耗时:{sw.ElapsedMilliseconds}ms");

六、界面设计示例

1. 主界面布局

+---------------------------------+
| 工具栏                        |
| [加载] [保存] [ROI设置]        |
+---------------------------------+
| 图像显示区 (HSmartWindowControl)|
| 缩放: 100% 平移: 0,0           |
+---------------------------------+
| ROI列表                       |
| 1. 矩形ROI (100,100)-(200,200) |
+---------------------------------+

2. ROI操作菜单

ContextMenuStrip roiMenu = new ContextMenuStrip();
roiMenu.Items.Add("删除", null, (s,e) => {
    hWindow.DeleteDrawingObject(hWindow.GetSelectedObject());
});

七、完整项目结构

HalconImageProcessing/
├── Controls/
│   ├── DoubleBufferedHWindow.cs
│   └── ROIListControl.cs
├── Forms/
│   ├── MainForm.cs
│   └── SettingsForm.cs
├── Models/
│   ├── ROIData.cs
│   └── ImageProcessor.cs
└── Resources/
    ├── halcon.dll
    └── icons/

八、扩展学习资源

  1. 官方网页
    • Halcon .NET接口手册 www.mvtec.com/support/manuals/halcon/en/
    • C#事件处理最佳实践 docs.microsoft.com/en-us/dotnet/desktop/winforms/events/
  2. 项目参考
    • halcon与C#联合编程之鼠标控制图片缩放,拖动,roi www.youwenfan.com/contentcnf/93613.html

通过上述方案,开发者可以构建专业级图像处理系统,支持从基础交互到复杂算法集成的完整需求。建议结合具体应用场景优化ROI交互逻辑,并定期进行内存泄漏检测(使用GC.Collect()和内存分析工具)。

posted @ 2025-09-02 17:10  风一直那个吹  阅读(433)  评论(0)    收藏  举报