1绘制和保存
1. 模板文件加载 + 控件关联 + 事件绑定(Form 加载核心)
csharp
运行
// 从本地vpp文件加载已保存的PMAlign工具配置(含模板、参数)
pma = CogSerializer.LoadObjectFromFile("文件路径.vpp") as CogPMAlignTool;
cogPMAlignEditV21.Subject = pma; // 绑定工具到编辑控件,可视化编辑模板
pma.Run += Pma_Ran; // 绑定工具运行完成事件(运行后执行绘制/结果处理)
// 读取工具参数并赋值给界面控件(实现参数可视化)
textBox1.Text = pma.RunParams.ApproximateNumberToFind.ToString(); // 读取查找数量
numericUpDown1.Value = (decimal)pma.RunParams.AcceptThreshold; // 读取匹配阈值
2. 运行完成事件(核心:匹配结果获取 + 动态绘制图形)
csharp
运行
private void Pma_Ran(object sender, EventArgs e)
{
// 将匹配结果绑定到显示控件,可视化匹配过程/结果
cogRecordDisplay1.Record = pma.CreateLastRunRecord().SubRecords[0];
cogRecordDisplay1.Fit(); // 自适应显示图像
// 遍历所有匹配结果(支持多目标匹配)
for (int i = 0; i < pma.Results.Count; i++)
{
CogPMAlignResult result = pma.Results[i]; // 获取单个匹配结果
CogCircle cir = new CogCircle(); // 实例化绘制圆形(可替换为矩形/线)
// 关键:将匹配结果的位姿坐标赋值给绘制图形(精准定位匹配目标中心)
cir.CenterX = result.GetPose().TranslationX;
cir.CenterY = result.GetPose().TranslationY;
// 绘制图形样式设置
cir.Radius = 20; // 圆半径
cir.LineWidthInScreenPixels = 2; // 线宽
cir.Color = CogColorConstants.Red; // 绘制颜色(红色)
// 将绘制图形添加到显示控件,实现匹配目标标注
cogRecordDisplay1.StaticGraphics.Add(cir, "唯一标识");
}
}
3. 手动运行工具 + 界面参数回写(按钮触发)
csharp
运行
// 从界面控件读取参数,赋值给工具并执行匹配
int num1 = int.Parse(textBox1.Text); // 读取界面设置的查找数量
pma.RunParams.ApproximateNumberToFind = num1; // 回写查找数量参数
pma.RunParams.AcceptThreshold = (double)numericUpDown1.Value; // 回写匹配阈值参数
pma.Run(); // 执行模板匹配(触发Run事件)
3. 工具配置保存(按钮触发,永久保存模板 / 参数)
csharp
运行
// 将PMAlign工具的所有配置(模板、参数、绘制等)保存为vpp文件,下次可直接加载
CogSerializer.SaveObjectToFile(pma, "保存路径.vpp");
关键 API 速查
| 功能 | 核心 API / 对象 |
|---|---|
| PMAlign 工具实例化 | CogPMAlignTool |
| 序列化加载 / 保存 | CogSerializer.Load/SaveObjectToFile |
| 匹配结果集 | pma.Results |
| 单个匹配位姿坐标 | result.GetPose().TranslationX/Y |
| 图像显示控件赋值 | cogRecordDisplay1.Record |
| 动态绘制图形 | CogCircle/CogRectangle + StaticGraphics.Add |
| 核心运行参数 | pma.RunParams.ApproximateNumberToFind/AcceptThreshold |
cs
namespace _02绘制和保存
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
CogPMAlignTool pma = new CogPMAlignTool();
//加载
private void Form1_Load(object sender, EventArgs e)
{
string path = @"C:\Users\Administrator\Desktop\新建文件夹\huizhibaocun.vpp";
pma = CogSerializer.LoadObjectFromFile(path) as CogPMAlignTool;//sb
cogPMAlignEditV21.Subject = pma;
pma.Ran += Pma_Ran;
textBox1.Text = pma.RunParams.ApproximateNumberToFind.ToString(); //获取查找概数
MessageBox.Show(pma.RunParams.AcceptThreshold + "");
numericUpDown1.Value = (decimal)pma.RunParams.AcceptThreshold ;// 获取接收阈值
}
private void Pma_Ran(object sender, EventArgs e)
{
cogRecordDisplay1.Record = pma.CreateLastRunRecord().SubRecords[0];
cogRecordDisplay1.Fit();
for (int i = 0; i < pma.Results.Count; i++)
{
CogPMAlignResult result = pma.Results[i];
CogCircle cir = new CogCircle();
cir.CenterX = result.GetPose().TranslationX;// 获取x坐标
cir.CenterY = result.GetPose().TranslationY;
cir.Radius = 20;
cir.LineWidthInScreenPixels = 2; ;// 线宽
cir.Color = CogColorConstants.Red;
cogRecordDisplay1.StaticGraphics.Add(cir, "ss"); //把圆添加到cogRecordDisplay1上
}
}
//运行
private void button1_Click(object sender, EventArgs e)
{
//获取查找概数
int num1 = int.Parse(textBox1.Text);
pma.RunParams.ApproximateNumberToFind = num1;
// 获取接收阈值
pma.RunParams.AcceptThreshold = (double)numericUpDown1.Value;
pma.Run();//执行
}
//保存
private void button2_Click(object sender, EventArgs e)
{
CogSerializer.SaveObjectToFile(pma, @"C:\Users\Administrator\Desktop\新建文件夹\huizhibaocun.vpp");//保存vpp
}
}
2 加载tb块
1. 全局核心对象(ToolBlock 是核心,整合多工具的容器)
CogToolBlock tb = new CogToolBlock(); // 实例化ToolBlock工具块(整合多视觉工具的容器)
List<string> pics = new List<string>(); // 存储批量读取的图像路径
int index = 0; // 图像遍历索引(用于切换/批量处理图像)
2. 窗体加载:多线程加载 ToolBlock(避免 UI 卡顿,核心优化)
private void Form1_Load(object sender, EventArgs e)
{
Thread th = new Thread(f1); // 开启子线程加载vpp文件
th.Start();
}
// 子线程执行:加载ToolBlock+跨线程绑定UI控件
public void f1()
{
// 从vpp文件加载ToolBlock(含内部所有视觉工具、参数、流程)
tb = CogSerializer.LoadObjectFromFile("tb.vpp路径") as CogToolBlock;
// 跨线程更新UI(子线程不能直接操作WinForm控件,Invoke是必用)
this.Invoke(new Action(() =>
{
cogToolBlockEditV21.Subject = tb; // 绑定工具块到编辑控件,可视化编辑内部流程
}));
}
3. 选择文件夹:批量读取图像路径 + 单张图像初始化运行
FolderBrowserDialog fd = new FolderBrowserDialog(); // 文件夹选择对话框
if (fd.ShowDialog() == DialogResult.OK)
{
string[] s1 = Directory.GetFiles(fd.SelectedPath); // 获取文件夹下所有文件路径
foreach (var item in s1) pics.Add(item); // 存入图像路径集合
// 图像格式转换:本地图片(Bitmap) → VisionPro可识别的CogImage24PlanarColor
Bitmap map = Image.FromFile(pics[0]) as Bitmap;
CogImage24PlanarColor img = new CogImage24PlanarColor(map);
// 关键:给ToolBlock输入参数赋值(对接工具块内部的图像输入)
tb.Inputs["OutputImage"].Value = img;
tb.Run(); // 执行ToolBlock内部所有视觉工具
// 显示运行结果到图像控件
cogRecordDisplay1.Record = tb.CreateLastRunRecord().SubRecords[0];
cogRecordDisplay1.Fit(); // 自适应显示
}
4. 批量运行:图像切换 + ToolBlock 执行 + 输出参数获取 + OK/NG 分类保存(核心业务)
index++; // 切换下一张图像
if (index == pics.Count) index = 0; // 循环遍历图像
// 1. 图像加载+格式转换+ToolBlock输入赋值+执行
Bitmap map = Image.FromFile(pics[index]) as Bitmap;
CogImage24PlanarColor img = new CogImage24PlanarColor(map);
tb.Inputs["OutputImage"].Value = img;
tb.Run();
// 2. 结果显示
cogRecordDisplay1.Record = tb.CreateLastRunRecord().SubRecords[0];
cogRecordDisplay1.Fit();
// 3. 关键:获取ToolBlock**输出参数**(内部工具的运算结果,如灰度均值)
double huiduzhi = (double)tb.Outputs["Result_Mean"].Value;
this.Text = huiduzhi.ToString(); // 窗体标题实时显示结果值
// 4. OK/NG文件夹初始化(不存在则创建)
string okPath = Path.Combine(Directory.GetCurrentDirectory(), "OK");
string ngPath = Path.Combine(Directory.GetCurrentDirectory(), "NG");
if (!Directory.Exists(okPath)) Directory.CreateDirectory(okPath);
if (!Directory.Exists(ngPath)) Directory.CreateDirectory(ngPath);
// 5. 按判定条件分类保存图像(保存显示控件上的结果图,含标注)
Bitmap resultBmp = cogRecordDisplay1.CreateContentBitmap(CogDisplayContentBitmapConstants.Image) as Bitmap;
string saveName = $"{DateTime.Now:yyyyMMddHHmmss}.bmp"; // 时间戳命名,避免重复
if (huiduzhi > 100) // OK判定条件
resultBmp.Save(Path.Combine(okPath, saveName));
else // NG判定条件
resultBmp.Save(Path.Combine(ngPath, saveName));
5. ToolBlock 保存:永久保存工具块配置(含内部所有工具、参数)
csharp
运行
// 将ToolBlock的完整配置(内部工具、流程、参数)保存为vpp文件,下次可直接加载
CogSerializer.SaveObjectToFile(tb, @"C:\Users\Administrator\Desktop\新建文件夹\tb.vpp");
关键 API 速查(ToolBlock 专属 + 核心操作)
| 功能 | 核心 API / 语法 |
|---|---|
| ToolBlock 实例化 / 加载 | CogToolBlock + CogSerializer.LoadObjectFromFile |
| 工具块输入赋值 | tb.Inputs["输入参数名"].Value = 赋值 |
| 工具块输出取值 | tb.Outputs["输出参数名"].Value |
| 跨线程更新 UI | this.Invoke(new Action(() => { UI操作 })) |
| 批量获取文件路径 | Directory.GetFiles(文件夹路径) |
| 文件夹创建 / 判断 | Directory.Exists/CreateDirectory |
| 结果图保存 | cogRecordDisplay1.CreateContentBitmap(转 Bitmap)+ Save |
| 时间戳命名 | DateTime.Now.ToString("yyyyMMddhhmmss") |
| ToolBlock 保存 | CogSerializer.SaveObjectToFile(tb, 路径) |
cs
namespace _03加载tb块
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//窗体加载事件
private void Form1_Load(object sender, EventArgs e)
{
Thread th = new Thread(f1);
th.Start();
}
CogToolBlock tb = new CogToolBlock();
public void f1()
{
string path = @"C:\Users\Administrator\Desktop\新建文件夹\tb.vpp";
tb = CogSerializer.LoadObjectFromFile(path) as CogToolBlock; // 类似于vpp里面高级脚本的mToolBlock对象
//tb.Tools["工具名"] as 对应的类型 获取对应的工具
this.Invoke(new Action(() =>
{
cogToolBlockEditV21.Subject = tb;
}));
}
List<string> pics = new List<string>(); //图片路径
//选择图像
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog fd = new FolderBrowserDialog();//文件夹浏览框
if (fd.ShowDialog()==DialogResult.OK)
{
// fd.SelectedPath //文件夹的路径
string[] s1 = Directory.GetFiles(fd.SelectedPath);
foreach (var item in s1)
{
pics.Add(item);
}
Bitmap map = Image.FromFile(pics[0]) as Bitmap;
CogImage24PlanarColor img = new CogImage24PlanarColor(map);
// tb.Inputs tb块输入对象
// tb.Inputs["OutputImage"] tb块OutputImage的输入参数
tb.Inputs["OutputImage"].Value = img;
tb.Run();
cogRecordDisplay1.Record = tb.CreateLastRunRecord().SubRecords[0];
cogRecordDisplay1.Fit();
}
}
int index = 0;
//运行
private void button2_Click(object sender, EventArgs e)
{
index++;
if (index==pics.Count)
{
index = 0;
}
Bitmap map = Image.FromFile(pics[index]) as Bitmap;
CogImage24PlanarColor img = new CogImage24PlanarColor(map);
tb.Inputs["OutputImage"].Value = img;
tb.Run();
cogRecordDisplay1.Record = tb.CreateLastRunRecord().SubRecords[0];
cogRecordDisplay1.Fit();
// 获取输出参数
this.Text = tb.Outputs["Result_Mean"].Value + "";
double huiduzhi = (double)tb.Outputs["Result_Mean"].Value;
string ok = Directory.GetCurrentDirectory() + "\\OK";
string ng = Directory.GetCurrentDirectory() + "\\NG";
if (!Directory.Exists(ok))
{
Directory.CreateDirectory(ok);
}
if (!Directory.Exists(ng))
{
Directory.CreateDirectory(ng);
}
if (huiduzhi>100) //ok图
{
Bitmap map1= cogRecordDisplay1.CreateContentBitmap(Cognex.VisionPro.Display.CogDisplayContentBitmapConstants.Image) as Bitmap;//把控件上记录转成位图
map1.Save(ok + $"\\{DateTime.Now.ToString("yyyyMMddhhmmss")}.bmp");
}
else // ng图
{
Bitmap map1 = (Bitmap)cogRecordDisplay1.CreateContentBitmap(Cognex.VisionPro.Display.CogDisplayContentBitmapConstants.Image);//把控件上记录转成位图
map1.Save(ng + $"\\{DateTime.Now.ToString("yyyyMMddhhmmss")}.bmp");
}
}
// 保存
private void button3_Click(object sender, EventArgs e)
{
CogSerializer.SaveObjectToFile(tb, @"C:\Users\Administrator\Desktop\新建文件夹\tb.vpp");
}
}
3处理vpp脚本的方式
1. 核心全局对象(ToolBlock 工具块为核心容器)
CogToolBlock mToolBlock = new CogToolBlock(); // 实例化ToolBlock,承载vpp内所有视觉工具
2. 窗体加载:ToolBlock 加载 + UI 控件绑定(基础必备)
// 从vpp文件加载ToolBlock(含内部所有子工具、参数,支持不同vpp切换)
string path = @"对应vpp文件路径";
mToolBlock = CogSerializer.LoadObjectFromFile(path) as CogToolBlock;
cogToolBlockEditV21.Subject = mToolBlock; // 绑定到编辑控件,可视化查看/编辑vpp内流程
3. 方式 1:VPP 内置脚本(逻辑写在 VisionPro 的 vpp 中,VS 仅调用执行)
// 极简调用:直接运行ToolBlock,所有逻辑(运算、判断、输出)由vpp内置脚本完成
mToolBlock.Run();
// 直接获取vpp内脚本定义的输出参数,无需在VS中写业务逻辑
this.Text = mToolBlock.Outputs["text"].Value + "";
4. 方式 2:VS 外部编写逻辑(核心:提取 ToolBlock 内子工具 + 单独调用 / 二次处理)
if (mToolBlock != null)
{
// 1. 先执行整个ToolBlock
mToolBlock.Run();
// 2. 关键:从ToolBlock中提取指定子工具(按vpp内工具名强转)
CogPMAlignTool pma = mToolBlock.Tools["CogPMAlignTool1"] as CogPMAlignTool; // 模板匹配工具
CogCompositeColorMatchTool color = mToolBlock.Tools["CogCompositeColorMatchTool1"] as CogCompositeColorMatchTool; // 颜色匹配工具
// 3. 遍历子工具结果,自定义业务逻辑(VS中灵活编写)
string s = "";
for (int i = 0; i < pma.Results.Count; i++)
{
// 3.1 从模板匹配结果获取位姿,创建仿射矩形(适配目标旋转/位移)
CogRectangleAffine rect = new CogRectangleAffine();
rect.CenterX = pma.Results[i].GetPose().TranslationX; // 匹配目标X中心
rect.CenterY = pma.Results[i].GetPose().TranslationY; // 匹配目标Y中心
rect.Rotation = pma.Results[i].GetPose().Rotation; // 匹配目标旋转角度
rect.SideXLength = 100; rect.SideYLength = 10; // 矩形尺寸
// 3.2 给颜色匹配工具赋值检测区域(模板匹配定位+颜色匹配检测)
color.Region = rect;
// 3.3 单独运行颜色匹配工具,执行检测
color.Run();
// 3.4 提取颜色匹配结果,拼接自定义逻辑结果
s += color.Result.ResultOfBestMatch.Color.Name;
}
// 3.5 展示自定义逻辑处理结果
this.Text = s;
}
关键 API 速查(ToolBlock 子工具操作 + 核心联动)
| 功能 | 核心 API / 语法 |
|---|---|
| 提取 ToolBlock 内子工具 | mToolBlock.Tools["vpp内工具名"] as 工具类型 |
| 模板匹配结果位姿获取 | pma.Results[i].GetPose().TranslationX/Y/Rotation |
| 仿射矩形创建 / 赋值 | CogRectangleAffine(适配旋转目标) |
| 颜色匹配区域赋值 | color.Region = 几何图形(矩形/圆) |
| 颜色匹配结果提取 | color.Result.ResultOfBestMatch.Color.Name |
| ToolBlock 内工具单独运行 | 子工具对象.Run()(如color.Run()) |
| VPP 内置脚本输出获取 | mToolBlock.Outputs["vpp内定义输出名"].Value |
cs
namespace _04处理vpp脚本的方式
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
CogToolBlock mToolBlock = new CogToolBlock();
private void Form1_Load(object sender, EventArgs e)
{
string path = @"C:\Users\Administrator\Desktop\新建文件夹\颜色.vpp";
//string path = @"C:\Users\Administrator\Desktop\新建文件夹\tb2.vpp";
mToolBlock = CogSerializer.LoadObjectFromFile(path) as CogToolBlock;
cogToolBlockEditV21.Subject = mToolBlock;
}
private void button1_Click(object sender, EventArgs e)
{
//这俩句代码为了颜色加载tb2.vpp, 把逻辑写在vpp里面
//mToolBlock.Run();
//this.Text = mToolBlock.Outputs["text"].Value + "";
// 加载颜色.vpp 主要是演示把逻辑写在vs里面
if (mToolBlock != null)
{
mToolBlock.Run();
//获取tb块的工具
CogPMAlignTool pma = mToolBlock.Tools["CogPMAlignTool1"] as CogPMAlignTool;
CogCompositeColorMatchTool color = mToolBlock.Tools["CogCompositeColorMatchTool1"] as CogCompositeColorMatchTool;
string s = "";
for (int i = 0; i < pma.Results.Count; i++)
{
CogRectangleAffine rect = new CogRectangleAffine();
rect.CenterX = pma.Results[i].GetPose().TranslationX;
rect.CenterY = pma.Results[i].GetPose().TranslationY;
rect.Rotation = pma.Results[i].GetPose().Rotation;
rect.SideXLength = 100;
rect.SideYLength = 10;
color.Region = rect;
//运行工具
color.Run();
s += color.Result.ResultOfBestMatch.Color.Name;
}
this.Text = s;
}
}
}
}