Files
test_demo/MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/Vision
Shi.Ji e31d3560bb 添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
2026-05-18 11:43:09 +08:00
..
2026-05-18 11:43:09 +08:00
2026-05-18 11:43:09 +08:00
2026-05-18 11:43:09 +08:00
2026-05-18 11:43:09 +08:00

Vision 模块使用文档

1. 文档范围

本文档说明当前 MainShell/Vision 模块在“一个算法一个文件夹”的结构下的职责划分和推荐使用方式,重点覆盖:

当前目录划分如下:

  • Common/:共享结果模型与算法参数基类
  • ImageCapture/:采图接口、实现与采图相关模型
  • FindTemplate/:模板匹配算法接口、实现、请求、参数、结果
  • FindMark/Mark 识别参数与后续算法扩展入口
  • FindDie/Die 定位参数与后续算法扩展入口
  • FindCenter/:中心识别草稿算法骨架

2. 当前模块职责边界

2.1 VisionParController

负责视觉前置硬件准备:

  • 设置曝光和增益
  • 设置触发模式
  • 设置触发源
  • 设置触发延时
  • 启动或停止抓流
  • 设置光源参数

2.2 ImageCaptureService

只负责执行采图动作:

  • 不再自动切换触发模式
  • 不再自动切换触发源
  • 不再自动设置触发延时
  • 不再自动启停抓流
  • 同一相机的采图请求在服务内部按相机粒度串行执行
  • 通过 ImageCaptureResult 返回成功、取消、无帧或设备状态异常等结果

调用方必须在采图前通过 VisionParController 或其他上层硬件控制流程准备好相机状态。

2.3 FindTemplateService

负责:

当前模板匹配算法本体仍为占位实现,尚未接入真实视觉算法库。当前占位实现会明确返回失败,避免上层流程误判为识别成功。

3. 当前推荐结构

当前推荐使用“一个算法一个实现”的结构,即:

  • 每个算法拥有独立接口,例如 IFindTemplateService
  • 每个算法拥有独立实现,例如 FindTemplateService
  • 每个算法拥有独立请求、参数、结果模型
  • 不再使用统一算法总入口服务

推荐未来新增算法继续按相同方式组织,例如:

  • FindMark/IFindMarkService.cs
  • FindMark/FindMarkService.cs
  • FindMark/FindMarkRequest.cs
  • FindMark/FindMarkResult.cs

如果算法需要“已有图像直接处理”的场景,可按需再增加 XXXImageRequest.cs

4. 推荐调用顺序

推荐顺序如下:

  1. 先通过 VisionParController 准备相机与光源参数
  2. 再通过 IImageCaptureService 执行采图,或由具体算法服务内部采图
  3. 最后通过具体算法服务,例如 IFindTemplateService,执行算法

5. 采图前提说明

5.1 连续流采图

CameraCaptureMode.Stream 用于采图时,调用前应确保:

  • 相机已打开
  • 相机已处于 grabbing 状态
  • 相机已被配置为适合连续流取图的工作模式

5.2 软触发采图

CameraCaptureMode.SoftTrigger 用于采图时,调用前应确保:

  • 相机已打开
  • 相机已处于 grabbing 状态
  • 相机已被配置为软触发模式
  • 触发源已设置为软件触发

如果上述前提不满足,ImageCaptureService 不会代替调用方修改硬件状态,而是直接失败并记录日志。

6. 请求模型

模板匹配当前使用独立请求模型:

推荐新算法默认最小模型集为:

  • XXXRequest
  • XXXResult

只有在算法确实需要时,再增加:

  • XXXParameters
  • XXXImageRequest

7. 结果模型

当前结果模型已调整为四层:

模板匹配当前返回:

FindTemplateResult 当前包含:

  • CenterX
  • CenterY
  • Score
  • Match

FindTemplatesResult 当前包含:

  • Items

8. 当前算法实现状态

