發布日期:2022-04-25 點擊率:36
關鍵詞:正運動技術,機器視覺,運動控制一體機
摘要:在實際的機器視覺應用項目中,常常需要提取產品的輪廓信息進行進一步的加工處理。在本次的課程中,我們將使用ZDevelop軟件來演示提取目標輪廓的功能。
在實際的機器視覺應用項目中,常常需要提取產品的輪廓信息進行進一步的加工處理。在本次的課程中,我們將使用ZDevelop軟件來演示提取目標輪廓的功能。
一檢測原理及應用場景
(一)檢測原理
提取輪廓也是基于邊緣輪廓的算法。它是在輸入的單通道圖像中,獲取梯度值大于設置的梯度閾值、連接的輪廓長度大于最小輪廓長度的所有輪廓點并輸出輪廓點對應的位置坐標數據。
(二)應用場景
1.提取產品的輪廓特征進行加工,如鞋底點膠,根據特定形狀裁切布藝等。
2.提取產品的外輪廓作為檢測區域對產品進行外觀檢測。
二軟件演示
(一)流程圖
(二)實例演示
1.打開ZDevelop軟件:新建項目→新建HMI文件→新建main.bas文件,用于編寫界面響應函數→新建global_variable.bas文件用于定義和初始化全局變量并開啟HMI自動運行任務→新建camera.bas文件用于實現相機采集功能→新建draw.bas文件用于更新繪制圖形刷新界面→文件添加到項目。
2.設計HMI啟動界面。
3.在global_variable.bas文件中定義并初始化全局變量,定義完成后運行Hmi.hmi文件。
'''''全局變量大部分使用數組結構'''''
''注:basic編程中很多函數會以TABLE(系統的數據結構)做為參數
''table 說明 table 說明
''11~12 鼠標操作時獲取的坐標 15~18 提取輪廓ROI圖像坐標數據
''25~28 提取輪廓ROI控件坐標數據 40 輪廓點數量
''50~50+輪廓數量*2 指定輪廓的輪廓點坐標
'***********定義程序任務相關變量**********************
'主任務狀態
'0 - 未初始化
'1 - 停止
'2 - 運行中
'3 - 正在停止
GLOBAL DIM main_task_state
main_task_state = 1
'運行任務開關
GLOBAL DIM run_switch
run_switch = 0
'采集任務開關
'0 - 停止采集
'1 - 請求采集
GLOBAL DIM grab_switch
grab_switch = 0
'定位檢測主任務id - 10
GLOBAL DIM main_task_id
main_task_id = 10
'相機連續采集線程id - 7
GLOBAL DIM grab_task_id
grab_task_id = 7
'***********結束定義程序任務相關變量******************
'***********定義相機采集相關變量**********************
'相機種類,此處使用海康相機-"mvision"
GLOBAL DIM CAMERA_TYPE(100)
'CAMERA_TYPE = "mindvision;basler;mvision;huaray;zmotion"
CAMERA_TYPE = "mvision"
'相機個數
GLOBAL cam_num
cam_num = 0
'相機模式,-1 連續采集,0-軟件觸發采集
GLOBAL cam_mode
cam_mode = 0
'***********結束定義相機采集相關變量******************
'定義使用ROI標志,1-使用ROI,0-使用全圖像區域
GLOBAL DIM d_roi_arc_flag
d_roi_arc_flag = 0
'定義鼠標按下標志位,1-已按下,0-未按下
GLOBAL DIM is_set_roi_m_down
is_set_roi_m_down = 0
GLOBAL DIM d_detect_time '定義消耗的時間變量
d_detect_time = 0
'定義程序執行過程中采集的圖像變量、二值化圖像變量、顯示圖像變量、提取到的輪廓列表
GLOBAL ZVOBJECT grabImg,binImg,colorImg,contlist
'定義最小輪廓長度
GLOBAL DIM minLength
minLength=1700 '默認提取輪廓最小長度為1700像素
'定義提取到輪廓的數量
GLOBAL DIM count
count=0
'定義保存參數標志
GLOBAL DIM d_is_saved
'定義提取輪廓的ROI區域
GLOBAL DIM d_learn_roi(4)
d_learn_roi(0)=180
d_learn_roi(1)=110
d_learn_roi(2)=380
d_learn_roi(3)=310
TABLE(25) = d_learn_roi(0) '將矩形ROI數據存放到起始地址為25的table數組中
TABLE(26) = d_learn_roi(1)
TABLE(27) = d_learn_roi(2)
TABLE(28) = d_learn_roi(3)
'常用顏色變量
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)
'***********定義讀取本地文件功能相關變量**************
''注意,該功能只在使用仿真器時有效
'定義是否使用本地圖片標志
GLOBAL DIM d_use_imgfile
d_use_imgfile=1
'定義本地圖片索引
GLOBAL DIM d_index
'定義讀取圖片的路徑
GLOBAL DIM File_Name(100)
'***********結束定義讀取本地文件功能相關變量**********
'初始化全局變量完成后開啟HMI文件
RUN"Hmi1.hmi",1
4.關聯HMI啟動界面值控件變量。
5.在main.bas文件中添加HMI界面初始化函數并在Hmi系統設置中關聯初始化函數。
end
'注:
'凡是要使用Region有關的算子在系統初始化時都要調用ZV_RESETCLIPSIZE(width, height)這個算子設置下圖像尺寸,以滿足相機分辨率,因為默認的是640*480尺寸
'HMI界面初始化函數
GLOBAL SUB hmi_init()
grab_switch = 0 '停止采集
main_task_state = 1 '主任務停止運行
if(VR(7)=1)then '如果已保存參數
btn_LoadParam()
endif
ZV_RESETCLIPSIZE(1280, 960)'初始化時依據圖像分辨率設置區域的裁剪尺寸,此處圖像分辨率為1280x960
ZV_LATCHSETSIZE(0, HMI_ConTROLSIZEX(10, 1), HMI_ConTROLSIZEY(10, 1)) '設置鎖存的大小
ZV_SETSYSDBL("CamGetTimeout", 1000) '設置采集超時
ZV_LATCHCLEAR(0) '清空鎖存通道0
END SUB
'加載保存參數子程序
GLOBAL SUB btn_LoadParam()
'加載保存的參數
minLength=VR(0)
d_roi_arc_flag=VR(1)
d_learn_roi(0)=VR(2)
d_learn_roi(1)=VR(3)
d_learn_roi(2)=VR(4)
d_learn_roi(3)=VR(5)
d_use_imgfile =VR(6)
TABLE(25) = VR(9)
TABLE(26) = VR(10)
TABLE(27) = VR(11)
TABLE(28) = VR(12)
END SUB
6.在draw.bas文件中添加檢測ROI更新繪制函數,并在自定義元件屬性窗口中關聯刷新函數和繪制函數。
end
'和繪制(即選擇ROI)有關的界面的刷新繪制函數放在這個bas文件里
DIM is_redraw
is_redraw = 0
DIM hit_pos,sr_mpos_x ,sr_mpos_y
'根據鼠標操作更新訓練顏色樣本的有效區域
GLOBAL SUB update_roi()
if d_roi_arc_flag = 1 then '如果選擇ROI類型為矩形
if mouse_scan(11) = 1 then '掃描鼠標按下操作
is_set_roi_m_down = 1 '鼠標按下標志置1
sr_mpos_x = table(11) '將當前鼠標按下位置的坐標賦值給變量
sr_mpos_y = table(12)
'只有按下時可以改變擊中位置,獲取鼠標點擊位置對應的擊中區域編號
hit_pos = ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 25, -1)
is_redraw = 1 '繪圖標志置1
endif
if mouse_scan(11) = -1 then '掃描鼠標松開操作
is_set_roi_m_down = 0 '鼠標按下標志置0
sr_mpos_x = table(11) '將當前鼠標松開位置的坐標賦值給變量
sr_mpos_y = table(12)
'根據區域編號調整定位器區域位置
ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 25, hit_pos)
is_redraw = 1 '繪圖標志置1
endif
'如果鼠標按下時
if (is_set_roi_m_down and MOUSE_state(11)) then
sr_mpos_x = table(11) '將當前鼠標按下位置的坐標賦值給變量
sr_mpos_y = table(12)
'根據區域編號調整定位器區域位置
ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 25, hit_pos)
is_redraw = 1 '繪圖標志置1
endif
if (1 = is_redraw) then '如果繪制標志=1
is_redraw = 0 '將繪制標志置0
'控件roi坐標轉圖像roi坐標,控件坐標存放在起始地址為25的數組,圖像坐標存放在起始地址為15的數組
ZV_POSTOIMG(0, 2, 25, 15)
'將圖像坐標的數據賦值給ROI變量中
d_learn_roi(0) = TABLE(15)
d_learn_roi(1) = TABLE(16)
d_learn_roi(2) = TABLE(17)
d_learn_roi(3) = TABLE(18)
SET_REDRAW '重新繪制全部區域
endif
else
SET_REDRAW
endif
END SUB
'根據更新的鼠標位置坐標繪制訓練顏色樣本區域
GLOBAL SUB draw_roi()
if d_roi_arc_flag = 1 then '如果ROI類型為矩形
SET_COLOR(C_BLUE) '設置繪制時畫筆的顏色為藍色
'根據控件坐標數據繪制矩形
DRAWRECT(TABLE(25), TABLE(26), TABLE(27), TABLE(28))
local cx,cy '定義局部變量
cx = (TABLE(25) + TABLE(27)) / 2 '計算矩形的中心坐標x、y
cy = (TABLE(26) + TABLE(28)) / 2
DRAWLINE(cx-5, cy, cx+5, cy) '繪制中心十字線
DRAWLINE(cx, cy-5, cx, cy+5)
endif
END SUB
7.在camera.bas文件中添加HMI界面中采集相關按鈕響應的函數并關聯動作函數。
end
'主界面按下掃描相機按鈕時響應的函數
GLOBAL SUB cam_scan_all()
if(d_use_imgfile=1)then
?"請先按下使用本地圖片按鈕關閉該功能"
return
endif
ZV_SETSYSINT("LogLevel", 7) '設置控制器信息
ZV_SETSYSSTR("DataDir","")
CAM_SCAN(CAMERA_TYPE) '掃描相機,CAMERA_TYPE="mvision"
cam_num = CAM_COUNT() '獲取掃描到的相機數量
if (0 = cam_num) then '如果相機數量=0,打印提示信息
? "未找到相機"
return '退出子函數,不往下執行
endif
?"cam_num = " cam_num '如果掃描到相機,打印相機數量
cam_mode = 0 '設置軟觸發采集
CAM_SEL(0) '選擇掃描到的第一個相機進行操作
CAM_SETEXPOSURE(5000) '設置相機曝光時間為5000us
CAM_SETMODE(cam_mode) '設置軟件觸發模式
CAM_START(0) '開啟相機
END SUB
'主界面按下單次采集按鈕執行的函數
GLOBAL SUB btn_grab()
'如果d_use_imgfile=1時使用讀取本地圖片功能,使用控制器時請將此部分代碼注釋掉
if (d_use_imgfile=1) then
if(d_index=3) then
d_index=0
endif
File_Name="提取輪廓"+TOSTR(d_index,1,0)+".bmp" '.../flash/提取輪廓/目錄下的圖片所在的路徑名稱
ZV_IMGREAD(grabImg,File_Name,0)
ZV_LATCH(grabImg, 0)
d_index=d_index+1
return
endif
''讀取本地圖片功能結束
'如果相機數量為0,提示先掃描相機,并退出子函數不往下執行
if cam_num = 0 then
?"請先掃描相機!"
return
endif
CAM_SETPARAM("TriggerSoftware", 0) '發送觸發指令
CAM_GET(grabImg, 0) '獲取一幀圖像存放到grabImg變量中
ZV_LATCH(grabImg, 0) '將圖像顯示到鎖存通道0中
END SUB
'主界面按下連續采集按鈕響應的函數
GLOBAL SUB btn_cgrab()
if grab_switch =1 then '如果已經處于連續執行狀態,打印提示信息并退出函數
?"正在連續運行中,請勿重復操作!"
return
endif
if( d_use_imgfile =0) then '如果使用相機采集功能
if cam_num = 0 then '判斷如果相機數量=0,打印提示信息并退出函數
?"請先掃描相機!"
return
endif
endif
grab_switch = 1 '采集任務開關置1
if (1 = grab_switch) then
if (0 = PROC_STATUS(grab_task_id)) then
RUNTASK grab_task_id, grab_task '開啟連續采集任務
endif
endif
END SUB
'采集任務實現函數
grab_task:
while(1)
if (0 = grab_switch) then '如果采集任務開關=0即停止采集按鈕按下時
exit while '退出循環
endif
'grab_switch=1時重復執行以下操作
btn_grab()'單次采集按鈕響應的函數
wend
END
'主界面按下停止采集按鈕響應的函數
GLOBAL SUB btn_stopCgrab()
if grab_switch =0 then '如果已經處于停止采集狀態,打印提示信息并退出函數
?"未開啟連續采集!"
return
endif
grab_switch = 0 '將采集任務開關置0
END SUB
8.在main.bas文件中添加HMI界面按下【保存】按鈕時響應的函數并關聯動作函數名。
'HMI界面按下保存按鈕時響應的函數
GLOBAL SUB btn_SaveParam()
VR(0)=minLength
VR(1)=d_roi_arc_flag
VR(2)=d_learn_roi(0)
VR(3)=d_learn_roi(1)
VR(4)=d_learn_roi(2)
VR(5)=d_learn_roi(3)
VR(6)=d_use_imgfile
VR(9)=TABLE(25)
VR(10)= TABLE(26)
VR(11)=TABLE(27)
VR(12)=TABLE(28)
d_is_saved=1
VR(7)=d_is_saved
?"已成功保存參數"
END SUB
9.在main.bas文件中添加HMI界面按下【測試】按鈕響應的函數并關聯動作函數。
'定義HMI界面按下測試按鈕時響應的函數
GLOBAL SUB btn_test()
TICKS=0
ZVOBJECT regionMask,contour,genList,fragment
'生成ROI區域
if d_roi_arc_flag = 1 then '如果選擇的ROI類型是矩形
'根據ROI數據生成旋轉矩形區域
ZV_REGENRECT(regionMask,d_learn_roi(0),d_learn_roi(1),d_learn_roi(2)-d_learn_roi(0)+1,d_learn_roi(3)-d_learn_roi(1)+1) '生成矩形測量區域
else
'生成全圖像區域
ZV_REGENFULLIMG(grabImg,regionMask)
endif
ZV_CLEAR(contlist)
ZV_ConTGENSUBPIX(grabImg, regionMask,contlist,120,220,minLength) '從有效區域中提取最小輪廓長度為minLength的邊緣輪廓,并將提取的結果存于 list 列表中
ZV_GRAYTORGB(grabImg,colorImg)'將灰度圖轉換到RGB圖像,用于繪制檢測結果圖像
count = ZV_LISTCOUNT(contlist) '獲取列表中的數量
for i=0 to count-1
ZV_LISTGET(contlist,contour,i) '獲取列表中序號為i的元素
ZV_ConTCOUNT(contour,40) '獲取輪廓點的數量
ZV_ConTOUR(colorImg,contour,zv_color(0,255,0))
' '獲取輪廓點數據方法1,獲取所有輪廓點數據
' for j=0 to TABLE(40)-1
' ZV_ConTGETPT(contour,j,50) '指定輪廓中第i個點的坐標放到 TABLE (50)中
' next
'獲取輪廓點數據方法2,將輪廓分割成基元
ZV_CLEAR(genList)
ZV_ConTSEGMENT(contour,genList,0,1,1) '將輪廓分割成直線基元
DIM num
num=ZV_LISTCOUNT(genList)
for j=0 to num-1
ZV_LISTGET(genList,fragment,j) '獲取列表中序號為j的元素
ZV_ConTGETPARAM(fragment,64,50)'獲取輪廓基元類型和直線基元參數,包括基元類型,直線起始坐標x、y終點坐標x,y
ZV_LINE(colorImg,TABLE(51),TABLE(52),TABLE(53),TABLE(54),C_BLUE)'繪制輪廓分割后提取的效果
next
next
ZV_LATCH(colorImg,0)
d_detect_time=abs(TICKS)
END SUB
10.在main.bas文件中添加HMI界面按下【運行】按鈕響應的函數并關聯動作函數。
'主界面點擊運行按鈕時響應的函數
GLOBAL SUB btn_run()
if(run_switch = 1) then '如果已經開啟連續運行
?"已開啟連續運行,請勿重復操作!" '提示信息并退出子函數,不往下執行
return
endif
run_switch = 1 '主任務開關置1
if (1 = run_switch) then '如果主任務開關=1
if (0 = PROC_STATUS(main_task_id)) then '如果main_task_id任務未開啟
RUNTASK main_task_id, main_task '開啟main_task任務
endif
endif
END SUB
'主任務執行的內容
main_task:
while(1)
if (0 = run_switch) then '如果主任務開關=0即停止運行按鈕按下時
exit while '退出循環
endif
'否則重復執行以下操作
'執行單次采集響應函數獲取一幀圖像
btn_grab()
'執行提取輪廓子程序
btn_test()
wend
END
11.在main.bas文件中添加HMI啟動界面按下【停止】按鈕響應的函數并關聯動作函數。
'主界面點擊停止按鈕時響應的函數
GLOBAL SUB btn_stop()
if(run_switch = 0) then '如果主任務開關=0
?"未開啟連續運行!" '提示未開啟循環任務,并退出子函數不往下執行
return
endif
run_switch = 0 '主任務開關置0,退出循環
END SUB
(三)仿真演示效果圖
本次,正運動技術機器視覺運動控制一體機應用例程(四)——提取目標輪廓,就分享到這里。
更多精彩內容請關注“正運動小助手”公眾號,需要相關開發環境與例程代碼,請咨詢正運動技術銷售工程師:400-089-8936。
本文由正運動技術原創,歡迎大家轉載,共同學習,一起提高中國智能制造水平。文章版權歸正運動技術所有,如有轉載請注明文章來源。
下一篇: PLC、DCS、FCS三大控
上一篇: 會PLC也能玩轉機器視