VisionPro项目组成简介

一、脚本简介
1.1visionpro项目组成简介
在介绍脚本之前先简单介绍一下visionpro开发环境(quickbuild)的项目结构,job是quickbuild工程的基本组成单位,一个qucikbuild工程至少含有一个job,工程中所有的job是并行结构,各个job之间不会相互影响。每个job中默认包含一个toolgroup,用户可以在默认的toolgroup中添加项目所需的工具和工具块。工具块(toolblock)与工具组(toolgroup)都是工具的**“容器”**,通过使用工具块与工具组可以将完成某一功能的工具进行封装,实现项目模块化,同时亦可将某一特定功能的工具块或工具组导出实现重复使用,类似于编程语言中“函数”功能。工具块中亦可以包含工具块与工具组,两者之间的包含关系没有明确层次关系。
1.2visionpro脚本简介
visionpro工具封装了视觉算法与用户交互界面,toolgroup与toolblock提供了组合工具的容器,但是并非所有的功能都能通过既定交互界面实现。为了让用户实现客制化功能更加“随心所欲”,实现visionpro本身无法实现的逻辑功能,visionpro预留了脚本功能。脚本的类型、作用与支持语言如下图所示:
二、脚本类与方法
visionpro通过”多态”技术实现脚本功能,visionpro 的每一job、toolgroup、toolblock对象都含有一个接口对象,用户通过重写接口方法实现自定义拓展功能。以toolgroup为例, icogtoolgroupscript接口中定义了子类中必须实现的函数,当toolgruoup执行到某一节点(工具准备运行、工具运行完成等)时会调用相应的接口函数实现用户指定的功能。
如果你对接口、多态理解不够深入,你只需要明白脚本就是**“填空题”**,visionpro在适当的位置给你留下空白,在这个空白区域你可以在满足条件的情况下“自由发挥”,实现你想要实现的功能。
2.1 toolgroup脚本类
以toolgroup脚本为例展开,toolgroup 脚本是继承于cogtoolgroupbasescript,实现了icogtoolgroupscript接口,该接口有四个方法,详细介绍如下:
public class cogtoolgroupbasescript : icogtoolgroupscript{ // public virtual bool grouprun(ref string message,ref cognex.visionpro.cogtoolresultconstants result) { return true; } public virtual void modifycurrentrunrecord(icogrecord currentrecord) {} public virtual void modifylastrunrecord(icogrecord lastrecord) {} public virtual void initialize(cognex.visionpro.toolgroup.cogtoolgroup host) { toolgroup = host; } protected cognex.visionpro.toolgroup.cogtoolgroup toolgroup=null;}
initialize()顾名思义,该方法用于对toolgroup工具进行初始化,当退出脚本编辑工具时脚本会进行编译并进行初始化,此时该方法会被调用。此外,在对该group通过*.vpp文件进行加载时也会被立即调用。所以,所有的“一次性”的初始化工作都应该写在该方法中。
grouprun()方法运行该group中的工具,如果该方法返回值为true,所有的属于当前group的视觉工具都将运行,如果返回值为false,用户可以自定义工具的执行顺序,返回值为false为常见情况。
modifycurrentrunrecord()方法用于修改currentrecord,在toolgroup的currentrecord被创建后调用。
modifylastrunrecord()方法用于修改lastrunrecord,在toolgroup的lastrunrecord被创建后调用,例如:在最终生成图像中添加标签、该表颜色、用不同几何图像标记目标区域。
成员变量toolgroup为cogtoolgroup类型,该类的runtool方法用于运行指定视觉工具;tools 属性为当前group的工具集合,一般用于获取当前工具组中某一工具的引用;definescriptterminal、getscriptterminaldata、setscriptterminaldata 方法用于定义、获取、设置输入输出终端。
//对于当前group存在的视觉工具的程序集与命名空间会自动添加,如果用户想要使用当前group不存在的工具或者添加自定义程序集可以手动添加//详细的操作步骤会在后续实例中进行介绍using system;using cognex.visionpro;using cognex.visionpro3d;using cognex.visionpro.toolgroup; public class userscript : cogtoolgroupbasescript{ //默认情况下遍历group中所有的工具并运行,用户可以根据实际情况自定义运行逻辑与顺序 public override bool grouprun(ref string message, ref cogtoolresultconstants result) for (int32 toolidx = 0; toolidx 作业属性->编辑脚本->c#脚本,进入job脚本编辑环境
using system;using cognex.visionpro;using cognex.visionpro.quickbuild;using cognex.visionpro.imageprocessing; public class userscript : cogjobbasescript{ double exposure = 10;#region when an acq fifo has been constructed and assigned to the job // this function is called when a new fifo is assigned to the job. this usually // occurs when the initialize acquisition button is pressed on the image source // control. this function is where you would perform custom setup associated // with the fifo. public override void acqfifoconstruction(cognex.visionpro.icogacqfifo fifo) { }#endregion #region when an acquisition is about to be started // called before an acquisition is started for manual and semi-automatic trigger // models. if number of software acquisitions pre-queued is set to 1 in the // job configuration, then no acquisitions should be in progress when this // function is called. public override void preacquisition() { // 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 icogacqexposure iexposure = job.acqfifo.ownedexposureparams; iexposure.exposure = exposure; }#endregion #region when an acquisition has just completed // called immediately after an acquisition has completed. // return true if the image should be inspected. // return false to skip the inspection and acquire another image. public override bool postacquisitionrefinfo(ref cognex.visionpro.icogimage image, cognex.visionpro.icogacqinfo info) { // 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 coghistogram curimagehist = new coghistogram(); coghistogramresult curhistresult = curimagehist.execute(image,null); if(curhistresult.mean>150) exposure *= 0.75; if(curhistresult.mean < 50) exposure *= 1.5; if(exposure<0.1) exposure = 0.1; return true; }#endregion //perform any initialization required by your script here. public override void initialize(cogjob jobparam) { //do not remove - call the base class implementation first - do not remove base.initialize(jobparam); }#endregion }
3.2 toolblock脚本使用实例-----显示blob区域的中心坐标于当前blob区域
toolblock脚本的应用最为广泛,用于控制工具的运行逻辑,修改生成的record,拓展数据逻辑等。本例以最简单的方式介绍toolbloc脚本使用方法,本例的具体应用为在各个独立的blob区域显示其中心坐标值。
在进行脚本编辑之前,根据用户需要添加程序集以及命名空间,添加引用程序集的具体过程如下图所示:
在编写c#toolblock脚本时,其常规流程为:
step1.根据需求添加程序集以及命名空间
step2.声明对应toolblock的相关变量以及用户自定义变量
step3.在initialize()函数中获取toolblock中工具的引用
step4.在grouprun()方法中通过工具变量控制工具的执行顺序以及获取所需用户数据
step5.修改record得到用户所需效果
//==========================step1===================================#region namespace importsusing system;using system.collections;using system.collections.generic;using system.drawing;using system.io;using system.windows.forms;using cognex.visionpro;using cognex.visionpro.toolblock;using cognex.visionpro3d;using cognex.visionpro.blob;using cognex.visionpro.resultsanalysis;#endregion public class cogtoolblockadvancedscript : cogtoolblockadvancedscriptbase{//==========================step2=================================== #region private member variables private cognex.visionpro.toolblock.cogtoolblock mtoolblock; private cogblobtool mblob; private list mlabels; #endregion /// /// called when the parent tool is run. /// add code here to customize or replace the normal run behavior. /// /// sets the message in the tool's runstatus. /// sets the result in the tool's runstatus /// true if the tool should run normally, /// false if grouprun customizes run behavior 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 //==========================step4=================================== mlabels.clear(); // run each tool using the runtool function //foreach(icogtool tool in mtoolblock.tools) //mtoolblock.runtool(tool, ref message, ref result); mtoolblock.runtool(mblob, ref message, ref result); cogblobresultcollection blobs = mblob.results.getblobs(); foreach(cogblobresult blob in blobs) { coggraphiclabel templabel = new coggraphiclabel(); templabel.alignment = coggraphiclabelalignmentconstants.baselinecenter; templabel.setxytext(blob.centerofmassx, blob.centerofmassy, convert.tostring(blob.centerofmassx)+,+convert.tostring(blob.centerofmassy)); templabel.color = cogcolorconstants.red; mlabels.add(templabel); } return false; } #region when the current run record is created /// /// called when the current record may have changed and is being reconstructed /// /// /// the new currentrecord is available to be initialized or customized. public override void modifycurrentrunrecord(cognex.visionpro.icogrecord currentrecord) { } #endregion #region when the last run record is created /// /// called when the last run record may have changed and is being reconstructed /// /// /// the new last run record is available to be initialized or customized. public override void modifylastrunrecord(cognex.visionpro.icogrecord lastrecord) { //==========================step5=================================== foreach(coggraphiclabel label in mlabels) { mtoolblock.addgraphictorunrecord(label, lastrecord, cogblobtool1.inputimage, ); } } #endregion #region when the script is initialized /// /// perform any initialization required by your script here /// /// the host tool 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 //==========================step3=================================== this.mtoolblock = ((cognex.visionpro.toolblock.cogtoolblock)(host)); mblob = this.mtoolblock.tools[cogblobtool1] as cogblobtool; mlabels = new list(); } #endregion}
效果图为:
四、脚本进阶
4.1脚本是“插件”程序集
无论你是通过job脚本、toolgroup脚本还是toolblock脚本拓展quickbuild程序功能时,实际上是完善了继承于某一接口的脚本类(继承于cogtoolgroupbasescript、cogjobbasescript或者cogtoolblockadvancedscriptbase类),在退出脚本编辑环境时quickbuild对你完善的子类进行编译,如果出现语法错误会报错提示,在语法错误改正前当前脚本的所有内容都不会被调用,因为没有通过编译。如果出现逻辑错误不会提示,需要在vs环境下进行调试,调试方法后续会详细介绍。quickbuild程序运行时通过接口实现对脚本子类成员函数的调用,从而将脚本函数的拓展功能进行实现。
关于脚本,你还需要明白以下几点:
用户在脚本中编写的代码会成为visionpro程序的一部分,其中的bug也不可避免影响到visionpro 的运行。
用户实现的脚本类会被编译为程序集加载到内存当中,而且每次对脚本进行编辑之后会重新编译,但是旧版本的程序集会一致在内存中直到你重新启动quickbuild,因此频繁修改脚本会增加一点点的内存消耗。
脚本程序集被加载到内存之后,visionpro会创建一个该脚本类的接口对象。脚本重新编辑之后接口对象会释放dispose之前对象,运行gc进行垃圾回收,创建新脚本类的接口实例。
在进行脚本编辑时,如果脚本内容比较多,最好经常进行保存,保存时需要退出脚本编辑环境对整个quickbuild工程进保存。补充一点,在quickbuild环境下进行工具编辑时亦需要进行随手保存,工具block误删除之后好像是无法恢复的只有退出quickbuild时选择不保存,前提是你误删除之前刚好保存过,惨痛的经历已不止一次。
4.2脚本实现事件与委托
事件响应函数中要增加异常处理机制(try …catch),否则容易导致visionpro运行出现异常;
不要在事件处理函数中产生当前的事件,否则会造成无限循环;
重写实现dispose(),取消事件注册。脚本每次修改退出后都会进行编译,运行时重新注册事件,如果没有在dispose总取消注册会造成多次注册;
当前事件的响应函数可能不止你在脚本中实现,在visionpro内部机制中可能也有实现,这些事件的响应函数执行顺序是不确定的。

磁保持继电器驱动电路
判断永磁电机失磁的方法_如何避免永磁电机失磁
南昌中级法院首次使用VR技术进行庭审直播
一种电感式位移传感器的电路系统设计[图]
韩国开发基于Micro LED技术的新方法,驱动医疗植入设备
VisionPro项目组成简介
GainSpan推出同时支持Wi-Fi和ZigBee技术芯片方案
阻碍物联网发展的因素有哪一些
利用共享目录使您的企业实现统一
DFN0606 MOSFET:小封装里的高效器件
时隔16年,色情业透过VR重返CES
什么是DVD刻录
5G小基站与宏基站共同打造广覆盖与高质量的5G精品网络
手机信号如何提供,为什么火车隧道信号不好
气体报警控制器产品结构设计中的EMC缺陷分析
2G物联网业务迁移势在必行
空中作业新势力——基于飞凌嵌入式RK3588核心板的无人机主控方案
10月新能源车销量大幅度上涨,纯电动汽车销均7.7万辆
激光气体探测器:工业安全的新卫士
智能手机也能测量血压?