此前,我們依次講解了軟硬件介紹及計數實例、相機的基本使用、基于形狀匹配的視覺定位、BLOB有無檢測、測量尺寸、機器視覺方案中使用到的標定功能以及使用ZDevelop軟件實現坐標標定的方法。
本期課程我們繼續和大家一起分享使用ZDevelop軟件實現一維碼和二維碼的識別功能。
條形碼是由不同的寬度、不同的反射率的條(黑色)和空(白色)組成的,根據特定的編碼規則編制,用于表達一組數字、字母信息的圖形標識符。
條形碼可以標出商品的生產國、制造廠家、商品名稱、生產日期、圖書分類號、類別、日期等信息,因而在商品流通、圖書管理、銀行系統、生產制造等許多領域都得到了廣泛的應用。
二維碼是用某種特定的幾何圖形按一定規律在平面(二維方向上)分布的、黑白相間的、記錄數據符號信息的圖形。在代碼編制上巧妙地利用構成計算機內部邏輯基礎的“0”、“1”比特流的概念,使用若干個與二進制相對應的幾何形體來表示文字數值信息,通過圖像輸入設備或光電掃描設備自動識讀以實現信息自動處理。
二維碼技術是在計算機技術與信息技術基礎上發展起來的一門集編碼、印刷、識別、數據采集和處理于一身的新興技術,它解決了條形碼表達信息有限的問題。
一維條形碼只能在一個方向上(一般是水平方向)存儲表達信息,只能存儲數字和字母;二維碼在水平和垂直兩個方向上均能存儲表達信息,它可以存儲更多的信息包括數字、字母、漢字、圖片、音頻、視頻等。
條形碼需要按照一定規則的編碼方式將條和空進行不同的排列用于表示不同的信息;二維碼需要按照一定的編碼規律使用黑白塊在水平方向和垂直方向進行排列,用于表達不同的信息。它們都依賴于特定的編碼規則---編碼碼制,才能準確實現信息的存儲和表達。
正是由于條形碼和二維碼在日常生活和工業生產等多種領域中被廣泛應用到,因此在自動化生產制造業中需要自動檢測識別條形碼和二維碼的內容,對識別的內容進行判斷,比如根據判斷條形碼和檢測的字符是否一致來最終判斷產品包裝的信息的準確性;比如,通過識別二維碼的內容,導入對應產品的信息。
機器視覺是常用于自動化生產制造行業的一門自動檢測技術,它根據條形碼和二維碼的編碼原理也相應生成了對應的識別算法,可應用于自動檢測識別條形碼和二維碼。
識別流程圖
演示實例說明:本課程實例將演示使用ZDevelop軟件識別常用條形碼和二維碼的類型。
1.打開ZDevelop軟件:新建項目→新建HMI文件→新建main.bas文件,用于編寫界面響應函數→新建global_variable.bas文件用于存放全局變量并開啟HMI自動運行任務→新建identify.bas文件用于初始化測量參數→新建camera.bas文件用于實現相機采集功能→新建draw.bas文件用于更新繪制檢測區域ROI刷新界面→文件添加到項目。
2.設計HMI文件界面。
3.在global_variable.bas文件中定義全局變量。
'''''全局變量大部分使用數組結構'''''
''注:basic編程中很多函數會以TABLE(系統的數據結構)做為參數
''在這里table均是做為中間變量
''table 0-10 作為中間變量使用
''table 11-15,區域ROI參數,參數位置與dd_identfy_param對應,控件坐標系
''table 21-22,鼠標按鍵,控件坐標系
''table 31-35,控件坐標轉換后對應的圖像坐標,圖像坐標系
'主任務狀態
'0 - 未初始化
'1 - 停止
'2 - 運行中
'3 - 正在停止
GLOBAL DIM main_task_state
main_task_state = 1
'采集開關
'0 - 停止采集
'1 - 請求采集
GLOBAL DIM grab_switch
grab_switch = 0
'相機個數
GLOBAL cam_num
cam_num = 0
'相機種類,""
GLOBAL DIM CAMERA_TYPE(100)
'CAMERA_TYPE = "zmotion;mindvision;basler;mvision;huaray"
CAMERA_TYPE = "mvision"
' 任務號劃分, 主任務id - 10
GLOBAL DIM main_task_id
main_task_id = 10
'連續采集線程id - 9
GLOBAL DIM grab_task_id
grab_task_id = 9
'目前不能作為函數參數,故使用全局變量表示
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)
'數據碼識別參數數組,依次為中心cx、cy、w、h、angle、data_code_type、step
GLOBAL DIM d_identfy_param(7) 'd開頭表示數據結構
'識別消耗時間
GLOBAL DIM d_identfy_time
d_identfy_time = 0
'是否使用roi,0-不使用,不使用時就用全圖進行識別數據碼,1-使用時就用roi區域截取圖像用來識別數據碼
GLOBAL DIM d_useRoi
d_useRoi = 0
'條碼類型
GLOBAL DIM code_type
code_type = 0
'識別結果,結果存儲方式為:類型:結果,如EAN-13:123456789
GLOBAL DIM d_identfy_rst(256)
RUN "Hmi.hmi",1
4.在HMI界面的元件中關聯變量。
5.在identify.bas文件中初始化測量參數。
end
GLOBAL SUB init_param() '初始化測量參數
'初始化測量參數
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_identfy_param(6) = 4 '掃描步長
END SUB
6.在main.bas文件中添加初始化函數并在HMI編輯設置中關聯函數名。
'HMI界面初始化函數
GLOBAL SUB hmi_init()
grab_switch = 0
main_task_state = 1
init_param() '初始化測量參數
ZV_RESETCLIPSIZE(1280, 1024) '初始化時依據圖像分辨率設置區域的裁剪尺寸,此處圖像分辨率為1280x1024
ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 5), HMI_CONTROLSIZEY(10, 5)) '設置鎖存的大小
ZV_LATCHCLEAR(0)
'將檢測測量器ROI的圖像坐標數據轉到控件坐標數據
TABLE(11, d_identfy_param(0), d_identfy_param(1))
ZV_POSFROMIMG(0, 1, 11, 11) '圖像坐標轉換到HMI控件坐標
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文件中添加采集操作相關函數,并關聯動作函數名。
end
'HMI界面按下掃描相機按鈕時響應的函數
GLOBAL SUB cam_scan_all()
ZV_SETSYSINT("LogLevel", 7)
ZV_SETSYSSTR("DataDir","")
'掃描相機
CAM_SCAN(CAMERA_TYPE)
cam_num = CAM_COUNT()
?"cam_num = " cam_num
if (0 = cam_num) then
?"未找到相機"
' ZV_READIMAGE(grabImg, "QR.png", 1)
return
endif
'掃描到有相機就對一些相機參數進行設置
if cam_num > 0 then
CAM_SEL(0)
CAM_SETEXPOSURE(5000)
CAM_SETPARAM("GevSCPD", "3000")
CAM_SETPARAM("GevHeartbeatTimeout", "3000")
CAM_SETMODE(0)'設置觸發模式為軟觸發
CAM_START(0)'開始采集
endif
END SUB
'HMI界面按下單次采集按鈕時響應的函數
GLOBAL SUB btn_grab()
if cam_num=0 then
?"請先掃描相機!"
return
endif
CAM_SETPARAM("TriggerSoftware", 0)
CAM_GET(grabImg, 0)
ZV_LATCH(grabImg, 0) '將帶顯示的圖像轉換到鎖存通道指定的鎖存區域
END SUB
'HMI界面按下連續采集按鈕時響應的函數
GLOBAL SUB btn_mea_cgrab()
if cam_num=0 then
?"請先掃描相機!"
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界面按下停止采集按鈕時響應的函數
GLOBAL SUB btn_mea_stopCgrab()
grab_switch = 0
END SUB
'連續采集任務
grab_task:
while(1)
if (0 = grab_switch) then
exit while
endif
btn_grab()
wend
END
8.在draw.bas文件中添加更新繪制Roi函數,并在自定義元件屬性窗口關聯刷新函數和繪圖函數。
end
'和繪制(即選擇ROI)有關的界面的刷新繪制函數放在這個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
'根據鼠標操作更新檢測區域ROI的坐標位置和形狀大小
GLOBAL SUB update_identfy()
if mouse_scan(21) = 1 then '掃描按下操作
hit_pos = ZV_HMIADJRECT2(table(21), table(22), 11, -1) '只有按下時可以改變擊中位置
is_redraw = 1
endif
if mouse_scan(21) = -1 then '掃描松開操作
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坐標轉圖像roi坐標
is_redraw = 0
ZV_POSTOIMG(0,2, 11, 0) 'TABLE(0)作為中間變量臨時使用
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位置和大小后實時繪制ROI區域
GLOBAL SUB draw_identfy()
if d_useRoi =1 then
SET_COLOR(C_BLUE)
TABLE(16, 0, 0) '對子區域寬度和個數兩個參數清零
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界面按下【測試】按鈕時響應的函數,并關聯動作函數名。
'HMI界面按下測試按鈕時響應的函數
GLOBAL SUB btn_identfy_test()
'開始識別
TICKS = 0
DIM tmp1(64),tmp2(64)
ZVOBJECT grayImg, codeList, codeRst
if ZV_IMGCNS(grabImg) > 1 then '獲取圖像通道數,單通道表示灰度圖
ZV_RGBTOGRAY(grabImg,grayImg)
else
ZV_COPY(grabImg,grayImg) '復制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 '獲取列表中元素的數量
ZV_LISTGET(codeList,codeRst,0) '取出第一個條碼結果作為顯示
ZV_CODETYPESTR(codeRst,64,100) '獲取數據碼類型并將其存入起始索引為100的TABLE中
DMCPY tmp1(0),TABLE(100),64 '將TABLE中的數組拷貝至tmp1中
ZV_CODESTR(codeRst,64,100) '獲取數據碼結果并將其存入起始索引為100的TABLE中
DMCPY tmp2(0), TABLE(100), 64 '將TABLE中的數組拷貝至tmp2中
d_identfy_rst = tmp1 + ":"tmp2 '顯示識別結果為 數據碼類型:數據碼結果
else
d_identfy_rst = "identify fail!"
endif
d_identfy_time = abs(TICKS) '識別時間
END SUB
10.添加在HMI界面按下【運行】按鈕時響應的函數,并關聯動作函數名。
'HMI界面按下運行按鈕時響應的函數
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
'主任務執行的函數
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
'持續采集圖像,對圖像進行操作
btn_grab()
btn_identfy_test()
wend
END
11.添加在HMI界面按下【停止】按鈕時響應的函數,并關聯動作函數名。
'HMI界面按下停止按鈕時響應的函數
GLOBAL SUB btn_stop()
if (2 = main_task_state) then
main_task_state = 3
endif
END SUB
-
機器視覺
+關注
關注
161文章
4348瀏覽量
120134 -
人工智能
+關注
關注
1791文章
46896瀏覽量
237670 -
條碼識別
+關注
關注
0文章
28瀏覽量
7125 -
工廠自動化
+關注
關注
1文章
45瀏覽量
17187 -
正運動技術
+關注
關注
0文章
97瀏覽量
334
發布評論請先 登錄
相關推薦
評論