機(jī)器視覺大師(MVS),一體式可編程機(jī)器視覺控制器(FVS), 可組態(tài)機(jī)器視覺控制器(EVS)都支持腳本編程。雖然機(jī)器視覺大師腳本編程最簡單,但是很多用戶普遍感覺好像很難入門,筆者將詳細(xì)介紹一下這些機(jī)器視覺大師的腳本編程原理和過程。
機(jī)器視覺大師在自動檢測模式下,可以支持用戶腳本編程。為什么要這樣的功能呢?這需要簡單介紹一下機(jī)器視覺大師提供自動檢測功能的目的說起。
機(jī)器視覺大師自動檢測功能主要用于開發(fā)全自動機(jī)器視覺自動化系統(tǒng)的前期實(shí)驗(yàn)分析(圖形預(yù)處理,特征算法等)或桌面式半自動機(jī)器視覺應(yīng)用。機(jī)器視覺在自動化領(lǐng)域的應(yīng)用從軟件開發(fā)方面來講主要涉及圖像預(yù)處理,特征分析,模式識別算法等,實(shí)現(xiàn)工業(yè)領(lǐng)域常用的如定位,顏色區(qū)分,缺陷檢測,生產(chǎn)日期檢測或識別,條碼識別等。如果一個新的需求全部從頭開始開發(fā)的話,工作量十分巨大,而且需要開發(fā)人員既具有圖像處理方面的知識,也需要具備比較強(qiáng)的編程能力,一般來說,是非常困難的。
機(jī)器視覺大師將圖像分析和常用的模式識別等算法完全封裝成檢測算子,采用可視化編輯的方式,用戶只需要動動鼠標(biāo)扒拉幾下, 不到幾分鐘,一個機(jī)器視覺應(yīng)用系統(tǒng)原型將很快建立起來。但是,由于應(yīng)用的復(fù)雜化,機(jī)器視覺大師提供的算子可能不能完全適用用戶的實(shí)際需求。這就需要用戶進(jìn)行最后的處理即腳本編程,來完成最終的目標(biāo)。打個比喻來說,機(jī)器視覺大師就好比一個城市建立的地鐵系統(tǒng),雖然方便快捷,但是最后一公里還需要一種交通工具如共享單車,才能使乘客很舒服地到達(dá)目的地。腳本編程好像是共享單車,雖然不是全自動的,需要用點(diǎn)力,但是操作實(shí)在是很簡單,只要掌握好方向盤,用力蹬就行了。
機(jī)器視覺大師里面設(shè)計一個簡單的機(jī)器視覺或影像自動檢測應(yīng)用,基本過程如下:

言歸正傳,在機(jī)器視覺大師里面進(jìn)行腳本編程其實(shí)也是很簡單的一件事。不像一些高級編程語言如c/c++,java, 網(wǎng)頁腳本php,這些語言功能較強(qiáng),支持類,函數(shù),事件等,需要掌握的知識點(diǎn)較多,學(xué)習(xí)起來比較復(fù)雜,漫長。機(jī)器視覺大師的腳本編程只需要掌握兩點(diǎn):1. 理解和掌握對象和屬性的概念; 2. 理解和應(yīng)用邏輯判斷和循環(huán)或順序執(zhí)行。完全不需要自定義什么類,函數(shù)什么的。這些概念是所有編程語言里面最基本的內(nèi)容。所以,別擔(dān)心,一切會是那么的簡單。
對象模型
在機(jī)器視覺大師里面,編程的時候一定是以對象為主。 頂層對象只有兩種,即視場對象和整個應(yīng)用程序?qū)ο?/strong>。 視場對象下面有算子對象,算子對象有讀數(shù)屬性(復(fù)合型讀數(shù)如點(diǎn)(x,y)也可以理解成對象)。不同的算子對象具有不同的讀數(shù),有數(shù)據(jù)類,有文本類,或數(shù)組類。機(jī)器視覺大師里面的基本對象模型如下圖:

