基于WPF&Opencv 高级显示控件2.0 全新优化,支持图像拖入显示,使用wpf的adnoner和thumb实现可交互的绘图对象。

一、控件概述

基于WPF&OpenCV的高级显示控件2.0是一款面向图像可视化与交互操作的专业控件库,采用.NET Framework 4.8框架开发,融合WPF的高效UI渲染能力与OpenCV的强大图像处理功能。控件支持图像拖入显示、多类型绘图对象交互、图像特效处理等核心功能,通过WPF的Adorner和Thumb组件实现绘图对象的拖拽、缩放、旋转等交互操作,适用于机器视觉、图像分析、工业检测等场景。

二、核心技术架构

(一)技术栈选型

技术类别 核心组件/框架 作用说明
UI框架 WPF(Windows Presentation Foundation) 提供可视化界面、控件布局、Adorner装饰器、Thumb交互组件支持
图像处理 OpenCvSharp4(OpenCV的.NET封装) 实现图像读取、格式转换、边缘检测(Sobel算子)、几何绘图等功能
开发框架 .NET Framework 4.8 提供稳定的运行时环境,兼容Windows系统主流版本
辅助组件 System.Drawing 支持位图操作、图形绘制等底层功能

(二)核心模块划分

控件库采用模块化设计,主要包含以下核心模块:

  1. 图像显示与交互模块:负责图像加载、拖入显示、缩放平移、鼠标事件响应;
  2. 绘图对象模块:提供圆形、矩形、旋转矩形、直线、多边形等可交互绘图对象;
  3. 图像处理模块:集成Sobel边缘检测、图像格式转换、几何图形绘制等功能;
  4. 交互控制模块:通过Adorner和Thumb实现绘图对象的拖拽、缩放、旋转交互;
  5. 数据绑定模块:采用MVVM模式的ViewModel层,实现UI与数据的双向绑定。

三、核心功能详解

(一)图像加载与显示

1. 加载方式
  • 拖入加载:支持将本地图像文件直接拖入控件窗口完成加载,支持主流图像格式(BMP、PNG、JPG等);
  • 路径加载:通过LoadBitmapImageLoadMat方法传入文件路径加载图像;
  • 格式支持:兼容OpenCV的Mat格式与System.Drawing的Bitmap格式,支持格式互转。
2. 显示特性
  • 自适应显示:图像加载后自动适配控件尺寸,保持宽高比不变;
  • 缩放平移:支持鼠标滚轮缩放、鼠标拖拽平移图像;
  • 图像信息显示:实时显示图像尺寸、通道数、鼠标位置及对应像素的BGR值。

(二)绘图对象交互

控件支持5种核心绘图对象,所有对象均支持拖拽移动、样式自定义,部分支持缩放、旋转等扩展操作:

1. 绘图对象类型及功能
绘图对象 核心参数 交互能力 特色功能
圆形(CircleDrawingObject) 圆心坐标(CenterX/CenterY)、半径(Radius) 拖拽移动、半径缩放 支持Sobel边缘检测回调,鼠标拖拽时实时显示边缘效果
矩形(RectDrawingObject) 左上角坐标(Left/Top)、宽高(Width/Height) 拖拽移动、边缘缩放 支持文本叠加显示,可自定义文本内容、字体、颜色
旋转矩形(Rect2DrawingObject) 中心坐标、宽高、旋转角度(Angle) 拖拽移动、宽高缩放、角度旋转 旋转角度范围支持-360°~360°,保持中心位置不变
直线(LineDrawingObject) 起点坐标(StartX/StartY)、终点坐标(EndX/EndY) 拖拽移动、端点调整 支持直线两端点独立拖拽调整,保持线宽不变
多边形(PolygonDrawingObject) 顶点集合(Points)、质心坐标(CentroidX/CentroidY) 拖拽移动、顶点编辑、添加顶点 支持随机添加顶点、顶点拖拽调整,自动计算质心位置
2. 交互操作实现
  • 拖拽机制:通过WPF的Thumb组件捕获鼠标事件,结合DragDelta事件计算拖拽偏移量,更新绘图对象坐标;
  • 缩放机制:在绘图对象边缘设置缩放手柄(Thumb),根据手柄位置计算缩放比例,实时更新对象尺寸;
  • 旋转机制:旋转矩形专属旋转手柄,通过计算鼠标移动角度差更新对象旋转角度;
  • 装饰器(Adorner):使用AdornerLayer为每个绘图对象添加装饰层,显示交互手柄(如中心手柄、缩放手柄、旋转手柄),不影响底层图像显示。

(三)图像处理功能

