Skip to content

界面含义

image-20250331195159557

image-20250331201657499

工具列表

image-20250331201721829

image-20250331202310720

Calibration & fixturing

image-20250331201730924

Color

image-20250331201803218

Geometry - Creation

image-20250331201848968

Geometry - Finding & Fitting

image-20250331202007317

Geometry -Measurement

image-20250331202043537

Image Frocessing

image-20250331202150925

模板匹配

参数

算法

PatMax:精准度最高 匹配速度是最慢的 一般用于细微细节匹配的 例如:焊接工艺 PatQuick:精度较低 匹配速度较快 一般用于对细节或者质感没有太大要求的部件。例如:物品的检方 PatMax 与 PatQuick:介于以上两者之间 PatFlex:一般用于图像表面不平整,高灵活的图案的设计 PatMax -高灵敏度:适用对比度很低或者视频噪音或图像变形严重的图像 透视 -PatMax:查找已经历透视失真的二维特征

训练模式

图像:以我们训练的图像为模型,可以使用图像掩膜编辑器。 带图像的形状模型:在找不到整体质量好的训练元件的场合使用,可以在图像上使用建模器。 带转换的形状模型:使用建模器构建的模型。

极性

极性:表示特征边界点是从黑到白还是从白到黑,忽略极性可增加模型的多样性; 默认情况下要求训练的图像要求极性相同,如果忽略极性则只考虑轮廓与之相同即可,光线的变化的不考虑

重复模式

当训练的样板包含重复元素,例如网格,栏组,或平行线样板时,使用此参数

颗粒度

颗粒度被描述为探测到目的特征的半径,以像素表示

弹性

此属性为 PMAlign 工具允许的像素变量。通常,如果您希望运行时图像中的样板发生不同的变化,应指定非零的弹性值

图像坐标

VisionPro的默认空间

输入图像空间:“.” 像素空间:“#” 根空间:“@”

边缘阈值

image-20250331203326226

图像显示

image-20250331203355209

模板匹配

image-20250331203417747

工具含义

CogPatInspectTool

已上传的图片

输入参数:

  1. InputImage
    • 输入图像,通常是从上一处理步骤(如图中 CogPMAlignTool1)传来的图像,用于进行图案检测。
  2. Pose
    • 工件的姿态(位置和角度),用于将检测模板对齐实际图像中的位置。通常由 CogPMAlignTool1 提供的匹配位姿 GetPose() 提供。
  3. Pattern.TrainImage
    • 用于训练的模板图像,即你想要在目标图像中找到的图案。通常是初始图像或从某个区域截取的参考图。
  4. Pattern.Origin
    • 模板图像的原点(坐标参考点),用于标定与目标图像中图案位置的偏移关系。

编程

脚本

主要使用的库和命名空间

csharp
using System;
using Cognex.VisionPro;             // 基础视觉处理库
using Cognex.VisionPro3D;           // 3D视觉处理
using Cognex.VisionPro.ToolGroup;   // 工具组管理
using Cognex.VisionPro.PMAlign;     // 模式匹配工具
using Cognex.VisionPro.Caliper;     // 卡尺工具
using Cognex.VisionPro.Dimensioning; // 尺寸测量工具
using System.Drawing;               // 绘图功能
using System.Collections.Generic;   // 泛型集合

CogFindCircleTool (圆查找工具)

作用:检测图像中的圆形并提取圆心坐标

csharp
CogFindCircleTool cogFindCircleTool = toolGroup.Tools["CogFindCircleTool1"] as CogFindCircleTool;
double circleX = cogFindCircleTool.Results.GetCircle().CenterX;
double circleY = cogFindCircleTool.Results.GetCircle().CenterY;

CogPMAlignTool (模式匹配工具)

作用:在图像中查找预先训练的模板,获取匹配位置

csharp
CogPMAlignTool cogPMAlignTool = toolGroup.Tools["CogPMAlignTool2"] as CogPMAlignTool;
foreach (CogPMAlignResult item in cogPMAlignTool.Results)
{
    double headX = item.GetPose().TranslationX;
    double headY = item.GetPose().TranslationY;
    // 后续处理...
}

CogDistancePointPointTool (点到点距离工具)

作用:计算两点之间的欧氏距离

csharp
CogDistancePointPointTool cogDistancePointPointTool = new CogDistancePointPointTool();
cogDistancePointPointTool.StartX = headX;
cogDistancePointPointTool.StartY = headY;
cogDistancePointPointTool.EndX = circleX;
cogDistancePointPointTool.EndY = circleY;
cogDistancePointPointTool.InputImage = cogPMAlignTool.InputImage;
cogDistancePointPointTool.Run();
distances.Add(cogDistancePointPointTool.Distance);

CogGraphicLabel (图形标签工具)

作用:在图像上显示文本信息

csharp
CogGraphicLabel cogGraphicLabel = new CogGraphicLabel();
string text = string.Format("{0:F2}", cogDistancePointPointTool.Distance);
cogGraphicLabel.SetXYText(headX, headY, text);
cogGraphicLabel.Font = new Font("黑体", 20);
cogGraphicLabel.Color = CogColorConstants.Red;

CogCreateSegmentTool (线段创建工具)

作用:创建并显示两点之间的连接线段

csharp
CogCreateSegmentTool cogCreateSegmentTool = new CogCreateSegmentTool();
cogCreateSegmentTool.Segment.StartX = headX;
cogCreateSegmentTool.Segment.StartY = headY;
cogCreateSegmentTool.Segment.EndX = circleX;
cogCreateSegmentTool.Segment.EndY = circleY;
cogCreateSegmentTool.InputImage = cogPMAlignTool.InputImage;
cogCreateSegmentTool.Segment.Color = CogColorConstants.Yellow;

图像加载