應(yīng)用程序?qū)ο蟾鶕?jù)當(dāng)前的檢測任務(wù)的不同,具有不同的屬性(也稱變量)。視場對象即相機(jī)所能成像的范圍,表現(xiàn)為一個圖像,但實(shí)際編程時可能與圖像完全不搭邊,所以只要記住,當(dāng)前PC系統(tǒng)有幾個相機(jī),就可以理解有幾個視場對象。視場下面的算子的數(shù)量根據(jù)用戶自己實(shí)際添加的數(shù)量決定。
在編程中,所有的對象均使用名稱標(biāo)識,這些標(biāo)識均系統(tǒng)已經(jīng)自動命名, 應(yīng)用程序?qū)ο蟮拿譃閙vs, 有且只有一個。視場對象的名字為sight, 后面緊接一個數(shù)字,表示不同的視場對象等等,如sight1。視場里面不同的算子分別有自己的名字,同類型的算子后面添加序號加以區(qū)分,與視場名字的命名規(guī)則差不多。
使用的時候,對象一定是從最頂層對象開始,然后往下一層,再往下一層,直到屬性,不同的對象之間使用圓點(diǎn)”.”符號進(jìn)行連接。例如,如果要獲得視場一(sight1)里面的雙態(tài)識別算子(dual1)的“檢測結(jié)果”讀數(shù), 如:
n = sight1.dual1.res
算子對象的讀數(shù)在運(yùn)行一次檢測以后,系統(tǒng)會自動給出結(jié)果,但是,應(yīng)用程序?qū)ο蟮膶傩院芏嗲闆r下,需要用戶在腳本里面進(jìn)行編程計算,如
mvs.good = 1,
這條語句將應(yīng)用程序?qū)ο蟮膅ood屬性設(shè)置為1.
不同檢測算子可用讀數(shù)如下表(由于版本不斷變化,請使用實(shí)際名稱)
檢測算子
|
讀數(shù)名稱
|
數(shù)據(jù)類型
|
說明
|
雙態(tài)檢測
|
res-結(jié)果
|
整數(shù)
|
模板索引。如果為0表示第一個模板,如果為1表示第2個模板。
|
定位
|
count – 實(shí)例個數(shù)
position –位置
abspos –絕對位置
offset – 偏移
|
整數(shù)
點(diǎn)
點(diǎn)
2D實(shí)數(shù)
|
如果找到實(shí)例,返回1,否則返回0
|
多態(tài)檢測
|
result – 結(jié)果(最大分?jǐn)?shù)的模板索引)
count –已經(jīng)學(xué)習(xí)的模板數(shù)
pattname – 模板名稱或說明
score – 當(dāng)前識別的每個模板分?jǐn)?shù)值
|
整數(shù)
整數(shù)
文本
實(shí)數(shù)
|
多態(tài)檢測的識別結(jié)果為分?jǐn)?shù)最高的模板索引。除非進(jìn)行了實(shí)際的模板增或減操作,已經(jīng)學(xué)習(xí)的模板數(shù)每次識別以后都不會變換。
|
模板識別
|
count – 實(shí)例個數(shù)
position –位置
angle – 角度
|
整數(shù)
點(diǎn)
實(shí)數(shù)
|
|
一維碼
|
count – 條碼個數(shù)
content –條碼內(nèi)容
|
整數(shù)
文本
|
|
二維碼
|
count – 條碼個數(shù)
content –條碼內(nèi)容
|
整數(shù)
文本
|
|
BLOB分析
|
count – blob個數(shù)
offset – 偏移
width – 寬度
length – 長度
centroid – 質(zhì)心
dens – 密度
pixsum – 像素和
pixavg – 像素平均
pixvar—像素方差
strength – 強(qiáng)度
perim – 周長
area – 面積
circu -- 圓度
slant – 斜率
rect – 外接矩形
|
整數(shù)
2D實(shí)數(shù)
整數(shù)
整數(shù)
點(diǎn)
實(shí)數(shù)
實(shí)數(shù)
實(shí)數(shù)
實(shí)數(shù)
實(shí)數(shù)
整數(shù)
整數(shù)
實(shí)數(shù)
實(shí)數(shù)
矩形
|
|
文字識別
|
content –字符內(nèi)容
|
文本
|
|
顏色識別
|
result – 結(jié)果
|
整數(shù)
|
返回顏色索引
|
邊距測量
|
result – 結(jié)果
|
整數(shù)
|
返回實(shí)際的長度,以像素為單位
|
如果結(jié)果有多組相同屬性,那么該屬性即為屬性數(shù)組,需要使用數(shù)組的方式進(jìn)行引用,如
blob1.offset[1].x
數(shù)組序號從1開始。 記住: 凡是有多組相同屬性的的算子,一般都會提供一個名稱類似“count”的讀數(shù)表示當(dāng)前有多少組屬性。如:
n = blob1.count
m = pmat1.count
萬一忘記某個算子的讀數(shù),也可以在對應(yīng)算子的參數(shù)設(shè)置窗口里面的讀數(shù)頁中得到,如下圖:
邏輯判斷和條件執(zhí)行
機(jī)器視覺腳本編程機(jī)大部分上是對視場中算子的結(jié)果進(jìn)行邏輯運(yùn)行以后,然后對應(yīng)用程序?qū)ο蟮南嚓P(guān)屬性進(jìn)行賦值的一個過程。這樣的簡單的方式,極大地增強(qiáng)軟件的功能,達(dá)到完全滿足用戶需求的目的。下面為腳本編輯的一般過程:
  。

