当前位置: 首页 > web >正文

VisionPro —— 不规则胶路检测

简介

本文介绍了一种基于Cognex视觉工具的胶路检测方法,分为直线和弧形两部分检测。

直线部分采用卡尺工具检测胶路宽度,通过动态调整仿射矩形区域进行多位置测量;弧形部分使用blob工具沿圆周设置检测区域。

两种方法均通过脚本实现工具映射、参数绑定和结果分析功能,支持调试模式显示检测区域和结果标注。

通过try-catch异常处理机制确保检测过程稳定,直线部分可检测断胶情况,弧形部分通过径向补偿实现圆周检测。

此方法具有参数可调性,可根据实际需求灵活配置工具组合和检测参数,适用于不同形状胶路的自动化检测需求。

效果总览

工具

使用结果分析工具输出总结果

直线部分

工具及参数

只用了最基础的模板和定位,卡尺工具是主体。

自定义参数可根据项目需求灵活配置

脚本

映射所有工具并运行,初始化所需参数并与输入参数完成绑定。

创建仿射矩形对象并配置参数,注释的部分为调试用途

调试时取消代码注释,调整步距参数,检查矩形的尺寸、位置和角度是否符合预期效果。

使用try-catch语句能够有效避免因断胶导致卡尺搜索失败时程序报错中断,从而确保后续代码和工具的正常执行。

添加了文字显示功能,采用方法重载的方式实现。通过定义两个同名方法,可以根据需要灵活选择不同的显示效果。

脚本源码

