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