出于簡單易用的考慮,機(jī)器視覺大師支持最基本的邏輯判斷表達(dá)式和條件執(zhí)行語句。當(dāng)然,最基本的賦值語句和算術(shù)表達(dá)式是必須支持的。語句不需要結(jié)束符如c語言中的”;”,但是需要使用空格隔開,出于可讀性考慮,建議一個語句使用一行,最好采用縮進(jìn)結(jié)構(gòu)。
下表是邏輯運(yùn)算表達(dá)式:
邏輯運(yùn)算符或關(guān)系運(yùn)算符,算術(shù)運(yùn)算符,括號等構(gòu)成邏輯表達(dá)式,其結(jié)果只能為true(真)或false(假)。
支持的邏輯或關(guān)系運(yùn)算符如下:
算符或關(guān)鍵詞
|
說明
|
類型
|
and
|
與,左右兩邊的表達(dá)式為true,結(jié)果才為true,否則為false
|
邏輯運(yùn)算符
|
or
|
或,左右兩邊的任意一個表達(dá)式為true,結(jié)果為true,否則為false
|
邏輯運(yùn)算符
|
not
|
非,如果右邊的表達(dá)式為true,結(jié)果為false。反之如果右邊的表達(dá)式為false,結(jié)果為true。
|
邏輯運(yùn)算符
|
<
|
小于,左邊的表達(dá)式值如果小于右邊的表達(dá)式值,結(jié)果為true,否則為false.
|
關(guān)系運(yùn)算符
|
>
|
大于,左邊的表達(dá)式值如果大于右邊的表達(dá)式值,結(jié)果為true,否則為false.
|
關(guān)系運(yùn)算符
|
<=
|
小于等于,左邊的表達(dá)式值如果小于等于右邊的表達(dá)式值,結(jié)果為true,否則為false.
|
關(guān)系運(yùn)算符
|
>=
|
大于等于,左邊的表達(dá)式值如果大于等于右邊的表達(dá)式值,結(jié)果為true,否則為false.
|
關(guān)系運(yùn)算符
|
==
|
等于,左邊的表達(dá)式值如果等于右邊的表達(dá)式值,結(jié)果為true,否則為false.
|
關(guān)系運(yùn)算符
|
~=
|
不等于,左邊的表達(dá)式值如果不等于右邊的表達(dá)式值,結(jié)果為true,否則為false.
|
關(guān)系運(yùn)算符
|
算術(shù)表達(dá)式的算符如下:

