动态卡尺胶路检测

news2024/9/26 5:23:51

动态卡尺胶路检测

  • 1. 示例效果
  • 2. 代码

1. 示例效果

  • 使用了三个卡尺工具、一个线段工具。
  • 这种方法可以检测胶路最常见的缺陷:断胶和胶宽等
    在这里插入图片描述

2. 代码

#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.Caliper;
using Cognex.VisionPro.Dimensioning;
#endregion

public class CogToolBlockAdvancedScript : CogToolBlockAdvancedScriptBase
{
  #region Private Member Variables
  private Cognex.VisionPro.ToolBlock.CogToolBlock mToolBlock;
  
  //1.变量定义
  CogGraphicCollection my_gc = new CogGraphicCollection();
  CogGraphicLabel res = new CogGraphicLabel();
  #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(ICogTool tool in mToolBlock.Tools)
      mToolBlock.RunTool(tool, ref message, ref result);

    //===2.1 工具获取、获取参数、初始化等
    //初始化方向起点位置
    CogCaliperTool start = mToolBlock.Tools["StartPoint"] as CogCaliperTool; 
    start.Run();
    //初始化方向终点位置
    CogCaliperTool end = mToolBlock.Tools["EndPoint"] as CogCaliperTool; 
    end.Run();
    //动态卡尺,不断地利用该卡尺得到下一个点的位置
    CogCaliperTool autoCaliper = mToolBlock.Tools["AutoPoint"] as CogCaliperTool; 
    //动态卡尺的矩形框
    CogRectangleAffine rec = autoCaliper.Region as CogRectangleAffine;
    //线段工具用来计算角度
    CogCreateSegmentTool segment = mToolBlock.Tools["CogCreateSegmentTool1"] as CogCreateSegmentTool;
    //获取参数
    int d = Convert.ToInt32(mToolBlock.Inputs["Distance"].Value);
    int totalNum = Convert.ToInt32(mToolBlock.Inputs["totalNum"].Value);
    int range = Convert.ToInt32(mToolBlock.Inputs["range"].Value);
    //清空图形集合
    my_gc.Clear();
    //实例化一个多变形对象
    CogPolygon p = new CogPolygon();
    res.SetXYText(100, 100, "OK");
    res.Font = new Font("宋体",20);
    
    
    //===2.2 循环生成指定数量的点
    for (int i = 0;  i < totalNum;  i++)
    {
      if(i == 0)
      {
        //第一个点使用搜索方向的起点
        p.AddVertex(start.Results[0].PositionX, start.Results[0].PositionX, i);
        continue;
      }
      else if(i == 1)
      {
        //第二个点使用搜索方向的终点
        p.AddVertex(start.Results[0].PositionX, end.Results[0].PositionX, i);
        continue;
      }
      else
      {
        //第三个以上的路径点
        //设置线段起点和终点,运行线段工具,最终得到上一个线段的角度
        segment.Segment.StartX = p.GetVertexX(i - 2);
        segment.Segment.StartY = p.GetVertexY(i - 2);
        segment.Segment.EndX = p.GetVertexX(i - 1);
        segment.Segment.EndY = p.GetVertexY(i - 1);
        segment.Run();
        //通过上一个线段的角度、路径之间的距离、上一个点的坐标,算出下一个点的坐标,并将算出的坐标作为动态卡尺的中心点,卡尺角度与线段垂直
        rec.CenterX = p.GetVertexX(i - 1) + Math.Round(Math.Cos(segment.Segment.Rotation), 5) * d;
        rec.CenterY = p.GetVertexY(i - 1) + Math.Round(Math.Sin(segment.Segment.Rotation), 5) * d;
        //将动态卡尺的角度设为与线段垂直,然后运行
        rec.Rotation = CogMisc.DegToRad(90 + Convert.ToInt32(CogMisc.RadToDeg(segment.Segment.Rotation)));
        autoCaliper.Run();
        
        //自动卡尺运行结果判断
        if (autoCaliper.Results.Count != 0)
        {
          //如果动态卡尺找到了,就直接存进多边形
          p.AddVertex(autoCaliper.Results[0].PositionX, autoCaliper.Results[0].PositionY, i);
        }
        else
        {
          //如果没有找到,则以线段为基准,向左旋转一定角度遍历运行
          
          //----旋转搜索----
          //初始角度为上一个线段的角度
          int angle = Convert.ToInt32(CogMisc.RadToDeg(segment.Segment.Rotation));
          int j;
          for (j = 0; j < range; j+=5)
          {
            if(j <= range / 2)
            {
              //右转角度计算
              angle = angle + j;
            }
            else
            {
             //左转角度计算
              angle = angle - (j - range / 2);
            }
            rec.CenterX = p.GetVertexX(i - 1) + Math.Round(Math.Cos((angle * Math.PI) / 180), 5) * d;//5是返回值中的小数位数
            rec.CenterY = p.GetVertexX(i - 1) + Math.Round(Math.Sin((angle * Math.PI) / 180), 5) * d;
            autoCaliper.Run();
            if(autoCaliper.Results.Count != 0)
            {
              p.AddVertex(autoCaliper.Results[0].PositionX, autoCaliper.Results[0].PositionY, i);
              break;
            }
            
            //如果还没有找到,退出
            if(j >= range)
            {
              res.SetXYText(100, 100, "NG");
              break;
            }    
          }
        }
      }
      
      //生成每一段路径上的指示箭头
      CogLineSegment LineArrow1 = new CogLineSegment();
      LineArrow1.Color = CogColorConstants.Yellow;
      LineArrow1.LineWidthInScreenPixels = 2;
      LineArrow1.SetStartEnd(p.GetVertexX(i - 1), p.GetVertexY(i - 1), autoCaliper.Results[0].PositionX, autoCaliper.Results[0].PositionY);
      LineArrow1.EndPointAdornment = CogLineSegmentAdornmentConstants.SolidArrow;
      my_gc.Add(LineArrow1);
    }
    
    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)
  {
    //3.图形输出
    foreach (ICogGraphic x in my_gc)
    {
      mToolBlock.AddGraphicToRunRecord(x, lastRecord, "CogImageConvertTool1.InputImage", "");
    }
    mToolBlock.AddGraphicToRunRecord(res, lastRecord, "CogImageConvertTool1.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 REMOVE
    base.Initialize(host);


    // Store a local copy of the script host
    this.mToolBlock = ((Cognex.VisionPro.ToolBlock.CogToolBlock)(host));
  }
  #endregion

}