1. Sobel边缘检测
  • 针对圆形绘图对象提供Sobel边缘检测功能,勾选"Sobel"复选框后,拖拽圆形对象时,将对圆形区域内的图像进行边缘检测并实时显示;
  • 实现逻辑:先将图像转为灰度图,通过Sobel算子计算边缘,再与原图像叠加显示边缘效果。
2. 图像绘制

支持在图像上绘制几何图形,包括:

  • 基础图形:直线、矩形、圆形、椭圆、圆弧;
  • 复杂图形:旋转矩形、多边形、箭头、标记点(支持十字、星型、菱形等7种标记类型);
  • 文本绘制:支持自定义文本内容、字体、大小、颜色,可叠加在图像指定位置。
3. 图像格式转换

提供多种格式转换工具类(ImageConvertor),支持:

  • Bitmap与WriteableBitmap互转;
  • Bitmap与OpenCV Mat互转;
  • 支持灰度图、彩色图、索引图等多种格式适配。

(四)样式自定义与控制

1. 绘图对象样式
  • 颜色自定义:通过下拉框选择绘图对象的边框颜色(红、绿、蓝);
  • 线宽自定义:通过文本框输入数值设置绘图对象的边框厚度;
  • 填充控制:支持图形填充(如圆形、矩形),可通过参数控制是否填充。
2. 控件控制功能
控制功能 操作方式 作用说明
清空绘图对象 点击"清空绘图对象"按钮 移除所有已添加的绘图对象,保留图像显示
清空窗口 点击"清空窗口"按钮 移除图像及所有绘图对象,重置控件状态
保存图像 右键菜单"SaveImage" 将当前显示的图像(含绘图对象叠加)保存为本地文件
适应图像显示 右键菜单"AdaptiveDisplay" 自动调整图像缩放比例,使图像完整适配控件窗口

四、关键代码解析

(一)绘图对象交互核心代码

以圆形绘图对象的拖拽交互为例,通过Thumb的DragDelta事件实现位置更新:

internal override void ThumbDrag(object sender, DragDeltaEventArgs e)
{
    ThumbTag thumbTag = (ThumbTag)(sender as HandleThumb).Tag;
    if (thumbTag == ThumbTag.Center)// 中心手柄拖拽(移动)
    {
        Vector pImgChanged = PosToImageCoordinate<Vector, Point>(new Point(e.HorizontalChange, e.VerticalChange));
        Point pCenter = Point.Add(new Point(mCenterX, mCenterY), pImgChanged);
        mCenterX = pCenter.X;
        mCenterY = pCenter.Y;
        UpdateShapePos();// 更新图形位置
        OnDrag?.Invoke(CallBackType.OnDrag, this);// 触发拖拽回调
    }
    else if (thumbTag == ThumbTag.CenterRight)// 右侧手柄拖拽(缩放半径)
    {
        double dRImgChange = PosToImageCoordinate<Point, Point>(new Point(e.HorizontalChange, e.HorizontalChange)).X;
        mRadius += dRImgChange;
        mRadius = Math.Max(mRadius, 0);// 半径不小于0
        UpdateShapePos();// 更新图形尺寸
        OnResize?.Invoke(CallBackType.OnResize, this);// 触发缩放回调
    }
}

(二)Sobel边缘检测实现

在圆形绘图对象拖拽回调中集成边缘检测:

private void DrawObjCallback(DrawingObject.CallBackType callBackType, DrawingObject drawingObject)
{
    if (drawingObject is CircleDrawingObject circleObj && SobelcheckBox.IsChecked == true)
    {
        circleObj.GetDrawingObjectParam((int)CircleDrawingObject.Param.CenterX, out double dCenterX);
        circleObj.GetDrawingObjectParam((int)CircleDrawingObject.Param.CenterY, out double dCenterY);
        circleObj.GetDrawingObjectParam((int)CircleDrawingObject.Param.Radius, out double dR);
        
        if (_src == null)
        {
            _src = WindowControl.GetDisplay<OpenCvSharp.Mat>();
            if (_src.Channels() > 1)
            {
                OpenCvSharp.Cv2.CvtColor(_src, _src, OpenCvSharp.ColorConversionCodes.BGR2GRAY);
                WindowControl.Display(_src);
            }
        }
        OpenCvSharp.Mat sobelMat = SobelMat(_src, new Point(dCenterX, dCenterY), dR);
        WindowControl.Display(sobelMat);
    }
}