一個表達(dá)式可能由不同的類型的的表達(dá)式組成。這些表達(dá)式在計算的時候遵守一定的優(yōu)先順序。運(yùn)算符可以通過括號括起,括號里面的運(yùn)算符號具有最高的優(yōu)先級。當(dāng)無括號的情況下,這些運(yùn)算符的從高到低的優(yōu)先順序如下:
^
|
not,-
|
*, /, %
|
+, -
|
<, > , <=, >=, ==, ~=
|
and
|
or
|
在機(jī)器視覺大師腳本里面可以隨意定義變量,這些變量不需要申明數(shù)據(jù)類型,直接將算術(shù)表達(dá)式或邏輯表達(dá)式賦值即可。變量的類型根據(jù)表達(dá)式的結(jié)果決定,可以是邏輯類,數(shù)值類或文本類。
邏輯類的變量只能為true或 false, 文本類的內(nèi)容需要用雙引號括起。如
label = “hello, world”
result = sight1.dual1.res == 0
if result == true then
//do something
end
機(jī)器視覺大師可以運(yùn)行不同種類的自動檢測任務(wù)。很多情況下,需要進(jìn)行控制執(zhí)行,對不同的屬性進(jìn)行賦值,以獲得最終結(jié)果。機(jī)器視覺大師提供基本的控制關(guān)鍵詞如if, while, for等
if then else
if語句先測試其條件,然后根據(jù)測試結(jié)果執(zhí)行then部分或者else部分,else部分是可選的。如果要編寫嵌套的if,可以使用elseif。如:
示例一
if a < 0 then
a = 0
end
示例二
if a < b then
a =b
else
a = a+1
end
示例三
if op == "+" then
r = a + b
elseif op == "-" then
r = a – b
end
while
while語句評估邏輯表達(dá)式的值,當(dāng)結(jié)果為true的時候,執(zhí)行程序塊。如:
local a = 10
while a > 0 do
a = a - 1
end
for
for語句將指定的變量進(jìn)行遞增計算,循環(huán)一定次數(shù)。如:
for i= 1, 100, 1 do
# Do something
end
該段語句將反復(fù)執(zhí)行程序段100次。在for語句里面,第一個數(shù)字為初始值,第二個數(shù)字為終止值,第三個數(shù)字為步長,通常情況下為1,如果為1的話,第三個數(shù)字可以省略。
如果需要返回不再往下執(zhí)行,可以使用return關(guān)鍵詞進(jìn)行返回。跳出一些循環(huán)塊,可以使用break關(guān)鍵詞。如:
for i= 1, 100, 1 do
if i==50 then
break
end
end
n = 100
上面的語句段基本算法為當(dāng)i等于50的時候,跳出循環(huán),然后運(yùn)行n=100語句。
機(jī)器視覺大師支持不同的檢測任務(wù)類型,不同的檢測類型下,可用的應(yīng)用程序?qū)傩詳?shù)量和含義是不一樣的。這些屬性如合格數(shù),在檢測運(yùn)行過程中將在結(jié)果顯示面板中被顯示出來。下表為支持的所有屬性(全局變量):
名稱
|
說明
|
適用的檢測類型
|
數(shù)據(jù)類型
|
rd1
|
讀數(shù)1
|
常規(guī)檢測(默認(rèn))
|
實(shí)數(shù)
|
rd2
|
讀數(shù)2
|
常規(guī)檢測(默認(rèn))
|
實(shí)數(shù)
|
rd3
|
讀數(shù)3
|
常規(guī)檢測(默認(rèn))
|
實(shí)數(shù)
|
rd4
|
讀數(shù)4
|
常規(guī)檢測(默認(rèn))
|
實(shí)數(shù)
|
rd5
|
讀數(shù)5
|
常規(guī)檢測(默認(rèn))
|
實(shí)數(shù)
|
rd6
|
讀數(shù)6
|
常規(guī)檢測(默認(rèn))
|
實(shí)數(shù)
|
rd7
|
讀數(shù)7
|
常規(guī)檢測(默認(rèn))
|
實(shí)數(shù)
|
rd8
|
讀數(shù)8
|
常規(guī)檢測(默認(rèn))
|
實(shí)數(shù)
|
good
|
合格品
|
質(zhì)量檢測
|
布爾類整數(shù),僅為1或0
|
ng
|
缺陷品
|
質(zhì)量檢測
|
布爾類整數(shù),僅為1或0
|
count
|
當(dāng)前數(shù)
|
產(chǎn)品計數(shù)
|
整數(shù)(無小數(shù)部分)
|
diff
|
差數(shù)
|
產(chǎn)品計數(shù)
|
整數(shù)(無小數(shù)部分
|
want
|
目標(biāo)數(shù)
|
產(chǎn)品計數(shù)
|
整數(shù)(無小數(shù)部分
|
ms1
|
測量到的實(shí)際值1
|
尺寸測量
|
實(shí)數(shù)
|
ws1
|
目標(biāo)尺寸的標(biāo)準(zhǔn)值1
|
尺寸測量
|
實(shí)數(shù)
|
dif1
|
誤差1
|
尺寸測量
|
實(shí)數(shù)
|
ms2
|
測量到的實(shí)際值2
|
尺寸測量
|
實(shí)數(shù)
|
ws2
|
目標(biāo)尺寸的標(biāo)準(zhǔn)值2
|
尺寸測量
|
實(shí)數(shù)
|
dif2
|
誤差2
|
尺寸測量
|
實(shí)數(shù)
|
ms3
|
測量到的實(shí)際值3
|
尺寸測量
|
實(shí)數(shù)
|
ws3
|
目標(biāo)尺寸的標(biāo)準(zhǔn)值3
|
尺寸測量
|
實(shí)數(shù)
|
dif3
|
誤差3
|
尺寸測量
|
實(shí)數(shù)
|
ms4
|
測量到的實(shí)際值4
|
尺寸測量
|
實(shí)數(shù)
|
ws4
|
目標(biāo)尺寸的標(biāo)準(zhǔn)值4
|
尺寸測量
|
實(shí)數(shù)
|
dif4
|
誤差4
|
尺寸測量
|
實(shí)數(shù)
|
最后,以一個實(shí)際檢測的一個腳本結(jié)束本文。如下:
cnt = sight2.blob1.cnt
if cnt ~= 5 then
mvs.good = 0
mvs.ng =1
return
end
for i=1,5 do
if sight2.blob1.w[i] <25 then
mvs.good = 0
mvs.ng =1
return
end
if sight2.blob1.h[i] <12 then
mvs.good = 0
mvs.ng =1
return
end
end
mvs.good =1
mvs.ng =0
這個腳本算法解釋如下:如果sight2中的blob1的個數(shù)不是5個,那么將good設(shè)置為0,ng屬性設(shè)置為1后,直接返回。否則,逐個判斷其高度或?qū)挾,如果不合格則進(jìn)行相應(yīng)處理,然后返回。當(dāng)所有的blob寬度和高度完全合格以后,將good設(shè)為1,ng設(shè)為0,然后返回。
|