1:题目详情:
效果:
2:问题分析
第一步:当前题目引脚的类型主要分为上下两个部分,长度不同,需要分开检测,因此提供两种解决方法
1.使用两个CogAffineTransformTool工具将图片分成两个图片分别进行检测
效果如下
2.由于当前题目的所有图片上下引脚的位置大致一样,所以可以在判断时通过if判断将y坐标的位置分为上下两个位置,下面我将对第二中方法进行详细的解答
第二步:图片中的错误问题主要有两种:
角度倾斜和长度不合格,因此需要对上下位置的各个引脚进行角度和长度判断,
其中有些图片两个引脚中间出现引脚缺失所以需要通过卡尺工具对间距进行判断
3:解决方案
工具使用
首先我们观察图像,引脚的颜色为白色,而图片剩余位置为黑色。
那么我们可以使用CogBlobTool也就是斑点工具将引脚提出来,
在此之前我们可以对图像进行预处理
处理前:
处理后:
使用open操作:打开图像会 删除少量明亮像素,然后增强其余的明亮功能,这样会使我们的斑点工具更加容易的找到斑点。
然后使用CogBlobTool工具进行斑点提取
操作参数如下:
得到结果;
在斑点工具中有一个对此题重要的概念:
角度:
结果为弧度,这个可以让我们判断倾斜度
添加方式:点击右上角,添加角度,这样结果中就会出现角度列
由于我们需要检测两个斑点之间的间距,需要用到卡尺工具,所以我们需要对斑点工具添加图像输出终端
选择右上角所有(未过滤),在results中找到如图蓝色标题,然后添加输出
然后链接到卡尺工具
卡尺工具主要作用是为了检测间隔所以设置如下
到此我们的工具使用就到此结束;
脚本使用
目的,在写脚本之前我们需要了解我们写脚本的目的,
1:获取斑点角度,是否垂直(给其一个5的偏差),如何角度出入较大,获取斑点的轮廓,然后获取新的多边形接收此斑点轮廓,
2:获取斑点长度,分上下检测,给定范围,不符合就获取斑点的轮廓,然后获取新的多边形接收此斑点轮廓
3:获取两个引脚中间的距离,给定范围,不符合就标记出来
4:在符合的条件下载图像中添加“OK”不符合添加“NG”
解决方案
下面我们就来实现,我们发现需要添加在图像中的图形也好,文本也好,不止一个,所以我们可以用一个图像集合来接收,使用集合添加命名空间,将角度不合格多边形,长度不合格,距离不合格和文本图像添加到图像集合中。
下面我们来一步一步分析目的的解决方案:
首先我们要循环斑点工具中的各个图形信息,然后引入bool值进行判断,为了方便我们对接下来的文本输入进行判断
//为了判断是否符合然后添加文本,所以引入bool b
bool b = true;
1:角度分析:斑点工具给的角度是弧度,所以我们需要,对弧度进行处理,弧度转角度公式:[角度 = 弧度 × (180 ÷ π)],并且要取其绝对值所以我们需要写
//获取角度
double angle = Math.Abs(blob.Results.GetBlobs()[i].Angle) * 180 / Math.PI;
然后在循环中对角度进行判断,由于我们要预留5的偏差:然后将bool值赋为false
if (Math.Abs(angle - 90) > 5)
{
CogPolygon p = new CogPolygon();
//获取边界
p = blob.Results.GetBlobs()[i].GetBoundary();
//多边形颜色
p.Color = CogColorConstants.Red;
//添加到图像集合中
cc.Add(p);
//判断不符合
b = false;
}
2:判断高度,分为上下两个区域进行检测,我们通过之前说的上下分段进行判断,y坐标为220左右,上面高度范围为90-110,下半段为50-65 ,然后将bool值赋为false
//获取高度
double h = (blob.Results.GetBlobs()[i].GetMeasure(CogBlobMeasureConstants.BoundingBoxExtremaAngleHeight));
//判断y小于220 证明在上面
if (blob.Results.GetBlobs()[i].CenterOfMassY < 220)
{if (h > 110 || h < 90)
{//高度不合格
CogPolygon p = new CogPolygon();
//获取边界
p = blob.Results.GetBlobs()[i].GetBoundary();
//多边形颜色
p.Color = CogColorConstants.Red;
//添加到图像集合中
cc.Add(p);
//判断不符合
b = false;
}
}
//判断y大于220 证明在上面
else if(blob.Results.GetBlobs()[i].CenterOfMassY > 220)
{
if (h > 65 || h < 50)
{//高度不合格
CogPolygon p = new CogPolygon();
//获取边界
p = blob.Results.GetBlobs()[i].GetBoundary();
//多边形颜色
p.Color = CogColorConstants.Red;
//添加到图像集合中
cc.Add(p);
//判断不符合
b = false;
}
}
3:间距的判断,这时我们就需要用到卡尺工具的边缘了,将这些边缘的x坐标进行存储到集合中,然后进行判断以及计算,通过仿射矩形进行标记
//创建List,将卡尺工具的边缘线x坐标添加进去,然后进行从左到右的排列
List<double> list = new List<double>();
for (int i = 0; i < cal.Results.Count; i++)
{
list.Add(cal.Results[i].Edge0.PositionX);// 把边缘线的x坐标添加到数组
}
list.Sort();// 升序排序
for (int i = 0; i < list.Count-1; i++)
{
double off = list[i + 1] - list[i];//计算两条线间距
if (off > 80)
{
//创建仿射矩形,用来框出不合格区域
CogRectangleAffine rec = new CogRectangleAffine();
//图像中心x坐标
rec.CenterX = (list[i + 1] + list[i]) / 2;
//图像中心y坐标
rec.CenterY = cal.Results[i].Edge0.PositionY + 10;
//图像中心x间距
rec.SideXLength = off;
//图像中心y间距
rec.SideYLength = 100;
//图像颜色
rec.Color = CogColorConstants.Red;
//添加图像到集合中
cc.Add(rec);
//判断不合格
b = false;
}
4:添加文本,这时就用到我们之前设置的bool值了,true为“OK”false为“NG”
//创建文本
CogGraphicLabel label = new CogGraphicLabel();
//通过bool b之前的赋值进行判断,正确为“OK“错误为”NG“
if (b)
{
// 无瑕疵
label.SetXYText(100, 80, "OK");
}
else
{
// 瑕疵
label.SetXYText(100, 80, "NG");
label.Color = CogColorConstants.Red;
}
cc.Add(label);
最后就是在图片中输出了,由于我们要输出的是集合所以:
//将图像集合循环输出
for (int i = 0; i < cc.Count; i++)
{
mToolBlock.AddGraphicToRunRecord(cc[i], lastRecord, "CogIPOneImageTool1.InputImage", "ss");
}
整体代码如下
#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.Blob;
using Cognex.VisionPro.Caliper;
using System.Collections.Generic;//使用集合命名空间
#endregion
public class CogToolBlockAdvancedScript : CogToolBlockAdvancedScriptBase
{
#region Private Member Variables
private Cognex.VisionPro.ToolBlock.CogToolBlock mToolBlock;
#endregion
CogGraphicCollection cc = new CogGraphicCollection();//添加图形集合
/// <summary>
/// Called when the parent tool is run.
/// Add code here to customize or replace the normal run behavior.
/// </summary>
/// <param name="message">Sets the Message in the tool's RunStatus.</param>
/// <param name="result">Sets the Result in the tool's RunStatus</param>
/// <returns>True if the tool should run normally,
/// False if GroupRun customizes run behavior</returns>
public override bool GroupRun(ref string message, ref CogToolResultConstants result)
{
// To let the execution stop in this script when a debugger is attached, uncomment the following lines.
// #if DEBUG
// if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();
// #endif
//获取斑点和卡尺工具
CogBlobTool blob = mToolBlock.Tools["CogBlobTool1"] as CogBlobTool;//
CogCaliperTool cal = mToolBlock.Tools["CogCaliperTool1"] as CogCaliperTool;
cc.Clear();
// Run each tool using the RunTool function
foreach(ICogTool tool in mToolBlock.Tools)
mToolBlock.RunTool(tool, ref message, ref result);
//为了判断是否符合然后添加文本,所以引入bool b
bool b = true;
//循环斑点工具的图像信息
for (int i = 0; i < blob.Results.GetBlobs().Count; i++)
{
//获得角度绝对值
double angle = Math.Abs(blob.Results.GetBlobs()[i].Angle) * 180 / Math.PI;
//如果角度不合格
if (Math.Abs(angle - 90) > 5)
{
CogPolygon p = new CogPolygon();
//获取边界
p = blob.Results.GetBlobs()[i].GetBoundary();
//多边形颜色
p.Color = CogColorConstants.Red;
//添加到图像集合中
cc.Add(p);
//判断不符合
b = false;
}
//获取高度
double h = (blob.Results.GetBlobs()[i].GetMeasure(CogBlobMeasureConstants.BoundingBoxExtremaAngleHeight));
//判断y小于220 证明在上面
if (blob.Results.GetBlobs()[i].CenterOfMassY < 220)
{if (h > 110 || h < 90)
{//高度不合格
CogPolygon p = new CogPolygon();
//获取边界
p = blob.Results.GetBlobs()[i].GetBoundary();
//多边形颜色
p.Color = CogColorConstants.Red;
//添加到图像集合中
cc.Add(p);
//判断不符合
b = false;
}
}
//判断y大于220 证明在上面
else if(blob.Results.GetBlobs()[i].CenterOfMassY > 220)
{
if (h > 65 || h < 50)
{//高度不合格
CogPolygon p = new CogPolygon();
//获取边界
p = blob.Results.GetBlobs()[i].GetBoundary();
//多边形颜色
p.Color = CogColorConstants.Red;
//添加到图像集合中
cc.Add(p);
//判断不符合
b = false;
}
}
}
//创建List,将卡尺工具的边缘线x坐标添加进去,然后进行从左到右的排列
List<double> list = new List<double>();
for (int i = 0; i < cal.Results.Count; i++)
{
list.Add(cal.Results[i].Edge0.PositionX);// 把边缘线的x坐标添加到数组
}
list.Sort();// 升序排序
for (int i = 0; i < list.Count-1; i++)
{
double off = list[i + 1] - list[i];//计算两条线间距
if (off > 80)
{
//创建仿射矩形,用来框出不合格区域
CogRectangleAffine rec = new CogRectangleAffine();
//图像中心x坐标
rec.CenterX = (list[i + 1] + list[i]) / 2;
//图像中心y坐标
rec.CenterY = cal.Results[i].Edge0.PositionY + 10;
//图像中心x间距
rec.SideXLength = off;
//图像中心y间距
rec.SideYLength = 100;
//图像颜色
rec.Color = CogColorConstants.Red;
//添加图像到集合中
cc.Add(rec);
//判断不合格
b = false;
}
}
//创建文本
CogGraphicLabel label = new CogGraphicLabel();
//通过bool b之前的赋值进行判断,正确为“OK“错误为”NG“
if (b)
{
// 无瑕疵
label.SetXYText(100, 80, "OK");
}
else
{
// 瑕疵
label.SetXYText(100, 80, "NG");
label.Color = CogColorConstants.Red;
}
cc.Add(label);
return false;
}
#region When the Current Run Record is Created
/// <summary>
/// Called when the current record may have changed and is being reconstructed
/// </summary>
/// <param name="currentRecord">
/// The new currentRecord is available to be initialized or customized.</param>
public override void ModifyCurrentRunRecord(Cognex.VisionPro.ICogRecord currentRecord)
{
}
#endregion
#region When the Last Run Record is Created
/// <summary>
/// Called when the last run record may have changed and is being reconstructed
/// </summary>
/// <param name="lastRecord">
/// The new last run record is available to be initialized or customized.</param>
public override void ModifyLastRunRecord(Cognex.VisionPro.ICogRecord lastRecord)
{
//将图像集合循环输出
for (int i = 0; i < cc.Count; i++)
{
mToolBlock.AddGraphicToRunRecord(cc[i], lastRecord, "CogIPOneImageTool1.InputImage", "ss");
}
}
#endregion
#region When the Script is Initialized
/// <summary>
/// Perform any initialization required by your script here
/// </summary>
/// <param name="host">The host tool</param>
public override void Initialize(Cognex.VisionPro.ToolGroup.CogToolGroup host)
{
// DO NOT REMOVE - Call the base class implementation first - DO NOT REMOVE
base.Initialize(host);
// Store a local copy of the script host
this.mToolBlock = ((Cognex.VisionPro.ToolBlock.CogToolBlock)(host));
}
#endregion
}
感谢各位兄弟姐妹们的观看,如有需求评论区见!!!