// Sobel边缘检测核心方法
private OpenCvSharp.Mat SobelMat(OpenCvSharp.Mat mat, Point pCenter, double dR)
{
    // 1. 创建掩码,仅处理圆形区域内的图像
    OpenCvSharp.Mat mask = OpenCvSharp.Mat.Ones(mat.Size(), OpenCvSharp.MatType.CV_8UC1);
    OpenCvSharp.Cv2.Circle(mask, (int)pCenter.X, (int)pCenter.Y, (int)dR, OpenCvSharp.Scalar.All(0), -1);
    // 2. 提取圆形区域ROI(感兴趣区域)
    OpenCvSharp.Mat matRoi = OpenCvSharp.Mat.Zeros(mat.Size(), mat.Type());
    mat.CopyTo(matRoi, mask);
    // 3. Sobel算子边缘检测
    OpenCvSharp.Cv2.Scharr(matRoi, matRoi, -1, 1, 0);
    // 4. 与原图像叠加显示
    OpenCvSharp.Mat outMat = new OpenCvSharp.Mat(mat.Size(), mat.Type());
    OpenCvSharp.Cv2.Add(mat, matRoi, outMat);
    return outMat;
}

(三)图像拖入加载实现

通过WPF的DragDrop事件实现图像拖入加载:

private void rootCanvas_Drop(object sender, DragEventArgs e)
{
    try
    {
        string fileName = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
        LoadBitmapImage(fileName);
        // 适配图像显示尺寸
        viewModel.UpdateImageCanvas(UpdateImageCanvasProperty.ControlSize, rootCanvas.ActualHeight, rootCanvas.ActualWidth);
        viewModel.UpdateImageCanvas(UpdateImageCanvasProperty.LeftTopPos, new Size(rootCanvas.ActualWidth, rootCanvas.ActualHeight));
        ClearDisplay();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

五、使用指南

(一)环境配置

  1. 安装.NET Framework 4.8运行时环境;
  2. 引用核心依赖库:OpenCvSharp.dll、OpenCvSharp.Extensions.dll、WindowControl.dll;
  3. 配置项目目标框架为.NET Framework 4.8。

(二)快速上手

1. 控件初始化

在WPF窗口中添加WindowControl控件:

<WindowControl:WindowSmartControl x:Name="WindowControl" />
2. 添加绘图对象
// 添加圆形绘图对象
CircleDrawingObject circleObj = new CircleDrawingObject();
circleObj.CreateDrawingObject(200, 200, 100); // 圆心(200,200),半径100
circleObj.AttachToWindowControl(WindowControl);
circleObj.SetDrawingObjectCallback(DrawingObject.CallBackType.OnDrag, DrawObjCallback);
circleObj.SetDrawingObjectParam((int)CircleDrawingObject.Param.Stroke, Brushes.Red);
circleObj.SetDrawingObjectParam((int)CircleDrawingObject.Param.StrokeThickness, 2.0);
3. 加载图像
// 路径加载
WindowControl.LoadBitmapImage(@"C:\test.png");
// 或拖入加载(无需额外代码,控件自动响应)
4. 启用Sobel边缘检测
// 勾选Sobel复选框后,拖拽圆形对象即可触发边缘检测
SobelcheckBox.IsChecked = true;

六、扩展与定制

(一)自定义绘图对象

  1. 继承DrawingObject基类;
  2. 重写CreateDrawingObject方法定义图形参数;
  3. 实现UpdateShapePos方法更新图形位置;
  4. 重写ThumbDrag方法实现自定义交互逻辑。

(二)扩展图像处理功能

可通过集成OpenCV的其他算法(如Canny边缘检测、阈值分割、轮廓检测)扩展控件功能,示例如下:

// 扩展Canny边缘检测
private OpenCvSharp.Mat CannyMat(OpenCvSharp.Mat mat)
{
    OpenCvSharp.Mat cannyMat = new OpenCvSharp.Mat();
    OpenCvSharp.Cv2.Canny(mat, cannyMat, 100, 200);
    return cannyMat;
}

七、注意事项

  1. 确保OpenCvSharp相关依赖库与.NET Framework 4.8兼容;
  2. 绘图对象的交互操作仅在图像加载后生效;
  3. 处理大尺寸图像时,建议关闭实时特效(如Sobel检测)以提升性能;
  4. 控件支持Windows系统,暂不支持跨平台运行。

八、版本迭代说明

版本 迭代内容
2.0 新增图像拖入显示功能;优化绘图对象交互流畅度;集成Sobel边缘检测;支持多边形顶点动态添加
1.0 基础图像显示;圆形、矩形、直线绘图对象;基础拖拽缩放功能

基于WPF&Opencv 高级显示控件2.0 全新优化,支持图像拖入显示,使用wpf的adnoner和thumb实现可交互的绘图对象。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