方法一 (FormImageV1):使用 CogImageFileTool

csharp
CogImageFileTool cogImageFileTool = new CogImageFileTool();
cogImageFileTool.Operator.Open(filePath, CogImageFileModeConstants.Read);
cogImageFileTool.Run();
cogRecordDisplay1.Image = cogImageFileTool.OutputImage;

方法二 (FormImageV2):使用 .NET 标准库 + 转换

csharp
using (Image image = Image.FromFile(filePath))
{
    Bitmap bitmap = new Bitmap(image);
    CogImage8Grey image8Grey = new CogImage8Grey(bitmap);
    cogRecordDisplay1.Image = image8Grey;
}

图像保存

方法一 (FormImageV1):使用 CogImageFileTool

csharp
CogImageFileTool cogImageFileTool = new CogImageFileTool();
cogImageFileTool.InputImage = cogRecordDisplay1.Image;
cogImageFileTool.Operator.Open(filePath, CogImageFileModeConstants.Write);
cogImageFileTool.Run();

方法二 (FormImageV2):使用 CreateContentBitmap

csharp
Bitmap bitmap = cogRecordDisplay1.CreateContentBitmap(CogDisplayContentBitmapConstants.Image) as Bitmap;
bitmap.Save(filePath);

工具访问与执行

从工具组获取工具:

csharp
CogTool tool = toolGroup.Tools["工具名称"] as CogTool类型;

执行工具:

csharp
// 方法1: 通过工具组执行
toolGroup.RunTool(tool, ref message, ref result);

// 方法2: 直接调用工具的Run方法
tool.Run();

从文件反序列化 cogToolBlock 工具:

csharp
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "VPP 文件|*.vpp";
openFileDialog.Title = "选择 VPP 文件";
openFileDialog.InitialDirectory = @"F:\";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
    string filePath = openFileDialog.FileName;
    cogToolBlock = CogSerializer.LoadObjectFromFile(filePath) as CogToolBlock;
    if (cogToolBlock != null)
    {
        MessageBox.Show("加载成功");
    }
}
cogToolBlock.Run();
cogRecordDisplay1.Record = cogToolBlock.CreateLastRunRecord().SubRecords[0];
cogRecordDisplay1.Fit();

从文件反序列化 QuickBuild:

https://www.cnblogs.com/liubaoyu/p/16903363.html

c#
private CogJobManager cogJobManager;

private CogToolGroup cogToolGroup;


private void btnLoadTool_Click(object sender, EventArgs e)
{
    OpenFileDialog openFileDialog = new OpenFileDialog();
    openFileDialog.Filter = "Tool Block Files|*.vpp";
    openFileDialog.Title = "选择 CogToolBlock 文件";
    openFileDialog.InitialDirectory = @"C:\";
    if (openFileDialog.ShowDialog() == DialogResult.OK)
    {
        string filePath = openFileDialog.FileName;
        cogJobManager = CogSerializer.LoadObjectFromFile(filePath) as CogJobManager;

        if (cogJobManager != null)
        {
            MessageBox.Show("cogJobManager 加载成功");
        }
        else
        {
            MessageBox.Show("cogJobManager 加载失败");
            return;
        }
        cogToolGroup = cogJobManager.Job(0).VisionTool as CogToolGroup;
    }
}

private void btnDetection_Click(object sender, EventArgs e)
{
    //CogImageConvertTool cogImageConvertTool = cogToolGroup.Tools["CogImageConvertTool1"] as CogImageConvertTool;
    //cogImageConvertTool.InputImage = new CogImage24PlanarColor(currentImg);
    //cogJobManager.Job(0).Run();
    CogInputImageTool cogInputImageTool = cogToolGroup.Tools["Image Source"] as CogInputImageTool;
    cogInputImageTool.InputImage = new CogImage24PlanarColor(currentImg);
    cogToolGroup.Run();
    cogRecordDisplay1.Record = cogToolGroup.CreateLastRunRecord().SubRecords[0];
    cogRecordDisplay1.Fit();
    CogSearchMaxTool cogSearchMaxToolHege = cogToolGroup.Tools["hege"] as CogSearchMaxTool;
    CogSearchMaxTool cogSearchMaxToolQueshi = cogToolGroup.Tools["queshi"] as CogSearchMaxTool;
    int hege = cogSearchMaxToolHege.Results.Count;
    int queshi = cogSearchMaxToolQueshi.Results.Count;
    int chuofang = 15 - hege - queshi;
    string total = hege == 15 ? "合格" : "不合格";
    String date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
    ListViewItem listViewItem = new ListViewItem(new string[] { (currentImgIndex + 1).ToString(), date, "黑奴", hege.ToString(), queshi.ToString(), chuofang.ToString(), total.ToString() });
    AddDataListItems(listViewItem);

}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // 释放资源
    if (cogToolGroup != null)
    {
        cogToolGroup.Dispose();
        cogToolGroup = null;
    }
    if (cogJobManager != null)
    {
        cogJobManager.Shutdown();
        cogJobManager = null;
    }
}

获取Blob的面积

c#
CogBlobTool blobTool = toolGroup.Tools["CogBlobTool2"] as CogBlobTool;
if (blobTool != null)
{
    BackgroundArea = blobTool.Results.GetBlobs()[0].Area;
}

cogToolBlock 工具块

cogToolBlock.Inputs

  • 类型: 属性 (Property)
  • 作用: 访问工具块的输入终端集合 (Input Terminals)
  • 时间点: 主要在工具块执行 (.Run()) 之前使用。
  • 目的: 设置或提供 工具块运行时需要的数据和参数(例如图像、配置参数等)。
  • 操作: 写入/赋值 (Set/Assign)
  • 访问方式: 通常通过终端名称访问,例如 cogToolBlock.Inputs["OutputImage"]
  • 类比: 像是给一个函数传递输入参数,或者给一个机器装填原材料

