在康耐視實(shí)習(xí)怎憋,那就必須得掌握我們公司大大大厲害的產(chǎn)品Vision Pro啦。經(jīng)過大半個月的學(xué)習(xí)訓(xùn)練九昧,基本掌握了不少技能绊袋。在這里寫個階段性小結(jié),記錄一下子铸鹰。
貼兩個文檔癌别,一個中文的(版本較老,VB版)蹋笼,還有一個VP自帶的英文文檔展姐。
傳送門,提取碼ny2r
下面進(jìn)入正題
準(zhǔn)備工具:
正版Vision Pro剖毯、Visual Studio 2012(筆者使用版本圾笨,也是公司默認(rèn)版本)、
Cognex開發(fā)工具包
步驟0:添加引用如下
(前4個是必須的基本引用)
步驟1:使用QuickBuild創(chuàng)建自己的操作程序(.vpp)
這里我就不多說了逊谋,默認(rèn)大家都會一些PM擂达、Blob這種基本操作,如果有需要詳細(xì)說的胶滋,評論打出1讓我看見哈(嘖嘖板鬓,這個人有點(diǎn)過分哈哈)
步驟2:配置VS
這里由于公司給我們配置了電腦悲敷,給的時候就有Cognex的工具包了。我想大家如果購買的正版Vision Pro也是會有的俭令,這里提兩個注意點(diǎn):
(1).net框架是需要4.6版本的镀迂,2012默認(rèn)4.5,記得升級唤蔗。
大部分人下載下來的4.6安裝時都會提示電腦已安裝更高版本探遵。這個問題困擾了我好一會兒,同事都紛紛轉(zhuǎn)戰(zhàn)2015或2017妓柜,但最后我發(fā)現(xiàn)是因為下載的.net 4.6的版本問題箱季,導(dǎo)致的無法安裝。應(yīng)該安裝開發(fā)包(給個官方鏈接)棍掐,如果實(shí)在搞不懂藏雏,那就全下下來試一遍吧~
(2)Vision Pro工具箱的安裝。
傻瓜式點(diǎn)就完了作煌,然后VS里面ToolBox應(yīng)該就有了掘殴。
步驟3:根據(jù)pdf438頁開始碼
這里按照他說的來就行了,不過他給的是VB程序粟誓,我改成了C#奏寨,現(xiàn)在公司內(nèi)部好像都用C#開發(fā)了。
過程比較多鹰服,我從我的難點(diǎn)一步步說病瞳,詳細(xì)的大家自己看pdf。最后我會貼碼悲酷。
(1)看的懂.net框架的構(gòu)造
每個文件的作用是什么套菜,得知道。
(2)JobManager在代碼中就代表了你的整個vpp項目设易,JobManager.Job(i)代表你項目中得第i個Job逗柴。
// 加載vpp作為一個job manager
myJobManager = (CogJobManager)CogSerializer.LoadObjectFromFile("../../../Job722.vpp")
// 引用job manager中的第一個
myJob = myJobManager.Job(0);
(3)”委托“指A線程訪問B線程的功能時使用的東西,其處理模式為:
首先為跨線程事務(wù)創(chuàng)建一個相同聲明的委托
// 每個win窗體控件只能通過創(chuàng)建它的線程來訪問
// 創(chuàng)建一個有預(yù)期簽名的委托 用于指向下面的停止事
delegate void myJobManagerDelegate(Object ByVaklsender,CogJobManagerActionEventArgs _ByVale);
在該事務(wù)創(chuàng)建該委托實(shí)例顿肺,提供2中實(shí)例化方法如下
// 創(chuàng)建委托實(shí)例 并指向停止事件的函數(shù)指
myJobManagerDelegate mydelegate = myJobManager_Stopped
myJobManagerDelegate mydelegate = new myJobManagerDelegate(myJobManager_Stopped);
創(chuàng)建一個該事務(wù)參數(shù)的數(shù)組
// 定義一個參數(shù)數(shù)
Object[] myobj = new Object[2] { ByValsender, _ByVale };
使用控件Invoke方法調(diào)用委托戏溺,完成操作
// 使用控件“魔術(shù)”調(diào)用Invoke,在GUI線程上調(diào)用我們的委托(當(dāng)前我們在vpp線程挟冠,但是需要使用GUI線程來使按鈕恢復(fù)可選于购,所以需要委托給GUI線程
this.Invoke(mydelegate, myobj);
最后,程序是怎么發(fā)現(xiàn)線程之間的不通融的呢知染?這就是為什么Invoke厲害的地方了肋僧,在事務(wù)中添加下列代碼
if (InvokeRequired)
{
# 創(chuàng)建一個指針指向該函數(shù)
# 在正確的線程上調(diào)用同一個函數(shù)
}
InvokeRequired是每一個控件的”魔術(shù)“屬性,如果程序處在錯誤的線程上,它就會返回”true“嫌吠。這就是Microsoft的一個用于校正線程亂問題的標(biāo)準(zhǔn)方法止潘。請牢記!
(4)Vision Pro 內(nèi)部控件的調(diào)用辫诅,參數(shù)獲取
首先我們需要現(xiàn)實(shí)的代碼狀態(tài)凭戴,是一個ICogRecord類,所以我們需要實(shí)例化該對象炕矮,然后將JobManager.UserResult傳遞給他么夫。這樣我們就獲取到我們Job的結(jié)果了。之后就是檢索我們需要的result肤视。
// 輸出運(yùn)行狀
Cognex.VisionPro.ICogRecord myrecord = myJobManager.UserResult() as ICogRecord
RunStatusTextBox.Text = myrecord.SubRecords["UserResultTag"].Content.ToString() + ":" + myrecord.SubRecords["JobName"].Content.ToString() + "-->";
RunStatusTextBox.Text += myrecord.SubRecords["RunStatus"].Content.ToString();
如果是要顯示Job工具里的運(yùn)行結(jié)果或者運(yùn)行參數(shù)等档痪,需要先在QuickBuild里面將你想要的參數(shù)添加到發(fā)送項,這樣在Code里面才能獲取到邢滑,不然有的參數(shù)(如Item里面的參數(shù))是沒有權(quán)限獲得的腐螟,而Count這樣的public變量可以直接調(diào)用,見程序
// 輸出參數(shù)
Cognex.VisionPro.ToolGroup.CogToolGroup myTG = myJob.VisionTool as Cognex.VisionPro.ToolGroup.CogToolGroup;
Cognex.VisionPro.ToolBlock.CogToolBlock myTB1 = myTG.Tools["Detect_Defects"] as Cognex.VisionPro.ToolBlock.CogToolBlock;
Cognex.VisionPro.PMAlign.CogPMAlignTool myPM = myTB1.Tools["CogPMAlignTool2"] as Cognex.VisionPro.PMAlign.CogPMAlignTool
try
{
textBox1.Text = myPM.Results.Count.ToString();
}
catch (Exception e5)
{
textBox1.Text = e5.ToString();
}
輸出圖像的話困后,Vision Pro提供四類圖像顯示控件乐纸,分別是:
1)CogToolDisplay
2)CogRecordsDisplay
3)CogRecordDisplay
4)CogDisplay
ToolD最復(fù)雜,它知道如何連接到Vision Pro工具以及如何調(diào)用工具所有的執(zhí)行結(jié)果,它通過顯示區(qū)上放一個下拉框允許用戶選擇瀏覽哪張圖像(就像QB里面的顯示結(jié)果控件一樣)。
RecordsD看上去和TD一樣,也允許下拉選擇,但是他對Vision Pro工具一無所知荣回,他不能從工具中獲取Records樹,必須用編程的方法自己來獲取伏尼。
RecordD(注意上面一個是Recordsssssssssss)顯示單個圖像記錄及其圖形的子記錄(也就是你在fixture生成的圖上進(jìn)行操作咆蒿,那么這些操作都會顯示在fixture圖上,這就是子記錄)秩冈,不可以自己選擇下拉咯本缠,所以他也是一無所知的,而且不提供Record樹入问。
Display是最低級的顯示控件丹锹,由其他所有顯示控件來使用,一無所知芬失,只顯示一個圖像和一組圖形楣黍,圖形圖像必須通過編程提供。
這里我們選擇RecordD棱烂。
Cognex.VisionPro.ICogRecord graphic_record;
graphic_record = myrecord.SubRecords["ShowLastRunRecordForUserQueue"];
graphic_record = graphic_record.SubRecords["LastRun"];
graphic_record = graphic_record.SubRecords[1];
// graphic_record = graphic_record.SubRecords["CogFixtureTool1.OutputImage"]; 方法2
CogRecordDisplay1.Record = graphic_record;
CogRecordDisplay1.Fit(true);
差不多基本的功能就是這樣了租漂,這一套做完無Bug,大家基本上可以在此基礎(chǔ)上進(jìn)行二次開發(fā)了。下面貼一下
源碼
設(shè)置的各控件名稱
Form1.cs整體
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Cognex.VisionPro;
using Cognex.VisionPro.QuickBuild;
namespace mywind
{
public partial class Form1 : Form
{
private CogJobManager myJobManager;
private CogJob myJob;
private CogJobIndependent myIndepenentJob;
public Form1()
{
InitializeComponent();
// 臨時辦法:線程間相互訪問
//Control.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
// 加載vpp作為一個job manager
myJobManager = (CogJobManager)CogSerializer.LoadObjectFromFile("../../../Job722.vpp");
// 引用job manager中的第一個job
myJob = myJobManager.Job(0);
// 初始化一個對象哩治,其參數(shù)引用包含更多關(guān)于job manager的信息
myIndepenentJob = myJob.OwnedIndependent;
// 清空所有job manager隊列秃踩,刷新陳舊的圖像和結(jié)果
myJobManager.UserQueueFlush();
myJobManager.FailureQueueFlush();
myJob.ImageQueueFlush();
myIndepenentJob.RealTimeQueueFlush();
// 為停止操作綁定事件
// CJM沒有在GUI創(chuàng)建按鈕,但是它調(diào)用了一個按鈕停止事件业筏!這個事件需要訪問GUI線程的按鈕憔杨!故需要“委托”
myJobManager.Stopped += new CogJobManager.CogJobManagerStoppedEventHandler(myJobManager_Stopped);
//myJobManager.Stopped += myJobManager_Stopped;
// 狀態(tài)顯示操作綁定事件
myJobManager.UserResultAvailable += myJobManager_UserResultAvailable;
// 連接bar狀態(tài)欄
CogDisplaystatusBar1.Display = CogRecordDisplay1;
}
private void button1_Click(object sender, EventArgs e)
{
try
{
// 避免死鎖
//ControlBox = false;
ShowTrainCheckBox.Enabled = false;
RunContCheckBox.Enabled = false;
// 防止在單詞任務(wù)完成前再次調(diào)用任務(wù) 讓按鈕不可點(diǎn)擊就行了
RunOnceButton.Enabled = false;
myJobManager.Run();
}
catch (Exception e1)
{
MessageBox.Show(e1.Message);
}
}
// 每個win窗體控件只能通過創(chuàng)建它的線程來訪問
// 創(chuàng)建一個有預(yù)期簽名的委托 用于指向下面的停止事件
delegate void myJobManagerDelegate(Object ByVaklsender,CogJobManagerActionEventArgs _ByVale);
// 所有工作完成 CJM運(yùn)行一個停止事件 重啟按鈕
private void myJobManager_Stopped(Object ByValsender, CogJobManagerActionEventArgs _ByVale)
{
if (InvokeRequired)
{
// 創(chuàng)建委托實(shí)例 并指向停止事件的函數(shù)指針
//myJobManagerDelegate mydelegate = myJobManager_Stopped;
myJobManagerDelegate mydelegate = new myJobManagerDelegate(myJobManager_Stopped);
// 定義一個參數(shù)數(shù)組
Object[] myobj = new Object[2] { ByValsender, _ByVale };
// 使用控件“魔術(shù)”調(diào)用Invoke,在GUI線程上調(diào)用我們的委托(當(dāng)前我們在vpp線程蒜胖,但是需要使用GUI線程來使按鈕恢復(fù)可選消别,所以需要委托給GUI線程)
this.Invoke(mydelegate, myobj);
}
//線程報錯 暫時不管
//ControlBox = true;
RunOnceButton.Enabled = true;
RunContCheckBox.Enabled = true;
ShowTrainCheckBox.Enabled = true;
}
private void RunContCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (RunContCheckBox.Checked)
{
try
{
//ControlBox = false;
ShowTrainCheckBox.Enabled = false;
RunOnceButton.Enabled = false;
myJobManager.RunContinuous();
}
catch (Exception e2)
{
MessageBox.Show(e2.Message);
}
}
else
{
try
{
RunContCheckBox.Enabled = false;
myJobManager.Stop();
}
catch(Exception e3)
{
MessageBox.Show(e3.Message);
}
}
}
private void myJobManager_UserResultAvailable(Object sender, CogJobManagerActionEventArgs e)
{
if (InvokeRequired)
{
myJobManagerDelegate mydel = new myJobManagerDelegate(myJobManager_UserResultAvailable);
Object[] args = new Object[2] { sender, e };
Invoke(mydel, args);
return;
}
// 輸出運(yùn)行狀態(tài)
Cognex.VisionPro.ICogRecord myrecord = myJobManager.UserResult() as ICogRecord;
RunStatusTextBox.Text = myrecord.SubRecords["UserResultTag"].Content.ToString() + ":" + myrecord.SubRecords["JobName"].Content.ToString() + "-->";
RunStatusTextBox.Text += myrecord.SubRecords["RunStatus"].Content.ToString();
// 輸出參數(shù)
Cognex.VisionPro.ToolGroup.CogToolGroup myTG = myJob.VisionTool as Cognex.VisionPro.ToolGroup.CogToolGroup;
Cognex.VisionPro.ToolBlock.CogToolBlock myTB1 = myTG.Tools["Detect_Defects"] as Cognex.VisionPro.ToolBlock.CogToolBlock;
Cognex.VisionPro.PMAlign.CogPMAlignTool myPM = myTB1.Tools["CogPMAlignTool2"] as Cognex.VisionPro.PMAlign.CogPMAlignTool;
Cognex.VisionPro.ICogRecord tmpRecord;
try
{
textBox1.Text = myPM.Results.Count.ToString();
}
catch (Exception e5)
{
textBox1.Text = e5.ToString();
}
// 輸出圖像
Cognex.VisionPro.ICogRecord graphic_record;
graphic_record = myrecord.SubRecords["ShowLastRunRecordForUserQueue"];
graphic_record = graphic_record.SubRecords["LastRun"];
graphic_record = graphic_record.SubRecords[1];
//graphic_record = graphic_record.SubRecords["CogFixtureTool1.OutputImage"];
CogRecordDisplay1.Record = graphic_record;
CogRecordDisplay1.Fit(true);
//RunStatusTextBox.Text = "";
}
private void RetrainButton_Click(object sender, EventArgs e)
{
// 調(diào)取工具
Cognex.VisionPro.ToolGroup.CogToolGroup myTG = myJob.VisionTool as Cognex.VisionPro.ToolGroup.CogToolGroup;
Cognex.VisionPro.ToolBlock.CogToolBlock myTB = myTG.Tools["Detect_Defects"] as Cognex.VisionPro.ToolBlock.CogToolBlock;
Cognex.VisionPro.PMAlign.CogPMAlignTool myPM = myTB.Tools["CogPMAlignTool1"] as Cognex.VisionPro.PMAlign.CogPMAlignTool;
// 重訓(xùn)練
myPM.Pattern.Train();
RunStatusTextBox.Text = myPM.RunStatus.ToString();
}
private void ShowTrainCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (ShowTrainCheckBox.Checked)
{
RunOnceButton.Enabled = false;
RunContCheckBox.Enabled = false;
RetrainButton.Enabled = true;
Cognex.VisionPro .ToolGroup .CogToolGroup myTG = myJob.VisionTool as Cognex.VisionPro.ToolGroup.CogToolGroup;
Cognex.VisionPro.ToolBlock.CogToolBlock myTB1 = myTG.Tools["Detect_Defects"] as Cognex.VisionPro.ToolBlock.CogToolBlock;
Cognex.VisionPro.PMAlign.CogPMAlignTool myPM = myTB1.Tools["CogPMAlignTool1"] as Cognex.VisionPro.PMAlign.CogPMAlignTool;
Cognex.VisionPro.ICogRecord tmpRecord;
tmpRecord = myPM.CreateCurrentRecord();
tmpRecord = tmpRecord.SubRecords["TrainImage"];
CogRecordDisplay1.Record = tmpRecord;
CogRecordDisplay1.Fit(true);
}
else
{
RunOnceButton.Enabled = true;
RunContCheckBox.Enabled = true;
RetrainButton.Enabled = false;
CogRecordDisplay1.Record = null;
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
最后把我用的Job的框架給大家看一眼,不然不好理解我里面的一些名字是啥意思
這四部分給出來台谢,大家按照我給的名字命名你的控件妖啥,然后如果想先爽一下,直接把我給的Form1.cs覆蓋掉你原本的就應(yīng)該ok了哦对碌。但是我建議大家荆虱,還是先按照pdf自己做,不懂了或者卡殼了朽们,再來看怀读,可以理解更深哦~
最后筆者想說,如果有不理解骑脱,或者讀后有所感想菜枷,想說一說哪里寫的不夠清楚,或者思路或者語言構(gòu)造叁丧,甚至一句感謝啤誊,都是我十分看重的財富。我寫了也不少了拥娄,但真的沒什么人有學(xué)術(shù)互動的蚊锹。怎么說呢,有點(diǎn)悲傷稚瘾。
還有一點(diǎn)牡昆,我寫的所有東西,如果大家有需要摊欠,我可以放到Git里丢烘,哪怕有一個人,我也不嫌麻煩些椒。所以播瞳,還是想大家跟我說的。免糕。赢乓。
也不知道怎么結(jié)尾忧侧,就給大家拜個早年吧。
最后編輯于 :?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者- 文/潘曉璐 我一進(jìn)店門母怜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來余耽,“玉大人,你說我怎么就攤上這事苹熏〉郑” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵轨域,是天一觀的道長袱耽。 經(jīng)常有香客問我,道長干发,這世上最難降的妖魔是什么朱巨? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮枉长,結(jié)果婚禮上冀续,老公的妹妹穿的比我還像新娘。我一直安慰自己必峰,他們只是感情好洪唐,可當(dāng)我...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著自点,像睡著了一般桐罕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桂敛,一...
- 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼借浊!你這毒婦竟也來了塘淑?” 一聲冷哼從身側(cè)響起,我...
- 序言:老撾萬榮一對情侶失蹤蚂斤,失蹤者是張志新(化名)和其女友劉穎存捺,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體曙蒸,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡捌治,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了纽窟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肖油。...
- 正文 年R本政府宣布县袱,位于F島的核電站,受9級特大地震影響瓷胧,放射性物質(zhì)發(fā)生泄漏显拳。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一搓萧、第九天 我趴在偏房一處隱蔽的房頂上張望杂数。 院中可真熱鬧,春花似錦瘸洛、人聲如沸揍移。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽那伐。三九已至,卻和暖如春石蔗,著一層夾襖步出監(jiān)牢的瞬間罕邀,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓棍厌,卻偏偏與公主長得像肾胯,于是被迫代替她去往敵國和親竖席。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
步驟3:根據(jù)pdf438頁開始碼
這里按照他說的來就行了,不過他給的是VB程序粟誓,我改成了C#奏寨,現(xiàn)在公司內(nèi)部好像都用C#開發(fā)了。
過程比較多鹰服,我從我的難點(diǎn)一步步說病瞳,詳細(xì)的大家自己看pdf。最后我會貼碼悲酷。
(1)看的懂.net框架的構(gòu)造
每個文件的作用是什么套菜,得知道。
(2)JobManager在代碼中就代表了你的整個vpp項目设易,JobManager.Job(i)代表你項目中得第i個Job逗柴。
// 加載vpp作為一個job manager
myJobManager = (CogJobManager)CogSerializer.LoadObjectFromFile("../../../Job722.vpp")
// 引用job manager中的第一個
myJob = myJobManager.Job(0);
(3)”委托“指A線程訪問B線程的功能時使用的東西,其處理模式為:
首先為跨線程事務(wù)創(chuàng)建一個相同聲明的委托
// 每個win窗體控件只能通過創(chuàng)建它的線程來訪問
// 創(chuàng)建一個有預(yù)期簽名的委托 用于指向下面的停止事
delegate void myJobManagerDelegate(Object ByVaklsender,CogJobManagerActionEventArgs _ByVale);
在該事務(wù)創(chuàng)建該委托實(shí)例顿肺,提供2中實(shí)例化方法如下
// 創(chuàng)建委托實(shí)例 并指向停止事件的函數(shù)指
myJobManagerDelegate mydelegate = myJobManager_Stopped
myJobManagerDelegate mydelegate = new myJobManagerDelegate(myJobManager_Stopped);
創(chuàng)建一個該事務(wù)參數(shù)的數(shù)組
// 定義一個參數(shù)數(shù)
Object[] myobj = new Object[2] { ByValsender, _ByVale };
使用控件Invoke方法調(diào)用委托戏溺,完成操作
// 使用控件“魔術(shù)”調(diào)用Invoke,在GUI線程上調(diào)用我們的委托(當(dāng)前我們在vpp線程挟冠,但是需要使用GUI線程來使按鈕恢復(fù)可選于购,所以需要委托給GUI線程
this.Invoke(mydelegate, myobj);
最后,程序是怎么發(fā)現(xiàn)線程之間的不通融的呢知染?這就是為什么Invoke厲害的地方了肋僧,在事務(wù)中添加下列代碼
if (InvokeRequired)
{
# 創(chuàng)建一個指針指向該函數(shù)
# 在正確的線程上調(diào)用同一個函數(shù)
}
InvokeRequired是每一個控件的”魔術(shù)“屬性,如果程序處在錯誤的線程上,它就會返回”true“嫌吠。這就是Microsoft的一個用于校正線程亂問題的標(biāo)準(zhǔn)方法止潘。請牢記!
(4)Vision Pro 內(nèi)部控件的調(diào)用辫诅,參數(shù)獲取
首先我們需要現(xiàn)實(shí)的代碼狀態(tài)凭戴,是一個ICogRecord類,所以我們需要實(shí)例化該對象炕矮,然后將JobManager.UserResult傳遞給他么夫。這樣我們就獲取到我們Job的結(jié)果了。之后就是檢索我們需要的result肤视。
// 輸出運(yùn)行狀
Cognex.VisionPro.ICogRecord myrecord = myJobManager.UserResult() as ICogRecord
RunStatusTextBox.Text = myrecord.SubRecords["UserResultTag"].Content.ToString() + ":" + myrecord.SubRecords["JobName"].Content.ToString() + "-->";
RunStatusTextBox.Text += myrecord.SubRecords["RunStatus"].Content.ToString();
如果是要顯示Job工具里的運(yùn)行結(jié)果或者運(yùn)行參數(shù)等档痪,需要先在QuickBuild里面將你想要的參數(shù)添加到發(fā)送項,這樣在Code里面才能獲取到邢滑,不然有的參數(shù)(如Item里面的參數(shù))是沒有權(quán)限獲得的腐螟,而Count這樣的public變量可以直接調(diào)用,見程序
// 輸出參數(shù)
Cognex.VisionPro.ToolGroup.CogToolGroup myTG = myJob.VisionTool as Cognex.VisionPro.ToolGroup.CogToolGroup;
Cognex.VisionPro.ToolBlock.CogToolBlock myTB1 = myTG.Tools["Detect_Defects"] as Cognex.VisionPro.ToolBlock.CogToolBlock;
Cognex.VisionPro.PMAlign.CogPMAlignTool myPM = myTB1.Tools["CogPMAlignTool2"] as Cognex.VisionPro.PMAlign.CogPMAlignTool
try
{
textBox1.Text = myPM.Results.Count.ToString();
}
catch (Exception e5)
{
textBox1.Text = e5.ToString();
}
輸出圖像的話困后,Vision Pro提供四類圖像顯示控件乐纸,分別是:
1)CogToolDisplay
2)CogRecordsDisplay
3)CogRecordDisplay
4)CogDisplay
ToolD最復(fù)雜,它知道如何連接到Vision Pro工具以及如何調(diào)用工具所有的執(zhí)行結(jié)果,它通過顯示區(qū)上放一個下拉框允許用戶選擇瀏覽哪張圖像(就像QB里面的顯示結(jié)果控件一樣)。
RecordsD看上去和TD一樣,也允許下拉選擇,但是他對Vision Pro工具一無所知荣回,他不能從工具中獲取Records樹,必須用編程的方法自己來獲取伏尼。
RecordD(注意上面一個是Recordsssssssssss)顯示單個圖像記錄及其圖形的子記錄(也就是你在fixture生成的圖上進(jìn)行操作咆蒿,那么這些操作都會顯示在fixture圖上,這就是子記錄)秩冈,不可以自己選擇下拉咯本缠,所以他也是一無所知的,而且不提供Record樹入问。
Display是最低級的顯示控件丹锹,由其他所有顯示控件來使用,一無所知芬失,只顯示一個圖像和一組圖形楣黍,圖形圖像必須通過編程提供。
這里我們選擇RecordD棱烂。
Cognex.VisionPro.ICogRecord graphic_record;
graphic_record = myrecord.SubRecords["ShowLastRunRecordForUserQueue"];
graphic_record = graphic_record.SubRecords["LastRun"];
graphic_record = graphic_record.SubRecords[1];
// graphic_record = graphic_record.SubRecords["CogFixtureTool1.OutputImage"]; 方法2
CogRecordDisplay1.Record = graphic_record;
CogRecordDisplay1.Fit(true);
差不多基本的功能就是這樣了租漂,這一套做完無Bug,大家基本上可以在此基礎(chǔ)上進(jìn)行二次開發(fā)了。下面貼一下
源碼
設(shè)置的各控件名稱
Form1.cs整體
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Cognex.VisionPro;
using Cognex.VisionPro.QuickBuild;
namespace mywind
{
public partial class Form1 : Form
{
private CogJobManager myJobManager;
private CogJob myJob;
private CogJobIndependent myIndepenentJob;
public Form1()
{
InitializeComponent();
// 臨時辦法:線程間相互訪問
//Control.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
// 加載vpp作為一個job manager
myJobManager = (CogJobManager)CogSerializer.LoadObjectFromFile("../../../Job722.vpp");
// 引用job manager中的第一個job
myJob = myJobManager.Job(0);
// 初始化一個對象哩治,其參數(shù)引用包含更多關(guān)于job manager的信息
myIndepenentJob = myJob.OwnedIndependent;
// 清空所有job manager隊列秃踩,刷新陳舊的圖像和結(jié)果
myJobManager.UserQueueFlush();
myJobManager.FailureQueueFlush();
myJob.ImageQueueFlush();
myIndepenentJob.RealTimeQueueFlush();
// 為停止操作綁定事件
// CJM沒有在GUI創(chuàng)建按鈕,但是它調(diào)用了一個按鈕停止事件业筏!這個事件需要訪問GUI線程的按鈕憔杨!故需要“委托”
myJobManager.Stopped += new CogJobManager.CogJobManagerStoppedEventHandler(myJobManager_Stopped);
//myJobManager.Stopped += myJobManager_Stopped;
// 狀態(tài)顯示操作綁定事件
myJobManager.UserResultAvailable += myJobManager_UserResultAvailable;
// 連接bar狀態(tài)欄
CogDisplaystatusBar1.Display = CogRecordDisplay1;
}
private void button1_Click(object sender, EventArgs e)
{
try
{
// 避免死鎖
//ControlBox = false;
ShowTrainCheckBox.Enabled = false;
RunContCheckBox.Enabled = false;
// 防止在單詞任務(wù)完成前再次調(diào)用任務(wù) 讓按鈕不可點(diǎn)擊就行了
RunOnceButton.Enabled = false;
myJobManager.Run();
}
catch (Exception e1)
{
MessageBox.Show(e1.Message);
}
}
// 每個win窗體控件只能通過創(chuàng)建它的線程來訪問
// 創(chuàng)建一個有預(yù)期簽名的委托 用于指向下面的停止事件
delegate void myJobManagerDelegate(Object ByVaklsender,CogJobManagerActionEventArgs _ByVale);
// 所有工作完成 CJM運(yùn)行一個停止事件 重啟按鈕
private void myJobManager_Stopped(Object ByValsender, CogJobManagerActionEventArgs _ByVale)
{
if (InvokeRequired)
{
// 創(chuàng)建委托實(shí)例 并指向停止事件的函數(shù)指針
//myJobManagerDelegate mydelegate = myJobManager_Stopped;
myJobManagerDelegate mydelegate = new myJobManagerDelegate(myJobManager_Stopped);
// 定義一個參數(shù)數(shù)組
Object[] myobj = new Object[2] { ByValsender, _ByVale };
// 使用控件“魔術(shù)”調(diào)用Invoke,在GUI線程上調(diào)用我們的委托(當(dāng)前我們在vpp線程蒜胖,但是需要使用GUI線程來使按鈕恢復(fù)可選消别,所以需要委托給GUI線程)
this.Invoke(mydelegate, myobj);
}
//線程報錯 暫時不管
//ControlBox = true;
RunOnceButton.Enabled = true;
RunContCheckBox.Enabled = true;
ShowTrainCheckBox.Enabled = true;
}
private void RunContCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (RunContCheckBox.Checked)
{
try
{
//ControlBox = false;
ShowTrainCheckBox.Enabled = false;
RunOnceButton.Enabled = false;
myJobManager.RunContinuous();
}
catch (Exception e2)
{
MessageBox.Show(e2.Message);
}
}
else
{
try
{
RunContCheckBox.Enabled = false;
myJobManager.Stop();
}
catch(Exception e3)
{
MessageBox.Show(e3.Message);
}
}
}
private void myJobManager_UserResultAvailable(Object sender, CogJobManagerActionEventArgs e)
{
if (InvokeRequired)
{
myJobManagerDelegate mydel = new myJobManagerDelegate(myJobManager_UserResultAvailable);
Object[] args = new Object[2] { sender, e };
Invoke(mydel, args);
return;
}
// 輸出運(yùn)行狀態(tài)
Cognex.VisionPro.ICogRecord myrecord = myJobManager.UserResult() as ICogRecord;
RunStatusTextBox.Text = myrecord.SubRecords["UserResultTag"].Content.ToString() + ":" + myrecord.SubRecords["JobName"].Content.ToString() + "-->";
RunStatusTextBox.Text += myrecord.SubRecords["RunStatus"].Content.ToString();
// 輸出參數(shù)
Cognex.VisionPro.ToolGroup.CogToolGroup myTG = myJob.VisionTool as Cognex.VisionPro.ToolGroup.CogToolGroup;
Cognex.VisionPro.ToolBlock.CogToolBlock myTB1 = myTG.Tools["Detect_Defects"] as Cognex.VisionPro.ToolBlock.CogToolBlock;
Cognex.VisionPro.PMAlign.CogPMAlignTool myPM = myTB1.Tools["CogPMAlignTool2"] as Cognex.VisionPro.PMAlign.CogPMAlignTool;
Cognex.VisionPro.ICogRecord tmpRecord;
try
{
textBox1.Text = myPM.Results.Count.ToString();
}
catch (Exception e5)
{
textBox1.Text = e5.ToString();
}
// 輸出圖像
Cognex.VisionPro.ICogRecord graphic_record;
graphic_record = myrecord.SubRecords["ShowLastRunRecordForUserQueue"];
graphic_record = graphic_record.SubRecords["LastRun"];
graphic_record = graphic_record.SubRecords[1];
//graphic_record = graphic_record.SubRecords["CogFixtureTool1.OutputImage"];
CogRecordDisplay1.Record = graphic_record;
CogRecordDisplay1.Fit(true);
//RunStatusTextBox.Text = "";
}
private void RetrainButton_Click(object sender, EventArgs e)
{
// 調(diào)取工具
Cognex.VisionPro.ToolGroup.CogToolGroup myTG = myJob.VisionTool as Cognex.VisionPro.ToolGroup.CogToolGroup;
Cognex.VisionPro.ToolBlock.CogToolBlock myTB = myTG.Tools["Detect_Defects"] as Cognex.VisionPro.ToolBlock.CogToolBlock;
Cognex.VisionPro.PMAlign.CogPMAlignTool myPM = myTB.Tools["CogPMAlignTool1"] as Cognex.VisionPro.PMAlign.CogPMAlignTool;
// 重訓(xùn)練
myPM.Pattern.Train();
RunStatusTextBox.Text = myPM.RunStatus.ToString();
}
private void ShowTrainCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (ShowTrainCheckBox.Checked)
{
RunOnceButton.Enabled = false;
RunContCheckBox.Enabled = false;
RetrainButton.Enabled = true;
Cognex.VisionPro .ToolGroup .CogToolGroup myTG = myJob.VisionTool as Cognex.VisionPro.ToolGroup.CogToolGroup;
Cognex.VisionPro.ToolBlock.CogToolBlock myTB1 = myTG.Tools["Detect_Defects"] as Cognex.VisionPro.ToolBlock.CogToolBlock;
Cognex.VisionPro.PMAlign.CogPMAlignTool myPM = myTB1.Tools["CogPMAlignTool1"] as Cognex.VisionPro.PMAlign.CogPMAlignTool;
Cognex.VisionPro.ICogRecord tmpRecord;
tmpRecord = myPM.CreateCurrentRecord();
tmpRecord = tmpRecord.SubRecords["TrainImage"];
CogRecordDisplay1.Record = tmpRecord;
CogRecordDisplay1.Fit(true);
}
else
{
RunOnceButton.Enabled = true;
RunContCheckBox.Enabled = true;
RetrainButton.Enabled = false;
CogRecordDisplay1.Record = null;
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
最后把我用的Job的框架給大家看一眼,不然不好理解我里面的一些名字是啥意思這四部分給出來台谢,大家按照我給的名字命名你的控件妖啥,然后如果想先爽一下,直接把我給的Form1.cs覆蓋掉你原本的就應(yīng)該ok了哦对碌。但是我建議大家荆虱,還是先按照pdf自己做,不懂了或者卡殼了朽们,再來看怀读,可以理解更深哦~
最后筆者想說,如果有不理解骑脱,或者讀后有所感想菜枷,想說一說哪里寫的不夠清楚,或者思路或者語言構(gòu)造叁丧,甚至一句感謝啤誊,都是我十分看重的財富。我寫了也不少了拥娄,但真的沒什么人有學(xué)術(shù)互動的蚊锹。怎么說呢,有點(diǎn)悲傷稚瘾。
還有一點(diǎn)牡昆,我寫的所有東西,如果大家有需要摊欠,我可以放到Git里丢烘,哪怕有一個人,我也不嫌麻煩些椒。所以播瞳,還是想大家跟我說的。免糕。赢乓。
也不知道怎么結(jié)尾忧侧,就給大家拜個早年吧。
- 文/潘曉璐 我一進(jìn)店門母怜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來余耽,“玉大人,你說我怎么就攤上這事苹熏〉郑” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵轨域,是天一觀的道長袱耽。 經(jīng)常有香客問我,道長干发,這世上最難降的妖魔是什么朱巨? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮枉长,結(jié)果婚禮上冀续,老公的妹妹穿的比我還像新娘。我一直安慰自己必峰,他們只是感情好洪唐,可當(dāng)我...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著自点,像睡著了一般桐罕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桂敛,一...
- 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼借浊!你這毒婦竟也來了塘淑?” 一聲冷哼從身側(cè)響起,我...
- 序言:老撾萬榮一對情侶失蹤蚂斤,失蹤者是張志新(化名)和其女友劉穎存捺,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體曙蒸,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡捌治,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了纽窟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肖油。...
- 正文 年R本政府宣布县袱,位于F島的核電站,受9級特大地震影響瓷胧,放射性物質(zhì)發(fā)生泄漏显拳。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一搓萧、第九天 我趴在偏房一處隱蔽的房頂上張望杂数。 院中可真熱鬧,春花似錦瘸洛、人聲如沸揍移。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽那伐。三九已至,卻和暖如春石蔗,著一層夾襖步出監(jiān)牢的瞬間罕邀,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓棍厌,卻偏偏與公主長得像肾胯,于是被迫代替她去往敵國和親竖席。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...