#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.PMAlign;
using Cognex.VisionPro.CalibFix;
using Cognex.VisionPro.Caliper;
#endregionpublic class CogToolBlockAdvancedScript : CogToolBlockAdvancedScriptBase
{#region Private Member Variablesprivate Cognex.VisionPro.ToolBlock.CogToolBlock mToolBlock;private CogGraphicCollection gc = new CogGraphicCollection();#endregion/// <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// Run each tool using the RunTool function// 映射工具并运行,注意这里把 foreach 运行所有工具那行代码删了CogPMAlignTool pma = mToolBlock.Tools["CogPMAlignTool1"]as CogPMAlignTool;CogFixtureTool fix = mToolBlock.Tools["CogFixtureTool1"]as CogFixtureTool;CogCaliperTool cal = mToolBlock.Tools["CogCaliperTool1"]as CogCaliperTool;gc.Clear();pma.Run();fix.Run();cal.Run();// 给输出的结果初始化为falsemToolBlock.Outputs["FlowResult"].Value = false;bool FlowResult = true;// 初始化参数并与输入参数绑定double max = 0,min = 100,Pitch = (double) mToolBlock.Inputs["Pitch"].Value,StartX = (double) mToolBlock.Inputs["StartX"].Value,StartY = (double) mToolBlock.Inputs["StartY"].Value,SearchLength = (double) mToolBlock.Inputs["SearchLength"].Value,CaliperLengthX = (double) mToolBlock.Inputs["CaliperLengthX"].Value,CaliperLengthY = (double) mToolBlock.Inputs["CaliperLengthY"].Value,CaliperRotation = (double) mToolBlock.Inputs["CaliperRotation"].Value,SearchAngle = (double) mToolBlock.Inputs["SearchAngle"].Value,scale = (double) mToolBlock.Inputs["scale"].Value;int TestCount = (int) mToolBlock.Inputs["TestCount"].Value;bool breakLine = true;if (pma.RunStatus.Result == CogToolResultConstants.Accept){for (int i = 0; i < (SearchLength / Pitch) && i < TestCount; i++){ double CaliperDegrees = CaliperRotation * Math.PI / 180;double SearchDegrees = SearchAngle * Math.PI / 180;CogRectangleAffine rect = new CogRectangleAffine();rect.Rotation = CaliperDegrees;rect.CenterX = StartX - i * Pitch * Math.Sin(SearchDegrees);rect.CenterY = StartY + i * Pitch * Math.Cos(SearchDegrees);rect.SideXLength = Convert.ToInt32(mToolBlock.Inputs["CaliperLengthX"].Value);rect.SideYLength = Convert.ToInt32(mToolBlock.Inputs["CaliperLengthY"].Value);// 测试用显示矩形位置//rect.CenterX = pma.Results[0].GetPose().TranslationX + StartX - i * Pitch * Math.Sin(SearchDegrees);//rect.CenterY = pma.Results[0].GetPose().TranslationY + StartY + i * Pitch * Math.Cos(SearchDegrees);//gc.Add(rect);//MessageBox.Show("X坐标:" + rect.CenterX.ToString() + "Y坐标:" + rect.CenterY.ToString());// 把矩形给到卡尺的搜索范围并运行卡尺工具cal.Region = rect;cal.Run();max = max < (cal.Results[0].Width * scale) ? (cal.Results[0].Width * scale) : max;min = min > (cal.Results[0].Width * scale) ? (cal.Results[0].Width * scale) : min;//MessageBox.Show(max.ToString());try {	  if(cal.RunStatus.Result == CogToolResultConstants.Accept){if(((double) (cal.Results[0].Width * scale) > (double) mToolBlock.Inputs["WidthMax"].Value)|| ((double) (cal.Results[0].Width * scale) < (double) mToolBlock.Inputs["WidthMin"].Value)){AddLabel(pma.Results[0].GetPose().TranslationX + cal.Region.CenterX, pma.Results[0].GetPose().TranslationY + cal.Region.CenterY, "" + (cal.Results[0].Width * scale).ToString("f1"), CogColorConstants.Red);FlowResult = false;}else{AddLabel(pma.Results[0].GetPose().TranslationX + cal.Region.CenterX, pma.Results[0].GetPose().TranslationY + cal.Region.CenterY, "" + (cal.Results[0].Width * scale).ToString("f1"), CogColorConstants.Green);}}}catch (Exception){breakLine = false;AddLabel(pma.Results[0].GetPose().TranslationX + cal.Region.CenterX, pma.Results[0].GetPose().TranslationY + cal.Region.CenterY, "NG", CogColorConstants.Red);// MessageBox.Show("卡尺g了");// 继续执行或终止循环, 如果需要终止检测,可添加: return false;}}}AddLabel(520, 50, breakLine ? " " : "直线部分断胶", breakLine);AddLabel(520, 100, "直线部分最小值" + min.ToString("f1"), true);AddLabel(520, 150, "直线部分最大值" + max.ToString("f1"), true);mToolBlock.Outputs["FlowResult"].Value = FlowResult;return false;}// 添加文本方法private void AddLabel (double x, double y, string text, bool b){CogGraphicLabel label = new CogGraphicLabel();label.BackgroundColor = CogColorConstants.None;label.Color = b ? CogColorConstants.Green : CogColorConstants.Red;label.Font = new Font("楷体", 20);label.SetXYText(x, y, text);gc.Add(label);}private void AddLabel (double x, double y, string text, CogColorConstants color){CogGraphicLabel label = new CogGraphicLabel();label.BackgroundColor = CogColorConstants.None;label.Color = color;label.Font = new Font("楷体", 6);label.SetXYText(x, y, text);gc.Add(label);}#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 Createdpublic override void ModifyLastRunRecord(Cognex.VisionPro.ICogRecord lastRecord){foreach (ICogGraphic item in gc){mToolBlock.AddGraphicToRunRecord(item, lastRecord, "CogPMAlignTool1.InputImage", "");}}#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 REMOVEbase.Initialize(host);// Store a local copy of the script hostthis.mToolBlock = ((Cognex.VisionPro.ToolBlock.CogToolBlock)(host));}#endregion}

圆形部分

工具及参数

同直线部分一样,blob工具是核心

同上

调试的时候同样把相应的代码打开并调小步距。

脚本

同上

脚本源码

#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.PMAlign;
using Cognex.VisionPro.CalibFix;
using Cognex.VisionPro.Caliper;
using Cognex.VisionPro.Blob;
#endregionpublic class CogToolBlockAdvancedScript : CogToolBlockAdvancedScriptBase
{#region Private Member Variablesprivate Cognex.VisionPro.ToolBlock.CogToolBlock mToolBlock;private CogGraphicCollection gc = new CogGraphicCollection();#endregion/// <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// Run each tool using the RunTool function// 映射工具并运行,注意这里把 foreach 运行所有工具那行代码删了CogPMAlignTool pma1 = mToolBlock.Tools["CogPMAlignTool1"]as CogPMAlignTool;CogFixtureTool fix1 = mToolBlock.Tools["CogFixtureTool1"]as CogFixtureTool;CogFindCircleTool cir1 = mToolBlock.Tools["CogFindCircleTool1"]as CogFindCircleTool;CogBlobTool blob1 = mToolBlock.Tools["CogBlobTool1"]as CogBlobTool;gc.Clear();pma1.Run();fix1.Run();cir1.Run();blob1.Run();// 给输出的结果初始化为falsemToolBlock.Outputs["FlowResult"].Value = false;bool FlowResult = true;// 初始化参数并与输入参数绑定double Pitch = (double) mToolBlock.Inputs["Pitch"].Value,             // 步长StartArc = (double) mToolBlock.Inputs["StartArc"].Value,       // 开始角度SearchAngle = (double) mToolBlock.Inputs["SearchAngle"].Value, // 搜索范围BlobLengthX = (double) mToolBlock.Inputs["BlobLengthX"].Value, // 矩形长BlobLengthY = (double) mToolBlock.Inputs["BlobLengthY"].Value, // 矩形宽scale = (double) mToolBlock.Inputs["scale"].Value;             // 缩放系数int TestCount = (int) mToolBlock.Inputs["TestCount"].Value,      // 循环次数限制RadiusCompensate = (int) mToolBlock.Inputs["RadiusCompensate"].Value; // 半径补偿// 主循环:生成仿射矩形并检测for (int i = 0; i < SearchAngle/Pitch && i < TestCount; i++){// 计算当前角度(度转弧度)double currentAngleDegrees = StartArc + i * Pitch;double currentAngleRadians = currentAngleDegrees * Math.PI / 180;// 创建仿射矩形(短边垂直于切线使矩形指向圆心)CogRectangleAffine rect = new CogRectangleAffine();rect.SideXLength = BlobLengthX;rect.SideYLength = BlobLengthY;rect.Rotation = currentAngleRadians;  // 短边与半径方向一致// 计算矩形中心位置rect.CenterX = cir1.Results.GetCircle().CenterX + (cir1.Results.GetCircle().Radius + RadiusCompensate) * Math.Cos(currentAngleRadians);rect.CenterY = cir1.Results.GetCircle().CenterY + (cir1.Results.GetCircle().Radius + RadiusCompensate) * Math.Sin(currentAngleRadians);blob1.Region = rect;blob1.Run();// 调试显示矩形位置//rect.CenterX = pma1.Results[0].GetPose().TranslationX + cir1.Results.GetCircle().CenterX +    //  (cir1.Results.GetCircle().Radius + RadiusCompensate) * Math.Cos(currentAngleRadians);//rect.CenterY = pma1.Results[0].GetPose().TranslationY + cir1.Results.GetCircle().CenterY +     //  (cir1.Results.GetCircle().Radius + RadiusCompensate) * Math.Sin(currentAngleRadians);//gc.Add(rect);try{if(blob1.Results.GetBlobs().Count > 0){AddLabel(pma1.Results[0].GetPose().TranslationX + rect.CenterX, pma1.Results[0].GetPose().TranslationY + rect.CenterY, "OK", true);}else{AddLabel(pma1.Results[0].GetPose().TranslationX + rect.CenterX, pma1.Results[0].GetPose().TranslationY + rect.CenterY, "NG", false);FlowResult = false;}}catch{AddLabel(pma1.Results[0].GetPose().TranslationX + cir1.Results.GetCircle().CenterX + rect.CenterX, pma1.Results[0].GetPose().TranslationY + cir1.Results.GetCircle().CenterY + rect.CenterY, "None", false);continue;}}//MessageBox.Show(angleRadians.ToString());AddLabel(520, 200, FlowResult ? " " : "圆形部分断胶", FlowResult ? CogColorConstants.Green : CogColorConstants.Red);mToolBlock.Outputs["FlowResult"].Value = FlowResult;return false;}// 添加文本方法private void AddLabel (double x, double y, string text, bool b){CogGraphicLabel label = new CogGraphicLabel();label.BackgroundColor = CogColorConstants.None;label.Color = b ? CogColorConstants.Green : CogColorConstants.Red;label.Font = new Font("楷体", 10);label.SetXYText(x, y, text);gc.Add(label);}private void AddLabel (double x, double y, string text, CogColorConstants color){CogGraphicLabel label = new CogGraphicLabel();label.BackgroundColor = CogColorConstants.None;label.Color = color;label.Font = new Font("楷体", 20);label.SetXYText(x, y, text);gc.Add(label);}#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){foreach (ICogGraphic item in gc){mToolBlock.AddGraphicToRunRecord(item, lastRecord, "CogPMAlignTool1.InputImage", "");}}#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 REMOVEbase.Initialize(host);// Store a local copy of the script hostthis.mToolBlock = ((Cognex.VisionPro.ToolBlock.CogToolBlock)(host));}#endregion}

http://www.xdnf.cn/news/10480.html

相关文章:

  • Codeforces Round 1028 (Div. 2) C. Gellyfish and Flaming Peony
  • java synchronized关键字用法
  • STM32Cubemx-H7-17-麦克纳姆轮驱动
  • 关于神经网络中的梯度和神经网络的反向传播以及梯度与损失的关系
  • 用Python打开不同联类型的文件
  • 【xmb】】内部文档148344599
  • 大数据学习(126)-窗口函数范围
  • 通过WiFi无线连接小米手机摄像头到电脑的方法
  • AI炼丹日志-27 - Anubis 通过 PoW工作量证明的反爬虫组件 上手指南 原理解析
  • Java数值处理常见错误解析
  • java多线程与JUC
  • nt!MiDispatchFault函数分析之nt!MiCompleteProtoPteFault函数的作用
  • sqli-labs靶场32-37关(宽字节注入)
  • 历年苏州大学计算机保研上机真题
  • 语音转文字工具
  • Git 入门学习教程
  • Redis 缓存穿透、缓存击穿、缓存雪崩详解与解决方案
  • Ansible 进阶 - Roles 与 Inventory 的高效组织
  • uni-app学习笔记十八--uni-app static目录简介
  • YOLOv5-入门篇笔记
  • 算法打开13天
  • 焦虑而烦躁的上午
  • HTTPS
  • VeriFree:无需Verifier的通用RL框架
  • 【GPT入门】第40课 vllm与ollama特性对比,与模型部署
  • wsl安装linux
  • 测试总结(二)
  • Python 验证码识别(使用pytesseract库)
  • JVM——JVM运行时数据区的内部机制是怎样的?
  • unix/linux source 命令,在当前的 Shell 会话中读取并执行指定文件中的命令