cogToolBlock.CreateLastRunRecord().SubRecords[0]

  • 类型:方法调用 (CreateLastRunRecord()) + 属性访问 (SubRecords) + 索引器 ([0])
  • 作用: 获取工具块上一次运行时,其内部第一个工具运行结果记录 (Run Record)
  • 时间点: 主要在工具块执行 (.Run()) 之后使用。
  • 目的: 检查或获取 工具块内部特定工具(这里是第一个工具)在上一次运行中产生的结果或状态(例如匹配得分、测量值)
  • 操作: 读取/获取 (Get/Retrieve)
  • 细分:
    • CreateLastRunRecord(): 创建并返回整个工具块的最后一次运行记录。
    • .SubRecords: 从运行记录中获取其内部所有工具各自的运行记录集合。
    • [0] 从集合中选取第一个工具的运行记录。
  • 类比: 像是查看一个函数上次运行的返回值,或者检查一个机器上次生产出的产品(特别是生产流程中第一步的产品)。
特性cogToolBlock.InputscogToolBlock.CreateLastRunRecord().SubRecords[0]
用途配置输入获取结果
时间点运行前 (Before Run)运行后 (After Run)
数据流向外部 -> 工具块 (Data In)工具块内部 -> 外部 (Data Out / Results)
操作设置 (Setting)读取 (Getting)
关注点工具块需要什么来运行工具块(或其内部工具)上次运行产生了什么

cogToolGroup 工具组

c#
CogInputImageTool cogInputImageTool = cogToolGroup.Tools["Image Source"] as CogInputImageTool;
cogInputImageTool.InputImage = new CogImage24PlanarColor(currentImg);
cogToolGroup.Run();
cogRecordDisplay1.Record = cogToolGroup.CreateLastRunRecord().SubRecords[0];
cogRecordDisplay1.Fit();

工具组访问工具使用 .Tools, 工具组没有 Outputs 参数

工具块与工具组的区别

  1. 访问工具和结果的方式:

    • CogToolGroup:可以通过 CogToolGroup.Tools["工具名称"] 直接访问组内的具体工具,并进一步获取该工具的属性或结果,这种方式非常直观,适合快速访问组内工具及其结果。

      c#
       var imageSource = cogToolGroup.Tools["Image Source"] as CogImageSourceTool;
       var imageResult = imageSource.OutputImage;
      • CogToolBlock:无法直接通过类似的方式访问内部工具。需要通过预先定义的输出变量(Outputs)来获取结果。通常使用 Outputs[索引] 或 Outputs["输出名称"],在使用 CogToolBlock 时,必须提前在工具块中设置好输出参数,才能通过代码获取结果,操作上相对间接。

        c#
         var blockResult = cogToolBlock.Outputs[0].Value;
  2. 工具访问的灵活性:

    • CogToolGroup:由于可以直接访问 Tools 集合,代码编写时更灵活,开发者可以动态地操作组内任意工具。

    • CogToolBlock:工具内部的具体实现对外部代码是隐藏的,外部只能通过定义好的输入(Inputs)和输出(Outputs)接口与工具块交互,限制了直接访问内部工具的灵活性。

  3. 封装性

    • CogToolGroup:没有严格的封装性,组内的工具和结果对外部代码是透明的。

    • CogToolBlock:具有较高的封装性,内部工具和逻辑对外部代码不可见,只能通过预定义的接口(Inputs/Outputs)进行交互,适合模块化设计。

图形显示和结果记录

  • 创建统计信息标签:

    csharp
    CogGraphicLabel label = new CogGraphicLabel();
    label.SetXYText(x, y, "文本内容");
    label.Font = new Font("字体名", 字号);
    label.Color = CogColorConstants.颜色;
    // 固定位置(屏幕坐标)显示时使用:
    label.SelectedSpaceName = "@";
  • 添加图形到结果记录:

    csharp
    toolGroup.AddGraphicToRunRecord(图形对象, lastRecord, "显示工具.OutputImage", "");

附加模板匹配的结果

c#
for (int i = 0; i < cogPMALignTool.Results.Count; i++)
{
    CogRectangleAffine cir = cogCompositeColorMatchTool.Region as CogRectangleAffine;
    cir.CenterX = cogPMALignTool.Results[i].GetPose().TranslationX;
    cir.CenterY = cogPMALignTool.Results[i].GetPose().TranslationY;
    cogCompositeColorMatchTool.Region = cir;
    cogCompositeColorMatchTool.Run();
}

图片格式

c#
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "All Image Files|*.bmp;*.ico;*.gif;*.jpeg;*.jpg;*.png;*.tif;*.tiff;*.idb|Windows Bitmap(*.bmp)|*.bmp|Windows Icon(*.ico)|*.ico|Graphics Interchange Format (*.gif)|(*.gif)|JPEG File Interchange Format (*.jpg)|*.jpg;*.jpeg|Portable Network Graphics (*.png)|*.png|Tag Image File Format (*.tif)|*.tif;*.tiff|Image DataBase (*.idb)|*.idb;";
openFileDialog.Title = "选择图片文件";
openFileDialog.InitialDirectory = @"C:\";
openFileDialog.Multiselect = true; // 允许多选
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
    foreach (string filePath in openFileDialog.FileNames)
    {
        using (Image image = Image.FromFile(filePath))
        {
            Bitmap bitmap = new Bitmap(image);
            imageList.Add(bitmap);
        }
    }
    MessageBox.Show("图片加载成功");
}

示例脚本

模板匹配绘制标签

