http://casecurityhq.com 2023-05-12 11:06 深圳市正運(yùn)動(dòng)技術(shù)有限公司
此前,我們依次講解了軟硬件介紹及計(jì)數(shù)實(shí)例、相機(jī)的基本使用、基于形狀匹配的視覺(jué)定位、BLOB有無(wú)檢測(cè)、測(cè)量尺寸、機(jī)器視覺(jué)方案中使用到的標(biāo)定功能以及使用ZDevelop軟件實(shí)現(xiàn)坐標(biāo)標(biāo)定的方法。
本期課程我們繼續(xù)和大家一起分享使用ZDevelop軟件實(shí)現(xiàn)一維碼和二維碼的識(shí)別功能。
視頻教程:《VPLC系列機(jī)器視覺(jué)運(yùn)動(dòng)控制一體機(jī)快速入門(mén)(七)》
條形碼是由不同的寬度、不同的反射率的條(黑色)和空(白色)組成的,根據(jù)特定的編碼規(guī)則編制,用于表達(dá)一組數(shù)字、字母信息的圖形標(biāo)識(shí)符。
條形碼可以標(biāo)出商品的生產(chǎn)國(guó)、制造廠家、商品名稱、生產(chǎn)日期、圖書(shū)分類號(hào)、類別、日期等信息,因而在商品流通、圖書(shū)管理、銀行系統(tǒng)、生產(chǎn)制造等許多領(lǐng)域都得到了廣泛的應(yīng)用。
二維碼是用某種特定的幾何圖形按一定規(guī)律在平面(二維方向上)分布的、黑白相間的、記錄數(shù)據(jù)符號(hào)信息的圖形。在代碼編制上巧妙地利用構(gòu)成計(jì)算機(jī)內(nèi)部邏輯基礎(chǔ)的“0”、“1”比特流的概念,使用若干個(gè)與二進(jìn)制相對(duì)應(yīng)的幾何形體來(lái)表示文字?jǐn)?shù)值信息,通過(guò)圖像輸入設(shè)備或光電掃描設(shè)備自動(dòng)識(shí)讀以實(shí)現(xiàn)信息自動(dòng)處理。
二維碼技術(shù)是在計(jì)算機(jī)技術(shù)與信息技術(shù)基礎(chǔ)上發(fā)展起來(lái)的一門(mén)集編碼、印刷、識(shí)別、數(shù)據(jù)采集和處理于一身的新興技術(shù),它解決了條形碼表達(dá)信息有限的問(wèn)題。
一維條形碼只能在一個(gè)方向上(一般是水平方向)存儲(chǔ)表達(dá)信息,只能存儲(chǔ)數(shù)字和字母;二維碼在水平和垂直兩個(gè)方向上均能存儲(chǔ)表達(dá)信息,它可以存儲(chǔ)更多的信息包括數(shù)字、字母、漢字、圖片、音頻、視頻等。
條形碼需要按照一定規(guī)則的編碼方式將條和空進(jìn)行不同的排列用于表示不同的信息;二維碼需要按照一定的編碼規(guī)律使用黑白塊在水平方向和垂直方向進(jìn)行排列,用于表達(dá)不同的信息。它們都依賴于特定的編碼規(guī)則---編碼碼制,才能準(zhǔn)確實(shí)現(xiàn)信息的存儲(chǔ)和表達(dá)。
正是由于條形碼和二維碼在日常生活和工業(yè)生產(chǎn)等多種領(lǐng)域中被廣泛應(yīng)用到,因此在自動(dòng)化生產(chǎn)制造業(yè)中需要自動(dòng)檢測(cè)識(shí)別條形碼和二維碼的內(nèi)容,對(duì)識(shí)別的內(nèi)容進(jìn)行判斷,比如根據(jù)判斷條形碼和檢測(cè)的字符是否一致來(lái)最終判斷產(chǎn)品包裝的信息的準(zhǔn)確性;比如,通過(guò)識(shí)別二維碼的內(nèi)容,導(dǎo)入對(duì)應(yīng)產(chǎn)品的信息。
機(jī)器視覺(jué)是常用于自動(dòng)化生產(chǎn)制造行業(yè)的一門(mén)自動(dòng)檢測(cè)技術(shù),它根據(jù)條形碼和二維碼的編碼原理也相應(yīng)生成了對(duì)應(yīng)的識(shí)別算法,可應(yīng)用于自動(dòng)檢測(cè)識(shí)別條形碼和二維碼。
識(shí)別流程圖
演示實(shí)例說(shuō)明:本課程實(shí)例將演示使用ZDevelop軟件識(shí)別常用條形碼和二維碼的類型。
1.打開(kāi)ZDevelop軟件:新建項(xiàng)目→新建HMI文件→新建main.bas文件,用于編寫(xiě)界面響應(yīng)函數(shù)→新建global_variable.bas文件用于存放全局變量并開(kāi)啟HMI自動(dòng)運(yùn)行任務(wù)→新建identify.bas文件用于初始化測(cè)量參數(shù)→新建camera.bas文件用于實(shí)現(xiàn)相機(jī)采集功能→新建draw.bas文件用于更新繪制檢測(cè)區(qū)域ROI刷新界面→文件添加到項(xiàng)目。
2.設(shè)計(jì)HMI文件界面。
3.在global_variable.bas文件中定義全局變量。
'''''全局變量大部分使用數(shù)組結(jié)構(gòu)'''''
''注:basic編程中很多函數(shù)會(huì)以TABLE(系統(tǒng)的數(shù)據(jù)結(jié)構(gòu))做為參數(shù)
''在這里table均是做為中間變量
''table 0-10 作為中間變量使用
''table 11-15,區(qū)域ROI參數(shù),參數(shù)位置與dd_identfy_param對(duì)應(yīng),控件坐標(biāo)系
''table 21-22,鼠標(biāo)按鍵,控件坐標(biāo)系
''table 31-35,控件坐標(biāo)轉(zhuǎn)換后對(duì)應(yīng)的圖像坐標(biāo),圖像坐標(biāo)系
'主任務(wù)狀態(tài)
'0 - 未初始化
'1 - 停止
'2 - 運(yùn)行中
'3 - 正在停止
GLOBAL DIM main_task_state
main_task_state = 1
'采集開(kāi)關(guān)
'0 - 停止采集
'1 - 請(qǐng)求采集
GLOBAL DIM grab_switch
grab_switch = 0
'相機(jī)個(gè)數(shù)
GLOBAL cam_num
cam_num = 0
'相機(jī)種類,""
GLOBAL DIM CAMERA_TYPE(100)
'CAMERA_TYPE = "zmotion;mindvision;basler;mvision;huaray"
CAMERA_TYPE = "mvision"
' 任務(wù)號(hào)劃分, 主任務(wù)id - 10
GLOBAL DIM main_task_id
main_task_id = 10
'連續(xù)采集線程id - 9
GLOBAL DIM grab_task_id
grab_task_id = 9
'目前不能作為函數(shù)參數(shù),故使用全局變量表示
GLOBAL ZVOBJECT grabImg
'常用顏色變量
GLOBAL C_RED, C_GREEN, C_BLUE, C_YELLOW
C_RED = RGB(255,0,0)
C_GREEN = RGB(0,255,0)
C_BLUE = RGB(0,0,255)
C_YELLOW= RGB(255,255,0)
'數(shù)據(jù)碼識(shí)別參數(shù)數(shù)組,依次為中心cx、cy、w、h、angle、data_code_type、step
GLOBAL DIM d_identfy_param(7) 'd開(kāi)頭表示數(shù)據(jù)結(jié)構(gòu)
'識(shí)別消耗時(shí)間
GLOBAL DIM d_identfy_time
d_identfy_time = 0
'是否使用roi,0-不使用,不使用時(shí)就用全圖進(jìn)行識(shí)別數(shù)據(jù)碼,1-使用時(shí)就用roi區(qū)域截取圖像用來(lái)識(shí)別數(shù)據(jù)碼
GLOBAL DIM d_useRoi
d_useRoi = 0
'條碼類型
GLOBAL DIM code_type
code_type = 0
'識(shí)別結(jié)果,結(jié)果存儲(chǔ)方式為:類型:結(jié)果,如EAN-13:123456789
GLOBAL DIM d_identfy_rst(256)
RUN "Hmi.hmi",1
4.在HMI界面的元件中關(guān)聯(lián)變量。
5.在identify.bas文件中初始化測(cè)量參數(shù)。
end
GLOBAL SUB init_param() '初始化測(cè)量參數(shù)
'初始化測(cè)量參數(shù)
d_identfy_param(0) = 320.0 'roi中心x
d_identfy_param(1) = 240.0 'roi中心y
d_identfy_param(2) = 160 'roi寬
d_identfy_param(3) = 120.0 'roi高
d_identfy_param(4) = 0.0 'roi角度
d_identfy_param(5) = 0 '條碼類型為自動(dòng)
d_identfy_param(6) = 4 '掃描步長(zhǎng)
END SUB
6.在main.bas文件中添加初始化函數(shù)并在HMI編輯設(shè)置中關(guān)聯(lián)函數(shù)名。
'HMI界面初始化函數(shù)
GLOBAL SUB hmi_init()
grab_switch = 0
main_task_state = 1
init_param() '初始化測(cè)量參數(shù)
ZV_RESETCLIPSIZE(1280, 1024) '初始化時(shí)依據(jù)圖像分辨率設(shè)置區(qū)域的裁剪尺寸,此處圖像分辨率為1280x1024
ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 5), HMI_CONTROLSIZEY(10, 5)) '設(shè)置鎖存的大小
ZV_LATCHCLEAR(0)
'將檢測(cè)測(cè)量器ROI的圖像坐標(biāo)數(shù)據(jù)轉(zhuǎn)到控件坐標(biāo)數(shù)據(jù)
TABLE(11, d_identfy_param(0), d_identfy_param(1))
ZV_POSFROMIMG(0, 1, 11, 11) '圖像坐標(biāo)轉(zhuǎn)換到HMI控件坐標(biāo)
TABLE(13) = ZV_LENFROMIMG(0, d_identfy_param(2))
TABLE(14) = ZV_LENFROMIMG(0, d_identfy_param(3))
TABLE(15) = d_identfy_param(4)
END SUB
7.在camera.bas文件中添加采集操作相關(guān)函數(shù),并關(guān)聯(lián)動(dòng)作函數(shù)名。
end
'HMI界面按下掃描相機(jī)按鈕時(shí)響應(yīng)的函數(shù)
GLOBAL SUB cam_scan_all()
ZV_SETSYSINT("LogLevel", 7)
ZV_SETSYSSTR("DataDir","")
'掃描相機(jī)
CAM_SCAN(CAMERA_TYPE)
cam_num = CAM_COUNT()
?"cam_num = " cam_num
if (0 = cam_num) then
?"未找到相機(jī)"
' ZV_READIMAGE(grabImg, "QR.png", 1)
return
endif
'掃描到有相機(jī)就對(duì)一些相機(jī)參數(shù)進(jìn)行設(shè)置
if cam_num > 0 then
CAM_SEL(0)
CAM_SETEXPOSURE(5000)
CAM_SETPARAM("GevSCPD", "3000")
CAM_SETPARAM("GevHeartbeatTimeout", "3000")
CAM_SETMODE(0)'設(shè)置觸發(fā)模式為軟觸發(fā)
CAM_START(0)'開(kāi)始采集
endif
END SUB
'HMI界面按下單次采集按鈕時(shí)響應(yīng)的函數(shù)
GLOBAL SUB btn_grab()
if cam_num=0 then
?"請(qǐng)先掃描相機(jī)!"
return
endif
CAM_SETPARAM("TriggerSoftware", 0)
CAM_GET(grabImg, 0)
ZV_LATCH(grabImg, 0) '將帶顯示的圖像轉(zhuǎn)換到鎖存通道指定的鎖存區(qū)域
END SUB
'HMI界面按下連續(xù)采集按鈕時(shí)響應(yīng)的函數(shù)
GLOBAL SUB btn_mea_cgrab()
if cam_num=0 then
?"請(qǐng)先掃描相機(jī)!"
return
endif
grab_switch = 1
if (1 = grab_switch) then
if (0 = PROC_STATUS(grab_task_id)) then
RUNTASK grab_task_id, grab_task
endif
endif
END SUB
'HMI界面按下停止采集按鈕時(shí)響應(yīng)的函數(shù)
GLOBAL SUB btn_mea_stopCgrab()
grab_switch = 0
END SUB
'連續(xù)采集任務(wù)
grab_task:
while(1)
if (0 = grab_switch) then
exit while
endif
btn_grab()
wend
END
8.在draw.bas文件中添加更新繪制Roi函數(shù),并在自定義元件屬性窗口關(guān)聯(lián)刷新函數(shù)和繪圖函數(shù)。
end
'和繪制(即選擇ROI)有關(guān)的界面的刷新繪制函數(shù)放在這個(gè)bas文件里
DIM is_redraw
is_redraw = 0
DIM set_roi_open_init
set_roi_open_init = 0
DIM sr_mpos_x, sr_mpos_y, hit_pos
'根據(jù)鼠標(biāo)操作更新檢測(cè)區(qū)域ROI的坐標(biāo)位置和形狀大小
GLOBAL SUB update_identfy()
if mouse_scan(21) = 1 then '掃描按下操作
hit_pos = ZV_HMIADJRECT2(table(21), table(22), 11, -1) '只有按下時(shí)可以改變擊中位置
is_redraw = 1
endif
if mouse_scan(21) = -1 then '掃描松開(kāi)操作
ZV_HMIADJRECT2(table(21), table(22), 11, hit_pos)
is_redraw = 1
endif
if (MOUSE_state(21)) then
ZV_HMIADJRECT2(table(21), table(22), 11, hit_pos)
is_redraw = 1
endif
if (1 = is_redraw) then
'控件roi坐標(biāo)轉(zhuǎn)圖像roi坐標(biāo)
is_redraw = 0
ZV_POSTOIMG(0,2, 11, 0) 'TABLE(0)作為中間變量臨時(shí)使用
d_identfy_param(0) = TABLE(0)
d_identfy_param(1) = TABLE(1)
d_identfy_param(2) = ZV_LENTOIMG(0, TABLE(2))
d_identfy_param(3) = ZV_LENTOIMG(0, TABLE(3))
d_identfy_param(4) = TABLE(4)
SET_REDRAW
endif
SET_REDRAW
END SUB
'更新ROI位置和大小后實(shí)時(shí)繪制ROI區(qū)域
GLOBAL SUB draw_identfy()
if d_useRoi =1 then
SET_COLOR(C_BLUE)
TABLE(16, 0, 0) '對(duì)子區(qū)域?qū)挾群蛡€(gè)數(shù)兩個(gè)參數(shù)清零
ZV_HMIRECT2(11, 300)
DRAWLINE(TABLE(300), TABLE(301), TABLE(302), TABLE(303)) '外矩形
DRAWLINE(TABLE(302), TABLE(303), TABLE(304), TABLE(305))
DRAWLINE(TABLE(304), TABLE(305), TABLE(306), TABLE(307))
DRAWLINE(TABLE(306), TABLE(307), TABLE(300), TABLE(301))
DRAWLINE(TABLE(308), TABLE(309), TABLE(310), TABLE(311)) '方向箭頭
DRAWLINE(TABLE(312), TABLE(313), TABLE(310), TABLE(311))
DRAWLINE(TABLE(314), TABLE(315), TABLE(310), TABLE(311))
endif
END SUB
9.添加在HMI界面按下【測(cè)試】按鈕時(shí)響應(yīng)的函數(shù),并關(guān)聯(lián)動(dòng)作函數(shù)名。
'HMI界面按下測(cè)試按鈕時(shí)響應(yīng)的函數(shù)
GLOBAL SUB btn_identfy_test()
'開(kāi)始識(shí)別
TICKS = 0
DIM tmp1(64),tmp2(64)
ZVOBJECT grayImg, codeList, codeRst
if ZV_IMGCNS(grabImg) > 1 then '獲取圖像通道數(shù),單通道表示灰度圖
ZV_RGBTOGRAY(grabImg,grayImg)
else
ZV_COPY(grabImg,grayImg) '復(fù)制grabImg圖像到grayImg圖像中
endif
code_type = d_identfy_param(5)
if code_type = 7 then '如果在界面中選擇QR碼類型
code_type = 20
elseif code_type = 8 then '如果在界面中選擇DM碼類型
code_type = 21
endif
ZV_CLEAR(codeList)
ZV_CODEREAD(grayImg,codeList,code_type,d_identfy_param(6))
if ZV_LISTCOUNT(codeList) > 0 then '獲取列表中元素的數(shù)量
ZV_LISTGET(codeList,codeRst,0) '取出第一個(gè)條碼結(jié)果作為顯示
ZV_CODETYPESTR(codeRst,64,100) '獲取數(shù)據(jù)碼類型并將其存入起始索引為100的TABLE中
DMCPY tmp1(0),TABLE(100),64 '將TABLE中的數(shù)組拷貝至tmp1中
ZV_CODESTR(codeRst,64,100) '獲取數(shù)據(jù)碼結(jié)果并將其存入起始索引為100的TABLE中
DMCPY tmp2(0), TABLE(100), 64 '將TABLE中的數(shù)組拷貝至tmp2中
d_identfy_rst = tmp1 + ":"tmp2 '顯示識(shí)別結(jié)果為 數(shù)據(jù)碼類型:數(shù)據(jù)碼結(jié)果
else
d_identfy_rst = "identify fail!"
endif
d_identfy_time = abs(TICKS) '識(shí)別時(shí)間
END SUB
10.添加在HMI界面按下【運(yùn)行】按鈕時(shí)響應(yīng)的函數(shù),并關(guān)聯(lián)動(dòng)作函數(shù)名。
'HMI界面按下運(yùn)行按鈕時(shí)響應(yīng)的函數(shù)
GLOBAL SUB btn_run()
if (1 = main_task_state) then
if (0 = PROC_STATUS(main_task_id)) then
main_task_state = 2
RUNTASK main_task_id, main_task
endif
endif
END SUB
'主任務(wù)執(zhí)行的函數(shù)
main_task:
while(1)
if (3 = main_task_state) then
main_task_state = 1
exit while
endif
if cam_num = 0 then
btn_stop()
return
endif
'持續(xù)采集圖像,對(duì)圖像進(jìn)行操作
btn_grab()
btn_identfy_test()
wend
END
11.添加在HMI界面按下【停止】按鈕時(shí)響應(yīng)的函數(shù),并關(guān)聯(lián)動(dòng)作函數(shù)名。
'HMI界面按下停止按鈕時(shí)響應(yīng)的函數(shù)
GLOBAL SUB btn_stop()
if (2 = main_task_state) then
main_task_state = 3
endif
END SUB
EAN-13碼
本次,正運(yùn)動(dòng)技術(shù)VPLC系列機(jī)器視覺(jué)運(yùn)動(dòng)控制一體機(jī)快速入門(mén)(七)——使用ZDevelop軟件實(shí)現(xiàn)一維碼和二維碼的識(shí)別功能就分享到這里,更多精彩內(nèi)容請(qǐng)關(guān)注“正運(yùn)動(dòng)小助手”公眾號(hào)。
本文由正運(yùn)動(dòng)技術(shù)原創(chuàng),歡迎大家轉(zhuǎn)載,共同學(xué)習(xí),一起提高中國(guó)智能制造水平。文章版權(quán)歸正運(yùn)動(dòng)技術(shù)所有,如有轉(zhuǎn)載請(qǐng)注明文章來(lái)源。