WPF-VisionMasterOpenCV
·
WPF-VisionMasterOpenCV
一、项目概述
WPF-VisionMasterOpenCV 是一个基于 WPF + EmguCV(OpenCV的.NET封装)开发的机器视觉软件框架。它采用节点流程图的方式,让用户可以通过拖拽节点来构建视觉检测流程。
项目架构
WPF-VisionMaster/
├── Document/ # 文档资源
├── Solution/ # 解决方案文件
└── Source/
├── Apps/ # 应用入口(主程序)
│ └── H.App.VisionMaster.OpenCV/
├── NodeDatas/ # 节点数据定义(Onnx等)
│ ├── H.NodeDatas.Onnx.OpenCV/
│ └── H.NodeDatas.Zoo/
├── Setups/ # 安装包
├── VisionMaster/ # 核心视觉处理模块
│ ├── H.VisionMaster.DiagramData/
│ ├── H.VisionMaster.Network/
│ ├── H.VisionMaster.NodeData/
│ └── H.VisionMaster.OpenCV/ # ⭐ OpenCV节点核心
└── WPF-Control/ # WPF控件库(依赖模块)
二、学习路径规划
阶段一:环境搭建与项目启动(第1-2天)
目标:能够成功编译并运行项目
1.1 准备开发环境
- 必备工具:
- Visual Studio 2022(需安装 .NET 6/7 开发工具)
- Git(用于拉取子模块)
1.2 克隆项目并恢复依赖
# 克隆主项目
git clone https://github.com/xxx/WPF-VisionMasterOpenCV.git
# 进入目录
cd WPF-VisionMasterOpenCV\WPF-VisionMasterOpenCV2.0\WPF-VisionMaster
# 初始化子模块(重要!)
git submodule init
git submodule update
# 打开解决方案
Start-Process Solution\WPF-VisionMaster.sln
1.3 理解启动流程
查看入口文件 Source/Apps/H.App.VisionMaster.OpenCV/App.xaml.cs:
public partial class App : ApplicationBase
{
protected override void ConfigureServices(IServiceCollection services)
{
services.AddApplicationServices();
services.AddProject<VisionProjectService>(x =>
{
x.Extenstion = ".json";
x.JsonSerializerService = new NewtonsoftJsonSerializerService();
});
}
}
关键点:
- 使用 Dependency Injection(依赖注入)模式
- 项目配置使用 JSON 序列化
- 继承自
ApplicationBase(来自 H.Extensions 库)
阶段二:核心概念理解(第3-5天)
目标:理解节点系统的设计模式
2.1 节点分类体系
项目中的节点按功能划分为多个类别:
| 类别 | 目录 | 功能说明 |
|---|---|---|
| 数据源 | 1 - Src/ |
摄像头采集、图片读取、视频读取 |
| 预处理 | 2 - Preprocessings/ |
颜色转换、阈值、缩放、翻转等 |
| 模糊处理 | 3 - Blurs/ |
高斯模糊、均值模糊等 |
| 形态学 | 4 - Morphology/ |
腐蚀、膨胀、开闭运算 |
| 条件判断 | 5 - Conditions/ |
像素阈值判断等 |
| 模板匹配 | 6 - TemplateMatchings/ |
SIFT/SURF特征匹配、模板匹配 |
| 检测器 | 7 - Detector/ |
Canny边缘、Blob、轮廓检测 |
| 特征检测 | 8 - Feature/ |
AKaze、BRISK等特征点检测 |
| 其他 | 9 - Other/ |
YOLO、Haar级联、SVM等 |
| 输出 | 9 - Outputs/ |
OK/NG判定、消息通知 |
2.2 节点基类分析
查看典型节点实现,理解继承关系:
// 颜色转换节点
public class CvtColor : OpenCVNodeDataBase, IPreprocessingGroupableNodeData
{
// 属性定义
private ColorConversionCodes _colorConversionCode = ColorConversionCodes.BGR2GRAY;
[Display(Name = "转换规则", GroupName = VisionPropertyGroupNames.RunParameters)]
public ColorConversionCodes ColorConversionCode { get; set; }
// 核心处理逻辑
protected override FlowableResult<Mat> Invoke(
ISrcVisionNodeData<Mat> srcImageNodeData,
IVisionNodeData<Mat> from,
IFlowableDiagramData diagram)
{
Mat mat = from.Mat.CvtColor(this.ColorConversionCode, this.DstCn);
return this.OK(mat);
}
}
关键接口说明:
| 接口 | 作用 |
|---|---|
ISrcImageGroupableNodeData |
数据源节点标记 |
IPreprocessingGroupableNodeData |
预处理节点标记 |
IDetectorGroupableNodeData |
检测器节点标记 |
IFlowableLinkData |
节点间数据传递 |
IFlowableDiagramData |
流程图上下文 |
阶段三:OpenCV扩展方法深入(第6-8天)
目标:掌握 OpenvCVExtension.cs 中的核心扩展方法
3.1 坐标转换方法
// WPF Rect ↔ OpenCV Rect 互转
public static System.Windows.Rect ToWindowRect(this Rect rect)
{
return new System.Windows.Rect(rect.Left, rect.Top, rect.Width, rect.Height);
}
public static Rect ToCVRect(this System.Windows.Rect rect)
{
return new Rect((int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height);
}
3.2 颜色转换
// WPF Color ↔ OpenCV Scalar
public static Scalar ToScalar(this Color color)
{
return Scalar.FromRgb(color.R, color.G, color.B);
}
3.3 HSV颜色范围计算(重要)
public static Tuple<Scalar, Scalar> GetHSVRange(this Color color,
int hRange = 30, int sRange = 20, int vRange = 20)
{
// RGB转HSV,然后计算上下限范围
// 用于颜色识别场景
}
3.4 图像转WPF控件
public static ImageSource ToImageSource(this Mat mat)
{
if (!mat.IsValid()) return null;
return Application.Current.Dispatcher.Invoke(() =>
{
return mat.ToWriteableBitmap();
});
}
阶段四:典型节点实现学习(第9-12天)
目标:掌握不同类型节点的实现模式
4.1 数据源节点 - 摄像头采集
public class CameraCaptureNodeData : VideoCaptureNodeDataBase, ISrcImageGroupableNodeData
{
public override async Task<IFlowableResult> InvokeAsync(...)
{
using VideoCapture capture = new VideoCapture();
capture.Open(this.VideoCaptureIndex, this.VideoCaptureAPIs);
// 循环采集帧
while (true)
{
Mat frameMat = capture.RetrieveMat();
// 处理帧...
frameMat.Dispose();
}
}
}
关键点:
- 使用
VideoCapture类读取摄像头 using语句确保资源释放await this.InvokeFrameMatAsync()传递帧数据
4.2 预处理节点 - Canny边缘检测
public class Canny : OpenCVNodeDataBase, IDetectorGroupableNodeData
{
[Range(50.0, 100.0)]
public double Threshold1 { get; set; }
[Range(150.0, 200.0)]
public double Threshold2 { get; set; }
protected override FlowableResult<Mat> Invoke(...)
{
Mat result = new Mat();
Cv2.Canny(preMat, result, this.Threshold1, this.Threshold2, ...);
return this.OK(result);
}
}
4.3 高级节点 - YOLOv3目标检测
// 位于 9 - Other/Yolov3.cs
public class Yolov3 : OpenCVNodeDataBase, IDetectorGroupableNodeData
{
// 配置模型路径
private string _weights = "yolov3.cfg";
private string _model = "yolov3.weights";
protected override FlowableResult<Mat> Invoke(...)
{
// 使用 Dnn 模块加载 YOLO 模型
using Net net = Cv2.Dnn.ReadNetFromDarknet(_weights, _model);
// 推理检测...
}
}
阶段五:创建自定义节点(第13-15天)
目标:能够编写自己的视觉处理节点
5.1 创建节点的步骤
using H.Controls.Diagram.Presenter.NodeDatas.Base;
using Emgu.CV;
// 1. 添加特性标记
[Icon(FontIcons.Custom)]
[Display(Name = "我的自定义节点", GroupName = "自定义", Description = "自定义处理逻辑")]
// 2. 继承基类并实现接口
public class MyCustomNode : OpenCVNodeDataBase, IPreprocessingGroupableNodeData
{
// 3. 定义可配置属性
private int _parameter = 10;
[Display(Name = "参数", GroupName = "运行参数")]
public int Parameter
{
get { return _parameter; }
set { _parameter = value; RaisePropertyChanged(); }
}
// 4. 实现核心处理方法
protected override FlowableResult<Mat> Invoke(
ISrcVisionNodeData<Mat> srcImageNodeData,
IVisionNodeData<Mat> from,
IFlowableDiagramData diagram)
{
// 获取输入图像
Mat inputMat = from.Mat;
// 执行自定义处理
Mat result = new Mat();
// ... 你的 OpenCV 处理代码
// 返回结果
return this.OK(result);
}
}
5.2 节点注册
创建节点后,需要在模块初始化时注册:
// 在扩展类中注册
public static class MyNodeExtension
{
public static IServiceCollection AddMyCustomNode(this IServiceCollection services)
{
services.AddVisionNodeData<MyCustomNode>();
return services;
}
}
阶段六:实战项目开发(第16-20天)
目标:完成一个完整的视觉检测项目
6.1 项目案例:产品缺陷检测
流程设计:
- 摄像头采集 → 获取实时图像
- 色彩变换 → 转灰度图
- 高斯模糊 → 降噪
- Canny边缘检测 → 提取边缘
- 轮廓查找 → FindContours
- Blob检测 → 识别缺陷区域
- OK/NG判定 → 根据缺陷数量输出结果
6.2 配置流程图
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 摄像头采集 │───▶│ 色彩变换 │───▶│ 高斯模糊 │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Canny边缘 │───▶│ 轮廓查找 │───▶│ Blob检测 │
└─────────────┘ └─────────────┘ └─────────────┘
│
▼
┌─────────────┐
│ OK/NG判定 │
└─────────────┘
三、关键技术点总结
1. EmguCV 基础
| 类/方法 | 作用 |
|---|---|
Mat |
OpenCV图像容器 |
VideoCapture |
视频/摄像头捕获 |
Cv2.Canny() |
边缘检测 |
Cv2.GaussianBlur() |
高斯模糊 |
Cv2.FindContours() |
轮廓检测 |
Cv2.Dnn.ReadNetFromDarknet() |
加载YOLO模型 |
2. WPF 集成要点
- 线程安全:UI更新必须在 Dispatcher 线程执行
- 图像转换:
Mat.ToImageSource()方法 - 数据绑定:使用
BindableBase实现 MVVM
3. 节点生命周期
创建节点 → LoadDefault() → IsValid() → BeforeInvokeAsync()
→ InvokeAsync() → UpdateResultImageSource() → 销毁
四、学习资源推荐
官方文档
参考项目
视频教程
- B站搜索:
WPF-VisionMaster相关教程 - OpenCV 入门视频
五、练习建议
- 入门练习:修改现有节点参数,观察效果变化
- 基础练习:创建一个简单的自定义节点(如亮度调整)
- 进阶练习:实现一个完整的检测流程(如二维码识别)
- 高级练习:集成自定义深度学习模型
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)