c#
using System;
using Cognex.VisionPro;
using Cognex.VisionPro3D;
using Cognex.VisionPro.ToolGroup;
using Cognex.VisionPro.Implementation.Internal;
using Cognex.VisionPro.PMAlign;
using Cognex.VisionPro.Caliper;
using Cognex.VisionPro.Dimensioning;
using System.Drawing;
using System.Collections.Generic;

public class UserScript : CogToolGroupBaseScript
{
    public List<CogGraphicLabel> cogGraphicLabels = new List<CogGraphicLabel>();
    public List<CogCreateSegmentTool> cogCreateSegmentTools = new List<CogCreateSegmentTool>();
    public List<Double> distances = new List<Double>();

    public override bool GroupRun(ref string message, ref CogToolResultConstants result)
    {

        for (Int32 toolIdx = 0; toolIdx < toolGroup.Tools.Count; toolIdx++)
            toolGroup.RunTool(toolGroup.Tools[toolIdx], ref message, ref result);

        CogFindCircleTool cogFindCircleTool = toolGroup.Tools["CogFindCircleTool1"] as CogFindCircleTool;
        double circleX = cogFindCircleTool.Results.GetCircle().CenterX;
        double circleY = cogFindCircleTool.Results.GetCircle().CenterY;
        CogPMAlignTool cogPMAlignTool = toolGroup.Tools["CogPMAlignTool2"] as CogPMAlignTool;
        foreach (CogPMAlignResult item in cogPMAlignTool.Results)
        {
            double headX = item.GetPose().TranslationX;
            double headY = item.GetPose().TranslationY;
            CogDistancePointPointTool cogDistancePointPointTool = new CogDistancePointPointTool();
            cogDistancePointPointTool.StartX = headX;
            cogDistancePointPointTool.StartY = headY;
            cogDistancePointPointTool.EndX = circleX;
            cogDistancePointPointTool.EndY = circleY;
            cogDistancePointPointTool.InputImage = cogPMAlignTool.InputImage;
            cogDistancePointPointTool.Run();
            CogGraphicLabel cogGraphicLabel = new CogGraphicLabel();
            string text = string.Format("{0:F2}", cogDistancePointPointTool.Distance);
            distances.Add(cogDistancePointPointTool.Distance);
            cogGraphicLabel.SetXYText(headX, headY, text);
            cogGraphicLabel.Font = new Font("黑体", 20);
            cogGraphicLabel.Color = CogColorConstants.Red;
            cogGraphicLabels.Add(cogGraphicLabel);

            CogCreateSegmentTool cogCreateSegmentTool = new CogCreateSegmentTool();
            cogCreateSegmentTool.Segment.StartX = headX;
            cogCreateSegmentTool.Segment.StartY = headY;
            cogCreateSegmentTool.Segment.EndX = circleX;
            cogCreateSegmentTool.Segment.EndY = circleY;
            cogCreateSegmentTool.InputImage = cogPMAlignTool.InputImage;
            cogCreateSegmentTool.Segment.Color = CogColorConstants.Yellow;
            cogCreateSegmentTools.Add(cogCreateSegmentTool);

        }

        return false;
    }

    #region "When the Current Run Record is Created"
    public override void ModifyCurrentRunRecord(Cognex.VisionPro.ICogRecord currentRecord)
    {
    }
    #endregion

    #region "When the Last Run Record is Created"
    public override void ModifyLastRunRecord(Cognex.VisionPro.ICogRecord lastRecord)
    {
        foreach (CogGraphicLabel cogGraphicLabel in cogGraphicLabels)
        {
            toolGroup.AddGraphicToRunRecord(cogGraphicLabel, lastRecord, "CogFixtureTool1.OutputImage", "");
        }
        cogGraphicLabels.Clear();

        double ave = CalculateAverage(distances);
        double min = CalculateMin(distances);
        double max = CalculateMax(distances);

        CogGraphicLabel aveLabel = new CogGraphicLabel();
        string text = string.Format("平均值:{0:F2}", ave);
        aveLabel.SetXYText(10, 10, text);
        aveLabel.Font = new Font("黑体", 20);
        aveLabel.Color = CogColorConstants.Red;
        aveLabel.SelectedSpaceName = "@";

        CogGraphicLabel minLabel = new CogGraphicLabel();
        text = string.Format("最小值:{0:F2}", min);
        minLabel.SetXYText(10, 60, text);
        minLabel.Font = new Font("黑体", 20);
        minLabel.Color = CogColorConstants.Red;
        minLabel.SelectedSpaceName = "@";

        CogGraphicLabel maxLabel = new CogGraphicLabel();
        text = string.Format("最大值:{0:F2}", max);
        maxLabel.SetXYText(10, 130, text);
        maxLabel.Font = new Font("黑体", 20);
        maxLabel.Color = CogColorConstants.Red;
        maxLabel.SelectedSpaceName = "@";
        toolGroup.AddGraphicToRunRecord(aveLabel, lastRecord, "CogFixtureTool1.OutputImage", "");
        toolGroup.AddGraphicToRunRecord(minLabel, lastRecord, "CogFixtureTool1.OutputImage", "");
        toolGroup.AddGraphicToRunRecord(maxLabel, lastRecord, "CogFixtureTool1.OutputImage", "");
        distances.Clear();

        foreach (CogCreateSegmentTool cogCreateSegmentTool in cogCreateSegmentTools)
        {
            toolGroup.AddGraphicToRunRecord(cogCreateSegmentTool.Segment, lastRecord, "CogFixtureTool1.OutputImage", "");
        }
        cogCreateSegmentTools.Clear();

    }
    #endregion

    #region "When the Script is Initialized"
    public override void Initialize(CogToolGroup host)
    {
        base.Initialize(host);
    }
    #endregion

}

颜色匹配绘制标签

