界面含义
工具列表
Calibration & fixturing
Color
Geometry - Creation
Geometry - Finding & Fitting
Geometry -Measurement
Image Frocessing
模板匹配
参数
算法
PatMax:精准度最高 匹配速度是最慢的 一般用于细微细节匹配的 例如:焊接工艺 PatQuick:精度较低 匹配速度较快 一般用于对细节或者质感没有太大要求的部件。例如:物品的检方 PatMax 与 PatQuick:介于以上两者之间 PatFlex:一般用于图像表面不平整,高灵活的图案的设计 PatMax -高灵敏度:适用对比度很低或者视频噪音或图像变形严重的图像 透视 -PatMax:查找已经历透视失真的二维特征
训练模式
图像:以我们训练的图像为模型,可以使用图像掩膜编辑器。 带图像的形状模型:在找不到整体质量好的训练元件的场合使用,可以在图像上使用建模器。 带转换的形状模型:使用建模器构建的模型。
极性
极性:表示特征边界点是从黑到白还是从白到黑,忽略极性可增加模型的多样性; 默认情况下要求训练的图像要求极性相同,如果忽略极性则只考虑轮廓与之相同即可,光线的变化的不考虑
重复模式
当训练的样板包含重复元素,例如网格,栏组,或平行线样板时,使用此参数
颗粒度
颗粒度被描述为探测到目的特征的半径,以像素表示
弹性
此属性为 PMAlign 工具允许的像素变量。通常,如果您希望运行时图像中的样板发生不同的变化,应指定非零的弹性值
图像坐标
VisionPro的默认空间
输入图像空间:“.” 像素空间:“#” 根空间:“@”
边缘阈值
图像显示
模板匹配
工具含义
CogPatInspectTool
输入参数:
- InputImage:
- 输入图像,通常是从上一处理步骤(如图中
CogPMAlignTool1
)传来的图像,用于进行图案检测。
- 输入图像,通常是从上一处理步骤(如图中
- Pose:
- 工件的姿态(位置和角度),用于将检测模板对齐实际图像中的位置。通常由
CogPMAlignTool1
提供的匹配位姿GetPose()
提供。
- 工件的姿态(位置和角度),用于将检测模板对齐实际图像中的位置。通常由
- Pattern.TrainImage:
- 用于训练的模板图像,即你想要在目标图像中找到的图案。通常是初始图像或从某个区域截取的参考图。
- Pattern.Origin:
- 模板图像的原点(坐标参考点),用于标定与目标图像中图案位置的偏移关系。
编程
脚本
主要使用的库和命名空间
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 (圆查找工具)
作用:检测图像中的圆形并提取圆心坐标
CogFindCircleTool cogFindCircleTool = toolGroup.Tools["CogFindCircleTool1"] as CogFindCircleTool;
double circleX = cogFindCircleTool.Results.GetCircle().CenterX;
double circleY = cogFindCircleTool.Results.GetCircle().CenterY;
CogPMAlignTool (模式匹配工具)
作用:在图像中查找预先训练的模板,获取匹配位置
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 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 (图形标签工具)
作用:在图像上显示文本信息
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 (线段创建工具)
作用:创建并显示两点之间的连接线段
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
CogImageFileTool cogImageFileTool = new CogImageFileTool();
cogImageFileTool.Operator.Open(filePath, CogImageFileModeConstants.Read);
cogImageFileTool.Run();
cogRecordDisplay1.Image = cogImageFileTool.OutputImage;
方法二 (FormImageV2):使用 .NET 标准库 + 转换
using (Image image = Image.FromFile(filePath))
{
Bitmap bitmap = new Bitmap(image);
CogImage8Grey image8Grey = new CogImage8Grey(bitmap);
cogRecordDisplay1.Image = image8Grey;
}
图像保存
方法一 (FormImageV1):使用 CogImageFileTool
CogImageFileTool cogImageFileTool = new CogImageFileTool();
cogImageFileTool.InputImage = cogRecordDisplay1.Image;
cogImageFileTool.Operator.Open(filePath, CogImageFileModeConstants.Write);
cogImageFileTool.Run();
方法二 (FormImageV2):使用 CreateContentBitmap
Bitmap bitmap = cogRecordDisplay1.CreateContentBitmap(CogDisplayContentBitmapConstants.Image) as Bitmap;
bitmap.Save(filePath);
工具访问与执行
从工具组获取工具:
CogTool tool = toolGroup.Tools["工具名称"] as CogTool类型;
执行工具:
// 方法1: 通过工具组执行
toolGroup.RunTool(tool, ref message, ref result);
// 方法2: 直接调用工具的Run方法
tool.Run();
从文件反序列化 cogToolBlock 工具:
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
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的面积
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.Inputs | cogToolBlock.CreateLastRunRecord().SubRecords[0] |
---|---|---|
用途 | 配置输入 | 获取结果 |
时间点 | 运行前 (Before Run) | 运行后 (After Run) |
数据流向 | 外部 -> 工具块 (Data In) | 工具块内部 -> 外部 (Data Out / Results) |
操作 | 设置 (Setting) | 读取 (Getting) |
关注点 | 工具块需要什么来运行 | 工具块(或其内部工具)上次运行产生了什么 |
cogToolGroup 工具组
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 参数
工具块与工具组的区别
访问工具和结果的方式:
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;
工具访问的灵活性:
CogToolGroup:由于可以直接访问 Tools 集合,代码编写时更灵活,开发者可以动态地操作组内任意工具。
CogToolBlock:工具内部的具体实现对外部代码是隐藏的,外部只能通过定义好的输入(Inputs)和输出(Outputs)接口与工具块交互,限制了直接访问内部工具的灵活性。
封装性
CogToolGroup:没有严格的封装性,组内的工具和结果对外部代码是透明的。
CogToolBlock:具有较高的封装性,内部工具和逻辑对外部代码不可见,只能通过预定义的接口(Inputs/Outputs)进行交互,适合模块化设计。
图形显示和结果记录
创建统计信息标签:
csharpCogGraphicLabel label = new CogGraphicLabel(); label.SetXYText(x, y, "文本内容"); label.Font = new Font("字体名", 字号); label.Color = CogColorConstants.颜色; // 固定位置(屏幕坐标)显示时使用: label.SelectedSpaceName = "@";
添加图形到结果记录:
csharptoolGroup.AddGraphicToRunRecord(图形对象, lastRecord, "显示工具.OutputImage", "");
附加模板匹配的结果
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();
}
图片格式
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("图片加载成功");
}
示例脚本
模板匹配绘制标签
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
}
颜色匹配绘制标签
#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调用
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调用
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 内置事件用法
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被覆盖。
设置相机参数
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();
}
}
}
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;
串口通信
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);
}
}