当前状态如下:

  • 采图服务已按新职责边界实现
  • 模板匹配保持独立接口与独立服务实现
  • 采图结果已区分成功、取消、设备状态错误、无帧和驱动异常
  • 已不再使用统一视觉算法入口服务
  • FindTemplateService 当前仍为占位实现,尚未接入真实算法
  • 已预留单个模板匹配与多个模板匹配两套接口
  • 多个模板匹配当前已明确约定输出规则:保留底层原始顺序,不做得分筛选、不做去重、不做聚类合并

因此本模块当前适合作为:

  • 视觉接入骨架
  • 采图与参数联调骨架
  • 按算法拆服务的长期结构基础

9. 取消与超时说明

ImageCaptureService 当前采图仍基于底层同步驱动接口。

这意味着:

  • CancellationToken 主要控制外层任务流程
  • 取消仅能在进入驱动前或驱动返回后生效
  • 不一定能真正中断驱动内部阻塞调用
  • 软触发底层超时仍受驱动实现限制

FindTemplateService 当前会区分:

  • 调用方主动取消
  • 参数校验失败
  • 算法未实现
  • 采图阶段失败

10. 图像对象生命周期说明

11. 多模板匹配规则

当前多个模板匹配算法接口约定如下:

  1. 输入一张图像和一组模板匹配参数
  2. 调用底层模板匹配能力,获取原始匹配结果集合
  3. 不按 MinScore 做二次筛选
  4. 不做最佳值选优
  5. 不做结果去重
  6. 不做聚类合并
  7. 保持底层算法返回顺序
  8. 将原始匹配结果逐个映射为 FindTemplateResult 并输出到 FindTemplatesResult

12. 新增算法模板建议

推荐新增一个普通算法时,默认最小文件集合为:

  • IXXXService.cs
  • XXXService.cs
  • XXXRequest.cs
  • XXXResult.cs

复杂算法再按需增加:

  • XXXParameters.cs
  • XXXImageRequest.cs

这样可以兼顾:

  • 一算法一实现的清晰边界
  • 文件数量不过度膨胀
  • 后续维护和问题定位的可读性

13. 代码使用示例

13.1 示例一:由算法服务内部采图后执行单个模板匹配

这是推荐的业务调用方式。先通过 VisionParController 准备相机状态,再调用 IFindTemplateService.ProcessAsync()

using MainShell.Common;
using MainShell.Vision;
using System.Threading;
using System.Threading.Tasks;

public class VisionUsageExample
{
    private readonly IFindTemplateService _findTemplateService;

    public VisionUsageExample(IFindTemplateService findTemplateService)
    {
        _findTemplateService = findTemplateService;
    }

    public async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        FindTemplateRequest request = new FindTemplateRequest();
        request.CameraSource = CameraType.UpCamera;
        request.TimeoutMilliseconds = 3000;
        request.CaptureOptions.TimeoutMilliseconds = 2000;
        request.CaptureOptions.CaptureMode = CameraCaptureMode.Stream;
        request.Parameters.UseRoi = true;
        request.Parameters.RoiName = "DieCenterRoi";
        request.Parameters.TemplatePath = "Template/DieCenter";
        request.Parameters.MinScore = 0.8d;

        VisionProcessResult<FindTemplateResult> result = await _findTemplateService.ProcessAsync(
            request,
            cancellationToken).ConfigureAwait(false);

        if (!result.Succeeded)
        {
            string failureMessage = result.Message;
            return;
        }

        FindTemplateResult data = result.Data;
        double centerX = data.CenterX;
        double centerY = data.CenterY;
        double score = data.Score;
    }
}

13.2 示例二:对已有图像执行多个模板匹配

这个方式适合调试、联调或者需要复用同一帧图像的场景。

using MainShell.Common;
using MainShell.Models;
using MainShell.Vision;
using System.Threading;
using System.Threading.Tasks;