c#
#region namespace imports
using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Cognex.VisionPro;
using Cognex.VisionPro.ToolBlock;
using Cognex.VisionPro3D;
using Cognex.VisionPro.ImageProcessing;
using Cognex.VisionPro.PMAlign;
using Cognex.VisionPro.CompositeColorMatch;
#endregion

public class CogToolBlockAdvancedScript : CogToolBlockAdvancedScriptBase
{
  #region Private Member Variables
  private Cognex.VisionPro.ToolBlock.CogToolBlock mToolBlock;
  
  //1.code  定义一个标签用于显示结果和管理图形对象集合的工具
  CogGraphicLabel resultLabel = new CogGraphicLabel();
  CogGraphicCollection cc = new CogGraphicCollection();
  
  
  #endregion

  public override bool GroupRun(ref string message, ref CogToolResultConstants result)
  {

    cc.Clear();
    foreach(ICogTool tool in mToolBlock.Tools)
      mToolBlock.RunTool(tool, ref message, ref result);

    //2.code 
    //2.1 首先获取 PMA的运行结果 for foreach来获取多个结果 
     //获取工具 CogPMAlignTool1和CogCompositeColorMatchTool1
    CogPMAlignTool  pma  = mToolBlock.Tools["CogPMAlignTool1"]  as    CogPMAlignTool;  
    CogCompositeColorMatchTool  match  = mToolBlock.Tools["CogCompositeColorMatchTool1"]  as    CogCompositeColorMatchTool; 

    //计数定义
    int blueNum = 0;
    int greenNum = 0;
    int redNum = 0;
    
    int yellowNum = 0;
    int orangeNum = 0;
    
    
    //2.2 针对每个结果运行一下 复合颜色匹配工具
    foreach(CogPMAlignResult item   in pma.Results )  //item  指代 pma的每一个运行结果
    {
      //获取颜色匹配工具的匹配范围
      CogRectangleAffine region = match.Region  as  CogRectangleAffine;  
      region.CenterX = item.GetPose().TranslationX;  //设置颜色匹配工具的匹配范围  
      region.CenterY = item.GetPose().TranslationY; 
      region.Rotation = item.GetPose().Rotation;//旋转角度
      match.Run(); 
       
      //获取颜色匹配的最佳结果
      string color = match.Result.ResultOfBestMatch.Color.Name;//最佳匹配结果
      //2.3 获取结果进行统计
      switch(color)
      {
        case "蓝色":
          blueNum++;
          break;
        case "绿色":
          greenNum++;
          break;
        case "红色":
          redNum++;
          break;
        case "黄色":
          yellowNum++;
          break;
        case "橘色":
          orangeNum++;
          break;
        default:
          break; 
      } 
      CogGraphicLabel label = new CogGraphicLabel();
      label.SetXYText(item.GetPose().TranslationX+10,item.GetPose().TranslationY-50,color);
      label.Color = CogColorConstants.Blue;
      label.Font = new Font("楷体", 12);
      label.Alignment = CogGraphicLabelAlignmentConstants.TopLeft;//左上角放置
      cc.Add(label);
    } //for结束 
    string res = String.Format("蓝色:{0} 绿色{1} 红色{2} 黄色{3} 橘色{4} ", blueNum, greenNum, redNum, yellowNum, orangeNum);
    resultLabel.SetXYText(300,50,res);
    
    
    return false;
  }

  #region When the Current Run Record is Created
  public override void ModifyCurrentRunRecord(Cognex.VisionPro.ICogRecord currentRecord)
  {
  }
  #endregion

  #region When the Last Run Record is Created
  public override void ModifyLastRunRecord(Cognex.VisionPro.ICogRecord lastRecord)
  {
    //3.code
    mToolBlock.AddGraphicToRunRecord(resultLabel, lastRecord,"CogImageConvertTool1.InputImage",""  );
    foreach (ICogGraphic item in cc)
    {
      mToolBlock.AddGraphicToRunRecord(item, lastRecord, "CogImageConvertTool1.InputImage", "");
    }
    
  }
  #endregion

  #region When the Script is Initialized
  public override void Initialize(Cognex.VisionPro.ToolGroup.CogToolGroup host)
  {
    base.Initialize(host);

    this.mToolBlock = ((Cognex.VisionPro.ToolBlock.CogToolBlock)(host));
  }
  #endregion

}

读取 CogToolBlock VPP调用

c#
using Cognex.VisionPro;
using Cognex.VisionPro.ToolBlock;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp._04_10
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private CogToolBlock cogToolBlock;

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "VPP 文件|*.vpp";
            openFileDialog.Title = "选择 VPP 文件";
            openFileDialog.InitialDirectory = @"F:\";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string filePath = openFileDialog.FileName;
                cogToolBlock = CogSerializer.LoadObjectFromFile(filePath) as CogToolBlock;
                if (cogToolBlock != null)
                {
                    MessageBox.Show("加载成功");
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            cogToolBlock.Run();
            cogRecordDisplay1.Record = cogToolBlock.CreateLastRunRecord().SubRecords[0];
            cogRecordDisplay1.Fit();
        }
    }
}

读取 QuickBuild VPP调用

c#
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Cognex.VisionPro;
using Cognex.VisionPro.QuickBuild;
using Cognex.VisionPro.QuickBuild.Implementation.Internal;
using Cognex.VisionPro.ToolGroup;
using Cognex.VisionPro.SearchMax;



namespace CapsuleDefectDetection

{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        private CogJobManager cogJobManager;

        private CogToolGroup cogToolGroup;

        private List<Bitmap> imageList = new List<Bitmap>();

        private Bitmap currentImg;

        private int currentImgIndex = 0;