视频链接:Visonpro动态卡尺自动路径(胶线路径)搜索

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1364283.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【开发日记】IDEA“找不到或无法加载主类”问题

记录一个研究了两个小时的“玄学”问题找不到或无法加载主类。 ​1、问题 使用IDEA启动SpringBoot项目显示找不到或无法加载主类。 2、解决经历 尝试了很多种解决方法都没有解决&#xff0c;下面是我网上查询后尝试的一些方法。这些方法我都没有解决问题&#xff0c;是因为…

双十一的祈祷【算法赛】

问题描述 双十一&#xff0c;不仅是购物狂欢节&#xff0c;更有 "光棍节" 之称。这源于 11:1111:11 由四个 11 构成&#xff0c;象征着单身。 作为大学生的小蓝也想经历甜甜的校园恋爱&#xff0c;于是他找到了爱神丘比特&#xff0c;向他祈祷能为自己带来一段邂逅…

微软开源时空预测Fost的使用和解读

一、引言 时空预测是指对未知系统状态在时间和空间上的预测&#xff0c;它是地球系统科学、交通运输、智慧城市等领域的重要技术和工具。时空预测的目的是利用历史数据和当前信息&#xff0c;通过建立时空依赖关系&#xff0c;来推断未来的变化趋势和可能的情景。时空预测的应…

《PySpark大数据分析实战》-24.数据可视化图表介绍

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

强化学习4——动态规划初探

动态规划具体指的是在某些复杂问题中&#xff0c;将问题转化为若干个子问题&#xff0c;并在求解每个子问题的过程中保存已经求解的结果&#xff0c;以便后续使用。实际上动态规划更像是一种通用的思路&#xff0c;而不是具体某个算法。 在强化学习中&#xff0c;被用于求解值函…

CAN总线基础详解以及stm32的CAN控制器

目录 CAN简介 CAN总线拓扑图 CAN总线特定 CAN应用场景 CAN的物理层 CAN的协议层 CAN数据帧介绍 CAN位时序介绍 数据同步过程 硬件同步 再同步 CAN总线仲裁 stm32的CAN控制器 CAN控制器介绍 CAN控制器模式 CAN控制器框图 接收过滤器 CAN控制器波特率计算 CAN相…

