PLCSharp 机器视觉模块详解
PLCSharp 的机器视觉模块位于 VVMs/Vision/,是平台三大核心模块之一(视觉、运动控制、通讯)。不同于传统的视觉开发方式,PLCSharp 采用"视觉功能 + 视觉流程"的设计理念,用户可以通过配置而非编码的方式完成检测任务。
整体架构
VVMs/Vision/
├── Camera/ # 相机层
│ ├── CameraBase.cs # 相机基类(抽象)
│ ├── HikCamera.cs # 海康威视相机实现
│ ├── HikCameras.cs # 相机管理
│ ├── CameraConfigViewModel # 相机参数配置
│ └── TriggerMethod.cs # 触发模式枚举
├── VisionFunction.cs # 视觉功能单元
├── VisionFlow.cs # 视觉流程步骤
├── VisionType.cs # 流程类型枚举(24+种)
├── VisionConfig.xaml/cs # 视觉配置界面
├── Visions.xaml/cs # 视觉功能列表界面
├── VisionsModel.cs # 数据模型
├── VisionsViewModel.cs # 视图模型
├── VisionFlowHandler/ # 流程执行引擎
│ ├── IVisionFlowHandler.cs # 处理器接口
│ ├── Access/ # 图像存取
│ ├── Algorithm/ # 算法(卡尺寻边、ORB匹配)
│ └── Processing/ # 图像处理
├── CalibrationParam.xaml # 标定参数界面
├── ImageData.cs # 图像数据模型
└── MatExtension.cs # OpenCV Mat 扩展方法
相机模块 (Camera)
相机基类 (CameraBase.cs)
| 属性 | 类型 | 说明 |
|------|------|------|
| ID | Guid | 相机唯一标识 |
| Name | string | 相机名称 |
| Brand | CameraBrand | 品牌(目前支持海康机器人) |
| Params | CameraParams | 曝光时间、触发模式等参数 |
| Mat | Mat | 当前采集的图像 (OpenCV) |
| Connected | bool | 连接状态 |
关键方法:
Open() / Close()— 打开/关闭相机SoftwareTrig()— 软触发采集Continuous() / StopContinuous()— 连续采集/停止SetExposureTime()— 设置曝光时间SetTriggerSource()— 设置触发源
相机参数 (CameraParams)
| 参数 | 说明 |
|------|------|
| ExposureTime | 曝光时间(微秒) |
| MinExposureTime / MaxExposureTime | 曝光时间范围 |
| TriggerSource | 触发模式:Software(软触发)/ Line0(硬触发) |
支持的相机品牌
目前实现 CameraBrand.HikRobot(海康机器人),通过 HikCamera.cs 和 HikCameras.cs 管理,支持:
- 相机自动发现与枚举
- 多相机同时管理
- 实时图像采集
视觉功能 (VisionFunction)
VisionFunction 是视觉检测的核心单元,包含:
- 一组视觉流程步骤(
VisionFlows) - 输入输出的图像数据(
Mats) - 检测结果数据(
ResultDoubles、Line2Ds等)
视觉功能与 Recipe 配方 绑定(RecipeID),不同配方可以拥有完全不同的视觉方案。
视觉流程 (VisionFlow)
每个 VisionFunction 包含一个 VisionFlow 列表,流程步骤按顺序执行。当前支持的流程类型多达 24 种,分为三大类:
1️⃣ 图像存取 (Access)
| 流程类型 | 说明 | |---------|------| | 拍照 | 从相机采集图像 | | 从文件获取图片 | 从本地文件加载图像 | | 从全局图像获取图片 | 从全局图像池取图 | | 从过程图像获取图片 | 从上一个流程步骤取图 | | 存到文件 | 将图像保存到本地 | | 存到全局图像 | 保存到全局图像池 | | 存到过程图像 | 传递给下一个流程 | | 显示图像到主页 | 在主页画布上显示 |
2️⃣ 图像处理 (Processing)
| 流程类型 | 说明 | |---------|------| | BGR2GRAY | 彩色图转灰度图 | | GRAY2BGR | 灰度图转彩色图 | | 取通道 | 提取指定颜色通道 | | 各通道最小值 | 逐像素取各通道最小值 | | 各通道最大值 | 逐像素取各通道最大值 | | 阈值 | 二值化处理 |
3️⃣ 算法 (Algorithm)
| 流程类型 | 说明 | |---------|------| | 颜色面积 | 基于颜色的面积计算 | | 两线交点 | 计算两条直线的交点坐标 | | 卡尺寻边 | 边缘定位与测量 | | ORB匹配 | 基于 ORB 特征点的模板匹配 |
卡尺寻边 (CaliperFindEdge)
基于 OpenCV 的边缘检测实现,核心参数:
| 参数 | 默认值 | 说明 |
|------|--------|------|
| Threshold | 30 | 边缘阈值 |
| Sigma | 1.0 | 高斯平滑系数 |
| NumCalipers | 10 | 卡尺数量 |
| CaliperLength | 50 | 卡尺长度(像素) |
| Direction | 0 | 搜索方向(0=正黑到白,1=正白到黑) |
| MinScore | 60 | 最小得分 |
工作原理:在所画的线段上均匀分布卡尺,每个卡尺在所定方向上扫描边缘点,最后对检测到的边缘点进行直线拟合,输出边缘直线。
ORB 匹配 (ORBMatch)
基于 OpenCV ORB (Oriented FAST and Rotated BRIEF) 特征点的模板匹配算法,核心参数:
| 参数 | 默认值 | 说明 |
|------|--------|------|
| NFeatures | 500 | 特征点数量 |
| MinGoodRatio | 0.3 | 优质匹配最低比例 |
| MinMatches | 8 | 最少匹配点数 |
输出结果:
OffsetX / OffsetY— 图像中的偏移量Angle— 旋转角度CenterX / CenterY— 匹配中心坐标
特点:
- 支持旋转不变性(特征点方向)
- 受光照变化影响小
- 支持设定感兴趣区域,减少计算量
视觉流程执行引擎
VisionFunction.RunAll() 是流程执行的核心,采用状态机驱动:
RunAll 入口
→ 遍历 VisionFlows 列表
→ 对每个流程调用 RunItem()
→ 根据 VisionFlowType 查找对应的 Handler
→ 执行 Handler.Execute()
→ 全部完成
每种流程类型注册了对应的 Handler 处理器:
private static readonly Dictionary<VisionFlowType, IVisionFlowHandler> _handlers = new()
{
[VisionFlowType.阈值] = new ThresholdHandler(),
[VisionFlowType.卡尺寻边] = new CaliperFindEdgeHandler(),
[VisionFlowType.ORB匹配] = new ORBMatchHandler(),
[VisionFlowType.拍照] = new GetFromCameraHandler(),
// ... 共 24+ 种处理器
};
与配方系统的集成
Vision 模块与 Recipe 配方系统深度绑定:
- 每个
VisionFunction关联一个RecipeID - 切换配方时自动加载对应的视觉功能集合
- 配方数据自动保存到数据库(通过
DatasContext)
图像数据管理
图像数据通过 ImageData 模型管理,存储在全局 ImageDatas 集合中,支持:
- 多张图像同时管理
- 图像在视觉功能流程间传递
- 图像的保存与加载
开发状态
⚠️ 本项目仍在积极开发中,Vision 模块基于 OpenCVSharp (OpenCV .NET Wrapper),已完成:
- ✅ 海康相机接入与多相机管理
- ✅ 24+ 种视觉流程处理器
- ✅ 卡尺寻边、ORB 匹配等核心算法
- ✅ 视觉功能与配方系统绑定
- ✅ 视觉配置 UI