        private void btnAddImg_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "All Image Files|*.bmp;*.ico;*.gif;*.jpeg;*.jpg;*.png;*.tif;*.tiff;*.idb|Windows Bitmap(*.bmp)|*.bmp|Windows Icon(*.ico)|*.ico|Graphics Interchange Format (*.gif)|(*.gif)|JPEG File Interchange Format (*.jpg)|*.jpg;*.jpeg|Portable Network Graphics (*.png)|*.png|Tag Image File Format (*.tif)|*.tif;*.tiff|Image DataBase (*.idb)|*.idb;";
            openFileDialog.Title = "选择图片文件";
            openFileDialog.InitialDirectory = @"C:\";
            openFileDialog.Multiselect = true; // 允许多选
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                foreach (string filePath in openFileDialog.FileNames)
                {
                    using (Image image = Image.FromFile(filePath))
                    {
                        Bitmap bitmap = new Bitmap(image);
                        imageList.Add(bitmap);
                    }
                }
                MessageBox.Show("成功加载" + imageList.Count.ToString() + "张图片");
                this.labelTotalPage.Text = "总页数:" + imageList.Count.ToString();
                currentImg = imageList[0];
                this.cogRecordDisplay1.Image = new CogImage24PlanarColor(currentImg);
            }
        }

        private void btnPrevious_Click(object sender, EventArgs e)
        {
            if (imageList.Count == 0)
            {
                MessageBox.Show("请先加载图片");
                return;
            }
            if (currentImgIndex > 0)
            {
                cogRecordDisplay1.Record = null;
                currentImgIndex--;
                currentImg = imageList[currentImgIndex];
                this.cogRecordDisplay1.Image = new CogImage24PlanarColor(currentImg);
                this.labelPage.Text = "第 " + (currentImgIndex + 1).ToString() + " 页";
            }
            else
            {
                MessageBox.Show("已经是第一页了");
            }
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            if (imageList.Count == 0)
            {
                MessageBox.Show("请先加载图片");
                return;
            }
            if (currentImgIndex < imageList.Count - 1)
            {
                cogRecordDisplay1.Record = null;
                currentImgIndex++;
                currentImg = imageList[currentImgIndex];
                this.cogRecordDisplay1.Image = new CogImage24PlanarColor(currentImg);
                this.labelPage.Text = "第 " + (currentImgIndex + 1).ToString() + " 页";
            }
            else
            {
                MessageBox.Show("已经是最后一页了");
            }
        }

        private void btnClearnImg_Click(object sender, EventArgs e)
        {
            if (imageList.Count == 0)
            {
                MessageBox.Show("没有图片可以清除");
                return;
            }
            foreach (Bitmap bitmap in imageList)
            {
                bitmap.Dispose();
            }
            imageList.Clear();
            currentImg = null;
            this.cogRecordDisplay1.Image = null;
            this.labelPage.Text = "第 1 页";
            this.labelTotalPage.Text = "总页数:1";
            MessageBox.Show("成功清除所有图片");
        }

        private void btnLoadTool_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Tool Block Files|*.vpp";
            openFileDialog.Title = "选择 CogToolBlock 文件";
            openFileDialog.InitialDirectory = @"C:\";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string filePath = openFileDialog.FileName;
                cogJobManager = CogSerializer.LoadObjectFromFile(filePath) as CogJobManager;

                if (cogJobManager != null)
                {
                    MessageBox.Show("cogJobManager 加载成功");
                }
                else
                {
                    MessageBox.Show("cogJobManager 加载失败");
                    return;
                }
                cogToolGroup = cogJobManager.Job(0).VisionTool as CogToolGroup;
            }
        }

        private void AddDataListItems(ListViewItem listViewItem)
        {
            foreach (ListViewItem item in lvData.Items)
            {
                if (item.SubItems[0].Text == listViewItem.SubItems[0].Text)
                {
                    for (int i = 1; i < listViewItem.SubItems.Count; i++)
                    {
                        item.SubItems[i].Text = listViewItem.SubItems[i].Text;
                    }
                    return;
                }
            }
            lvData.Items.Add(listViewItem);
        }


        private void btnDetection_Click(object sender, EventArgs e)
        {
            //CogImageConvertTool cogImageConvertTool = cogToolGroup.Tools["CogImageConvertTool1"] as CogImageConvertTool;
            //cogImageConvertTool.InputImage = new CogImage24PlanarColor(currentImg);
            //cogJobManager.Job(0).Run();
            CogInputImageTool cogInputImageTool = cogToolGroup.Tools["Image Source"] as CogInputImageTool;
            cogInputImageTool.InputImage = new CogImage24PlanarColor(currentImg);
            cogToolGroup.Run();
            cogRecordDisplay1.Record = cogToolGroup.CreateLastRunRecord().SubRecords[0];
            cogRecordDisplay1.Fit();
            CogSearchMaxTool cogSearchMaxToolHege = cogToolGroup.Tools["hege"] as CogSearchMaxTool;
            CogSearchMaxTool cogSearchMaxToolQueshi = cogToolGroup.Tools["queshi"] as CogSearchMaxTool;
            int hege = cogSearchMaxToolHege.Results.Count;
            int queshi = cogSearchMaxToolQueshi.Results.Count;
            int chuofang = 15 - hege - queshi;
            string total = hege == 15 ? "合格" : "不合格";
            String date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            ListViewItem listViewItem = new ListViewItem(new string[] { (currentImgIndex + 1).ToString(), date, "黑奴", hege.ToString(), queshi.ToString(), chuofang.ToString(), total.ToString() });
            AddDataListItems(listViewItem);

        }

        private void btnSaveData_Click(object sender, EventArgs e)
        {

            string path = Directory.GetCurrentDirectory() + @"/data";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            string fileName = path + @"/" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".csv";
            using (StreamWriter sw = new StreamWriter(fileName, false, Encoding.UTF8))
            {
                sw.WriteLine("Id,时间,管理员,合格个数,缺失个数,错放个数,结果");
                foreach (ListViewItem item in lvData.Items)
                {
                    string line = "";
                    for (int i = 0; i < item.SubItems.Count; i++)
                    {
                        line += item.SubItems[i].Text + ",";
                    }
                    sw.WriteLine(line.TrimEnd(','));
                }
            }
            MessageBox.Show("数据保存成功,文件名为:" + fileName);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 释放资源
            if (cogToolGroup != null)
            {
                cogToolGroup.Dispose();
                cogToolGroup = null;
            }
            if (cogJobManager != null)
            {
                cogJobManager.Shutdown();
                cogJobManager = null;
            }
        }
    }
}