基于SSM的图书商城(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的图书商城&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring SpringMv…

libexif库介绍

libexif是一个用于解析、编辑和保存EXIF数据的库。它支持EXIF 2.1标准(以及2.2中的大多数)中描述的所有EXIF标签。它是用纯C语言编写的&#xff0c;不需要任何额外的库。源码地址&#xff1a;https://github.com/libexif/libexif &#xff0c;最新发布版本为0.6.24&#xff0c;…

topsis算法

TOPSIS &#xff08;Technique for Order Preference by Similarity to an Ideal Solution &#xff09;模型中文叫做“逼近理想解排序方法”&#xff0c;是根据评价对象与理想化目标的接近程度进行排序的方法&#xff0c;是一种距离综合评价方法。基本思路是通过假定正、负理想…

C#,数值计算,基础函数——任意位数π的数值算法源程序与数据可视化

对于数学常数 PI 后面位数的计算与追求&#xff0c;是数学家与计算机科学家们乐此不疲的游戏。 一、圆周率PI简史 圆周率&#xff08;Pi&#xff09;是圆的周长与直径的比值&#xff0c;一般用希腊字母π表示&#xff0c;是一个在数学及物理学中普遍存在的数学常数。π也等于圆…

关于图像分割任务中按照比例将数据集随机划分成训练集和测试集

1. 前言 之前写了分类和检测任务划分数据集的脚本&#xff0c;三大任务实现了俩&#xff0c;基于强迫症&#xff0c;也实现一下图像分割的划分脚本 分类划分数据&#xff1a;关于图像分类任务中划分数据集&#xff0c;并且生成分类类别的josn字典文件 检测划分数据&#xff…

如何计算ThreadLocal对象的hash值?【ThreadLocal技术】(含AtomicInteger的介绍)

如何计算ThreadLocal对象的hash值&#xff1f; 一、前置知识二、问题三、剖析源码&#xff1a;如何计算ThreadLocal对象的hash值&#xff1f;1、源码1.1 咱先得知道nextHashCode的起始值1.1.1 那就要先了解AtomicInteger创建AtomicInteger原子的增减操作原子的加法操作原子的获…

对Tor的去匿名化攻击的调查

文章信息 论文题目&#xff1a;De-Anonymisation Attacks on Tor: A Survey 期刊&#xff08;会议&#xff09;&#xff1a; IEEE Communications Surveys & Tutorials 时间&#xff1a;2021 级别&#xff1a;中科院1区&#xff08;IF&#xff1a;35.6&#xff09; 文章链…

Python 面向对象之反射

Python 面向对象之反射 【一】概念 反射是指通过对象的属性名或者方法名来获取对象的属性或调用方法的能力反射还指的是在程序额运行过程中可以动态获取对象的信息(属性和方法) 【二】四个内置函数 又叫做反射函数 万物皆对象&#xff08;整数、字符串、函数、模块、类等等…

黑马程序员Java项目实战《瑞吉外卖》,轻松掌握springboot + mybatis plus开发核心技术的真java实战项目——第三部分

黑马程序员Java项目实战《瑞吉外卖》&#xff0c;轻松掌握springboot mybatis plus开发核心技术的真java实战项目——第三部分 1. 菜品管理的业务功能1.1 文件的上传和下载&#x1f647;‍♂️1.2 新增菜品1.3 接收页面提交的数据&#x1f647;‍♂️&#xff08;涉及两张表&a…

大数据技术架构

1 技术架构矩阵 大数据技术栈虽然比较多,但可以抽象为输入(数据接入)--处理(数据处理、数据分析)--输出(数据应用)。工作角色分工,数据处理以数据仓库开发人员为主,数据分析以数据分析师为主,其他所有组件、系统、技术相关归为数据平台。 2 数据源 大数据的数据来源…

媒体捕捉-iOS自定义二维码扫描功能

引言 随着iOS 7引入AV Foundation框架&#xff0c;二维码扫描功能已经成为iOS应用程序中不可或缺的一部分。现今&#xff0c;几乎每个应用都充分利用这一功能&#xff0c;为用户提供了诸如扫码登录、扫码填充等丰富多彩的便捷体验。这项技术不仅丰富了应用功能&#xff0c;也为…

我与nano实验室交流群

感兴趣的同学、朋友可以加入群聊共同学习聊天哦。 主要是工训赛、电赛、光电、集成电路等等&#xff0c;会分享一些开源代码&#xff0c;博主自己做的项目&#xff0c;自己画的PCB等等&#xff0c;包含但不限于STM32、K210、V831、机器视觉&#xff0c;机械臂&#xff0c;ROS&a…

Packet Tracer - Configure AAA Authentication on Cisco Routers

Packet Tracer - 在思科路由器上配置 AAA 认证 地址表 目标 在R1上配置本地用户账户&#xff0c;并使用本地AAA进行控制台和vty线路的身份验证。从R1控制台和PC-A客户端验证本地AAA身份验证功能。配置基于服务器的AAA身份验证&#xff0c;采用TACACS协议。从PC-B客户端验证基…

我的隐私计算学习——联邦学习(2)

笔记内容来自多本书籍、学术资料、白皮书及ChatGPT等工具&#xff0c;经由自己阅读后整理而成 &#xff08;三&#xff09;联邦学习的算子 ------------------------ 算子是什么&#xff1f;--------------------------- ​ 从广义上讲&#xff0c;对任何函数进行某一项操作都可…