public class VisionImageUsageExample
{
    private readonly IImageCaptureService _imageCaptureService;
    private readonly IFindTemplateService _findTemplateService;

    public VisionImageUsageExample(
        IImageCaptureService imageCaptureService,
        IFindTemplateService findTemplateService)
    {
        _imageCaptureService = imageCaptureService;
        _findTemplateService = findTemplateService;
    }

    public async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        CameraCaptureOptions captureOptions = new CameraCaptureOptions();
        captureOptions.TimeoutMilliseconds = 2000;
        captureOptions.CaptureMode = CameraCaptureMode.Stream;

        ImageCaptureResult captureResult = await _imageCaptureService.CaptureAsync(
            CameraType.UpCamera,
            captureOptions,
            cancellationToken).ConfigureAwait(false);

        if (!captureResult.Succeeded)
        {
            string captureFailureMessage = captureResult.Message;
            return;
        }

        MxImage image = captureResult.Image;
        try
        {
            FindTemplateImageRequest request = new FindTemplateImageRequest();
            request.TimeoutMilliseconds = 3000;
            request.Parameters.UseRoi = false;
            request.Parameters.TemplatePath = "Template/DieCenter";
            request.Parameters.MinScore = 0.8d;

            VisionProcessResult<FindTemplatesResult> result = await _findTemplateService.ProcessMultipleImageAsync(
                image,
                request,
                cancellationToken).ConfigureAwait(false);

            if (!result.Succeeded)
            {
                string failureMessage = result.Message;
                return;
            }

            FindTemplatesResult data = result.Data;
            int count = data.Items.Count;
        }
        finally
        {
            if (image != null)
            {
                image.Dispose();
            }
        }
    }
}

13.3 示例三:如何判断采图失败原因

ImageCaptureResult 适合在上层做更细的失败分流。

using MainShell.Common;
using MainShell.Vision;
using System.Threading;
using System.Threading.Tasks;

public class CaptureResultExample
{
    private readonly IImageCaptureService _imageCaptureService;

    public CaptureResultExample(IImageCaptureService imageCaptureService)
    {
        _imageCaptureService = imageCaptureService;
    }

    public async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        ImageCaptureResult captureResult = await _imageCaptureService.CaptureAsync(
            CameraType.UpCamera,
            2000,
            CameraCaptureMode.Stream,
            cancellationToken).ConfigureAwait(false);

        if (captureResult.Succeeded)
        {
            return;
        }

        switch (captureResult.Status)
        {
            case ImageCaptureStatus.Cancelled:
                break;

            case ImageCaptureStatus.CameraNotFound:
            case ImageCaptureStatus.CameraNotOpen:
            case ImageCaptureStatus.CameraNotGrabbing:
            case ImageCaptureStatus.NoFrame:
            case ImageCaptureStatus.DriverError:
                string message = captureResult.Message;
                break;

            default:
                break;
        }
    }
}

13.4 示例四:新增一个新算法时的推荐骨架

FindMark 为例,推荐至少准备:

  • FindMark/IFindMarkService.cs
  • FindMark/FindMarkService.cs
  • FindMark/FindMarkRequest.cs
  • FindMark/FindMarkResult.cs

如果需要已有图像处理,再增加:

  • FindMark/FindMarkImageRequest.cs

如果参数较复杂,再增加:

  • FindMark/FindMarkParameters.cs

服务实现建议沿用 FindTemplateService 的结构:

  • ProcessAsync() 负责“采图 + 单个模板匹配”
  • ProcessImageAsync() 负责“已有图像 + 单个模板匹配”
  • ProcessMultipleAsync() 负责“采图 + 多个模板匹配”
  • ProcessMultipleImageAsync() 负责“已有图像 + 多个模板匹配”
  • NormalizeRequest() 负责标准化
  • ValidateRequest() 负责参数校验
  • CloneParameters() 负责避免共享可变输入对象

这样可以保证不同算法之间结构一致,便于维护和扩展。