Job 内置事件用法

c#
using Cognex.VisionPro;
using Cognex.VisionPro.Caliper;
using Cognex.VisionPro.Comm;
using Cognex.VisionPro.FGGigE;
using Cognex.VisionPro.QuickBuild;
using Cognex.VisionPro.ResultsAnalysis;
using Cognex.VisionPro.ToolGroup;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace VPPDemo
{
    public partial class Form1 : Form
    {
        private const int INFO_OK = 0;
        private const int INFO_ERR = -1;

        CogJobManager cogJobManager;
        CogFindCircleTool cogFindCircleTool;
        CogToolGroup cogToolGroup;
        CogAcqFifoTool cogAcqFifoTool;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string path = @"C:\Users\Administrator\Desktop\QuickBuild1.vpp"; //VPP绝对地址
            cogJobManager = (CogJobManager)CogSerializer.LoadObjectFromFile(path);//加载VPP文件并序列化
            cogToolGroup = cogJobManager.Job(0).VisionTool as CogToolGroup; //获取Job中的工具组0
            cogJobManager.Job(0).Running += new CogJob.CogJobRunningEventHandler(Job_Running); //注册事件
            cogJobManager.Job(0).Stopped += new CogJob.CogJobStoppedEventHandler(Job_Stopped); //注册事件
            cogAcqFifoTool = cogToolGroup.Tools["CogAcqFifoTool1"] as CogAcqFifoTool; //获取工具组中的CogFindCircleTool1
        }

        private void Job_Running(object sender,CogJobActionEventArgs e)
        {
            Console.WriteLine("Job running......");
        }

        private void Job_Stopped(object sender, CogJobActionEventArgs e)
        {
            Console.WriteLine("Job stopped......");
        }

        private void Form1_Running(object sender, CogJobActionEventArgs e)
        {
           
        }

        private void button1_Click(object sender, EventArgs e)
        {
            cogJobManager.Job(0).Run();
            cogRecordDisplay1.Image = cogAcqFifoTool.OutputImage;
            cogRecordDisplay1.AutoFit = true;//图像显示控件图像自适应大小
        }

        private void button2_Click(object sender, EventArgs e)
        {
            cogJobManager.Shutdown();
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            cogAcqFifoTool.Dispose();
            Application.ExitThread();
            Application.Exit();
            Environment.Exit(0);
        }
    }
}

脚本代码段含义

以下是每段代码的运行时机概览:

方法名运行时机主要作用
GroupRun工具组运行时自定义工具组中工具的运行方式
ModifyCurrentRunRecord当前运行记录创建时修改或添加当前运行记录的内容
ModifyLastRunRecord最后运行记录创建时修改或添加最后运行记录的内容
Initialize脚本初始化时执行初始化设置或准备工作

区别

1. 当前运行记录(Current Run Record)
  • 含义:当前运行记录是在工具组正在运行刚刚完成运行时生成的记录。它包含了本次运行中各个工具产生的数据,例如图像、测量值、状态信息等。
  • 用途:用于在运行过程中或运行后立即访问和修改本次运行的结果。在脚本中,可以通过ModifyCurrentRunRecord方法对当前运行记录进行自定义操作,比如添加额外的图形或数据。
  • 特点:与当前的单次运行紧密相关,每次运行都会生成一个新的当前运行记录。
2. 最后运行记录(Last Run Record)
  • 含义:最后运行记录是工具组最近一次完成运行时保存的记录。它存储了上一次运行的所有结果数据,并在工具组的属性或用户界面中保留,直到被下一次运行覆盖。
  • 用途:用于查看或分析最近一次运行的结果,例如在用户界面中显示最后的图像或测量数据。在脚本中,可以通过ModifyLastRunRecord方法对最后运行记录进行修改。
  • 特点:始终保存最近一次运行的数据,在下一次运行完成后会被更新。

主要区别

  • 时间点

    • 当前运行记录正在进行的运行刚刚结束的运行相关,反映的是本次运行的数据。
    • 最后运行记录最近一次完成的运行相关,保存的是上一次运行的结果。
  • 生命周期

    • 每次运行生成一个新的当前运行记录。
    • 运行完成后,当前运行记录会成为新的最后运行记录,覆盖之前的内容。
  • 使用场景

    • 当前运行记录适用于实时操作或立即处理本次运行数据。
    • 最后运行记录适用于回顾或展示最近一次运行的结果。
  • 单次运行:运行工具组一次后,当前运行记录和最后运行记录都包含这次运行的结果。

  • 连续运行

    • 第一次运行:生成当前运行记录A,完成后A成为最后运行记录。
    • 第二次运行:生成新的当前运行记录B,完成后B成为新的最后运行记录,A被覆盖。

设置相机参数

c#
using Cognex.VisionPro;
using Cognex.VisionPro.FGGigE.Implementation.Internal;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp._04_09
{
    public partial class FormCamera : System.Windows.Forms.Form
    {
        string filePath;
        private CogFrameGrabbers cogFrameGrabbers;
        private string CameraName;//相机名称
        private int Exposure;//曝光时间
        private double Bright;//相机亮度
        private string IP;//IP地址
        ICogFrameGrabber MGrabber = null;
        ICogAcqFifo MFifo = null;
        CogFrameGrabbers CogFrame;
        //定义图像类型 8位灰度图
        CogImage8Grey cogImage8Grey = new CogImage8Grey();

        private void init()
        {
            string path = Directory.GetCurrentDirectory() + @"\Profile\";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            filePath = path + "config.ini";
            if (File.Exists(filePath))
            {
                using (FileStream fileStream = File.OpenRead(filePath))
                {
                    if (fileStream != null)
                    {
                        txtCameraName.Text = IniAPI.GetPrivateProfileString("相机参数配置", "相机名称", "0", filePath);
                        CameraName = txtCameraName.Text;
                        txtExposureTime.Text = IniAPI.GetPrivateProfileInt("相机参数配置", "曝光时间", 0, filePath).ToString();
                        Exposure = Convert.ToInt32(txtExposureTime.Text);
                        txtCameraBright.Text = IniAPI.GetPrivateProfileDouble("相机参数配置", "相机亮度", 0, filePath).ToString();
                        Bright = Convert.ToDouble(txtCameraBright.Text);
                        txtCameraIP.Text = IniAPI.GetPrivateProfileString("相机参数配置", "相机IP", "192.168.1.1", filePath);
                        IP = txtCameraIP.Text;

                        cogFrameGrabbers = new CogFrameGrabbers();
                        if (cogFrameGrabbers.Count > 0)
                        {
                            label5.Text = "相机设备数量: " + cogFrameGrabbers.Count.ToString();
                            foreach (ICogFrameGrabber frameGrabber in cogFrameGrabbers)
                            {
                                MGrabber = frameGrabber;
                                MFifo = frameGrabber.CreateAcqFifo("Generic GigEVision (Mono)", CogAcqFifoPixelFormatConstants.Format8Grey, 0, true);
                                MFifo.OwnedExposureParams.Exposure = Exposure;
                                MFifo.OwnedGigEVisionTransportParams.LatencyLevel = 1;
                                MFifo.OwnedBrightnessParams.Brightness = Bright;
                                MFifo.Complete += MAcq;
                            }
                        }
                        else
                        {
                            MessageBox.Show("没有相机设备");
                        }
                    }
                }
            }
        }

        private void MAcq(object sender, EventArgs e)
        {
            try
            {
                int numPending, numReady; // 等待状态,准备状态
                bool isBusy; // 繁忙状态
                // 获取当前 相机的状态
                MFifo.GetFifoState(out numPending, out numReady, out isBusy);
                if (numReady > 0) // 判断相机是否准备好
                {
                    CogAcqInfo info = new CogAcqInfo(); // 创建acqinfo对象
                    cogImage8Grey = MFifo.CompleteAcquireEx(info) as CogImage8Grey; // 获取图像 
                    cogRecordDisplay1.Image = cogImage8Grey; // 显示图片
                    cogRecordDisplay1.Fit();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        public FormCamera()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {

            IniAPI.INIWriteValue(filePath, "相机参数配置", "相机名称", txtCameraName.Text);
            IniAPI.INIWriteValue(filePath, "相机参数配置", "曝光时间", txtExposureTime.Text);
            IniAPI.INIWriteValue(filePath, "相机参数配置", "相机亮度", txtCameraBright.Text);
            IniAPI.INIWriteValue(filePath, "相机参数配置", "相机IP", txtCameraIP.Text);
            MessageBox.Show("保存成功");
        }

        private void Form_Load(object sender, EventArgs e)
        {
            init();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MFifo.StartAcquire();
        }

        private void Form_FormClosing(object sender, FormClosingEventArgs e)
        {
            foreach (ICogFrameGrabber frameGrabber in cogFrameGrabbers)
            {
                if (frameGrabber != null)
                {
                    frameGrabber.Disconnect(false);
                }
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            init();
        }
    }
}
c#
ICogAcqFifo acq = cogAcqFifoEditV21.Subject.Operator;
//曝光
acq.OwnedExposureParams.Exposure = 100;
//亮度
acq.OwnedBrightnessParams.Brightness = 0.5;
//对比度
acq.OwnedContrastParams.Contrast = 0.6;
//超时
acq.TimeoutEnabled = true;
//超时时间
acq.Timeout = 1000;
//触发
acq.OwnedTriggerParams.TriggerEnabled = true;
//触发模式
acq.OwnedTriggerParams.TriggerModel = CogAcqTriggerModelConstants.FreeRun;
//ROI模式
acq.OwnedROIParams.ROIMode = CogAcqROIModeConstants.Manual;
//ROI区域
acq.OwnedROIParams.SetROIXYWidthHeight(10,10,1800,2000);
//延迟级别
acq.OwnedGigEVisionTransportParams.LatencyLevel = 2;
//传输超时
acq.OwnedGigEVisionTransportParams.TransportTimeout = 2000;
//包大小
acq.OwnedGigEVisionTransportParams.PacketSize = 10000;
//图像模式
acq.OutputPixelFormat = CogImagePixelFormatConstants.Grey16;

串口通信

c#
private SerialPort serialPort;

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    serialPort.Close();
}

private void Form1_Load(object sender, EventArgs e)
{
    serialPort = new SerialPort();
    serialPort.PortName = "COM2"; // 设置串口名称
    serialPort.BaudRate = 9600; // 设置波特率
    serialPort.DataBits = 8; // 设置数据位
    serialPort.Parity = Parity.None; // 设置校验位
    serialPort.StopBits = StopBits.One; // 设置停止位
    serialPort.Open();
}

private void button1_Click(object sender, EventArgs e)
{
    if (serialPort.IsOpen)
    {
        serialPort.WriteLine(textBox2.Text);
    }
}

Released under the MIT License.