[其他] VPLC系列机器视觉运动控制一体机快速入门(三)

[复制链接]
查看70805 | 回复0 | 4 天前 | 显示全部楼层 |阅读模式
点击上方“正运动小助手”,随时关注新动态!



今天,正运动技术为大家分享一下VPLC系列机器视觉运动控制一体机快速入门(三)——基于形状匹配的视觉定位。



video: https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&action=mpvideo&auto=0&vid=wxv_1696460527515795458



video: https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&action=mpvideo&auto=0&vid=wxv_1696461040697278466



video: https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&action=mpvideo&auto=0&vid=wxv_1696481003822710793



上期课程,我们讲述了机器视觉方案实施的基础即相机的基本使用内容,我们通过上期课程已经能实现使用ZDevelop软件获取图像进行处理。

本期课程我们和大家一起分享机器视觉方案中常用的基于形状匹配的视觉定位功能。









什么是视觉定位?

视觉定位是指在视觉检测中通过学习特定的模板或某些固定的特征,在检测区域内搜索满足条件的特征,并返回特征在图像坐标中的位置信息,如坐标位置X、坐标位置Y、角度。



什么是形状匹配?

形状匹配是基于边缘方向梯度的匹配,它是提取ROI中的边缘特征结合灰度信息创建模板,然后在检测区域ROI范围内搜索与模板的轮廓特征满足一定相似程度的产品特征,并返回对应位置信息。



形状匹配原理图

形状匹配特点

1.适应性强:可适应光照和图像的灰度变化。

2.兼容性强:可以支持搜索缺失局部边缘、有噪声干扰、有轻微变形和失焦的目标。

3.多目标搜索:支持同时搜索同一模板下的多个匹配目标。

4.支持旋转和缩放:在目标图像存在旋转或缩放的情况下仍然能匹配到目标,但是需要在设定的旋转和缩放比例范围内。

模板选择

使用形状匹配功能的前提是检测目标要有唯一且固定的特征。

1.在选择模板时,需要确保特征是检测目标唯一存在的特征,否则无法与其他检测目标区分。

2.尽量选择图像清晰形状完整的标准产品作为模板,避免掺入噪点等干扰因素。

3.尽量避免选择对称的特征作为模板。



如图,闪电是目标1唯一的特征,可以将目标1和目标2进行区分。



模板选择的原则





目标定位


在目标轮廓特征清晰且定位精度要求不高时,可直接使用形状匹配输出的位置结果做定位项目。



产品计数


对具有相同形状特征的产品进行计数统计。


位置跟随


当需要检测的目标位置不固定时,一些检测功能的ROI位置无法确定如检测直线、检测圆形等,我们可以利用检测目标周边有固定距离的特征进行位置跟随。





形状匹配流程图

实例演示



新建项目→新建HMI文件→新建main.bas文件,用于编写界面响应函数→新建global_variable.bas文件用于存放全局变量并开启HMI自动运行任务→新建InitLocator.bas文件用于初始化测量参数→新建camera.bas文件用于实现相机采集功能→新建draw.bas文件用于更新绘制图形刷新界面→文件添加到项目。





设计主界面。





在global_variable.bas文件中定义全局变量。
'''''全局变量大部分使用数组结构'''''''注:basic编程中很多函数会以TABLE(系统的数据结构)做为参数''在这里table均是做为中间变量''table 0-20 作为匹配时使用到的中间变量''table 50-70 作为roi绘制时的中间变量使用
''table 21-22,表示鼠标按键控件坐标系''table 31-35,表示控件坐标转换后对应的图像坐标''table 111-114,表示定位器区域roi参数,属于控件坐标系''table 121-124,表示橡皮擦区域roi参数,属于控件坐标系
'***********定义程序任务相关变量**********************
'主任务状态'0 - 未初始化'1 - 停止'2 - 运行中'3 - 正在停止GLOBAL DIM main_task_statemain_task_state = 1
'运行任务开关GLOBAL DIM run_switchrun_switch = 0
'采集任务开关'0 - 停止采集'1 - 请求采集GLOBAL DIM grab_switchgrab_switch = 0
'定位检测主任务id - 10GLOBAL DIM main_task_idmain_task_id = 10
'相机连续采集线程id - 7GLOBAL DIM grab_task_idgrab_task_id = 7
'***********结束定义程序任务相关变量******************
'***********定义相机采集相关变量**********************
'相机种类,"",此处使用海康相机-"mvision"GLOBAL DIM CAMERA_TYPE(100)'CAMERA_TYPE = "mindvision;basler;mvision;huaray;basler;zmotion"CAMERA_TYPE = "mvision"
'相机个数GLOBAL cam_numcam_num = 0
'相机模式,-1 连续采集,0-触发采集GLOBAL cam_modecam_mode = 0
'***********结束定义相机采集相关变量******************
'定义返回主界面标志,1-已返回,0-未返回GLOBAL DIM d_is_rtn_loc d_is_rtn_loc = 1
'***********定义模板相关变量*************************
'定义创建模板标志位,1-已创建模板,0-未创建模板GLOBAL DIM d_is_creModeld_is_creModel = 0
'学习模板参数,starAngle、endAngle、minScale、maxScale、thresh、numlevel、reduce、angleStep、scaleStepGLOBAL DIM d_mod_param(9)
'***********结束定义模板相关变量**********************
'***********定义编辑模板相关变量*********************
'定义编辑模板标志,0-表示不编辑模板,1-表示编辑模板GLOBAL DIM d_edit_md_edit_m = 0
'定义使用橡皮擦功能标志,0-表示恢复擦除的区域,1-表示擦除区域GLOBAL DIM d_isMask_md_isMask_m = 1
'定义橡皮擦的roi参数,依次是矩形左上角和右下角图像坐标x、y、x、yGLOBAL DIM d_locator_roi(4),d_eraser_roi(4)
'定义正方形橡皮擦尺寸宽度GLOBAL DIM d_eraser_sized_eraser_size = 5
'定义界面控件上橡皮擦的矩形区域 GLOBAL DIM c_rect(4)
'定义鼠标状态标志,0-表示鼠标处于松开状态,1-表示鼠标处于按下状态GLOBAL DIM d_mouse_sd_mouse_s = 0
'***********结束定义编辑模板相关变量******************
'***********定义匹配检测相关变量*********************
'匹配检测参数,minScore、matchNum、minDist、thresh、accuracy、speed、polorGLOBAL DIM d_match_param(7)
'定义学习模板的roi参数和橡皮擦的roi参数,依次是矩形左上角和右下角图像坐标x、y、x、yGLOBAL DIM d_locator_roi(4),d_eraser_roi(4)
'匹配结果,score、x、y、angle、scale, 目前对于多目标匹配也只存第一个目标GLOBAL DIM d_match_rst(5)
GLOBAL DIM d_match_time '定义匹配定位消耗的时间变量d_match_time = 0
'***********结束定义匹配检测相关变量******************
'定义程序执行过程中缓存中间图片和结果图片的变量GLOBAL ZVOBJECT grabImgGLOBAL ZVOBJECT subImg,copy_subImg,colorSubImg, s_modGLOBAL ZVOBJECT modRe
RUN"Hmi1.hmi",1



在InitLocator.bas文件中初始化测量参数。
end
GLOBAL SUB init_meas_param()   '初始化测量参数
  '初始化定位器roi参数  d_locator_roi(0) = 240    '左上角x  d_locator_roi(1) = 180    '左上角y  d_locator_roi(2) = 400    '右下角x  d_locator_roi(3) = 300    '右下角y
  '初始化模板参数  d_mod_param(0) = -180   '起始角度  d_mod_param(1) = 180    '终止角度  d_mod_param(2) = 1      '最小缩放  d_mod_param(3) = 1      '最大缩放  d_mod_param(4) = 80     '阈值  d_mod_param(5) = 0      '默认金字塔层数  d_mod_param(6) = 0      '默认约简特征点  d_mod_param(7) = 0      '默认角度步长  d_mod_param(8) = 0      '默认缩放步长
  '初始化匹配测量参数  d_match_param(0) = 50   '最小分数  d_match_param(1) = 1    '匹配个数  d_match_param(2) = 0    '默认最小间距  d_match_param(3) = 40   '最小阈值  d_match_param(4) = 0    '精度  d_match_param(5) = 9    '速度  d_match_param(6) = 0    '极性
  '初始化匹配定位结果  d_match_rst(0) = 0       '分数  d_match_rst(1) = 0       '位置X  d_match_rst(2) = 0       '位置Y  d_match_rst(3) = 0       '角度  d_match_rst(4) = 0       '比例
  '初始化匹配定位消耗时间  d_match_time = 0
END SUB



关联主界面值显示控件变量。







在main.bas文件中添加主界面初始化函数。
'HMI界面初始化函数,上电执行一次GLOBAL SUB hmi_init()
  grab_switch = 0                          '初始化采集任务开关,不开启采集任务  main_task_state = 1                      '初始化定位检测主任务状态为停止状态1  ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 2), HMI_CONTROLSIZEY(10, 2)) '设置锁存的大小  init_meas_param()                       '初始化测量参数
  ZV_IMGGENCONST(subImg,40,30,1,0,0)      '初始化模板子图像
  '初始化一些全局参数  ZVOBJECT contlist1, tsContlist1, mat_rigid1  ZVOBJECT contlist2, tsContlist2, mat_rigid2
  ZV_READIMAGE(grabImg,"1.bmp",1)      '读取.../flash目录下的show.bmp的灰度图像,存放到grabImg变量中  ZV_LATCH(grabImg,0)                  '显示到锁存通道0中,作为显示区域背景图片
END SUB



在camera.bas文件中添加主界面中采集相关按钮响应的函数并关联动作函数。



↓end
'主界面按下扫描相机按钮时响应的函数GLOBAL SUB cam_scan_all()  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(100000)         '设置相机曝光时间为100000us        CAM_SETMODE(cam_mode)            '设置软件触发模式  CAM_START(0)                     '开启相机  
END SUB
'主界面按下单次采集按钮执行的函数GLOBAL SUB btn_grab()    if cam_num = 0   then        ?"请先扫描相机!"     return     endif
  CAM_SETPARAM("TriggerSoftware", 0)  CAM_GET(grabImg, 0)  ZV_LATCH(grabImg, 0)
  ZV_IMGINFO(grabImg,3000)       '获取grabImg变量缓存的图片的基本信息,并存放到起始地址为3000的table数组中
end sub
'主界面按下连续采集按钮响应的函数GLOBAL SUB btn_cgrab()    if grab_switch =1 then        ?"正在连续运行中,请勿重复操作!"     return   endif
  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
'采集任务实现函数grab_task:  while(1)    if (0 = grab_switch) then      exit while    endif
      CAM_START(0)                     '开启相机        CAM_SETPARAM("TriggerSoftware", 0)      CAM_GET(grabImg, 0)      ZV_LATCH(grabImg, 0)  wendEND
'主界面按下停止采集按钮响应的函数GLOBAL SUB btn_stopCgrab()    if grab_switch =0 then        ?"未开启连续采集!"     return   endif
  grab_switch = 0end sub↓




点击[元件]→[新建窗口],新建学习模板窗口,设计窗口布局。



注意:需要设置窗口垄断属性。



在draw.bas文件中添加主界面【学习模板】按钮响应的函数并关联动作函数。




'主界面按下学习模板按钮时响应的函数GLOBAL SUB btn_sel_loc()      ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(11, 60), HMI_CONTROLSIZEY(11, 60)) '设置创建模板窗口锁存通道0的锁存大小  SET_COLOR(RGB(0,255,0))   '指定draw指令使用的颜色
  ZV_LATCHCLEAR(0)           '将锁存通道0清空  ZV_LATCH(grabImg, 0)       '显示采集图像显示到锁存通道0中  ZV_LATCH(colorSubImg, 1)   '显示模板图像显示到锁存通道1中
  '图像roi坐标转控件roi  is_redraw = 0  d_is_rtn_loc = 0  TABLE(111, d_locator_roi(0), d_locator_roi(1),d_locator_roi(2),d_locator_roi(3))   ZV_POSFROMIMG(0, 2, 111, 111) '图像坐标转换到HMI控件坐标  HMI_SHOWWINDOW(11)
END SUB↓




在draw.bas文件中添加模板区域更新绘制函数。
'根据鼠标操作更新定位器的区域即学习模板的有效区域GLOBAL SUB update_locator()
  if mouse_scan(21) = 1 then      '扫描鼠标按下操作    is_set_roi_m_down = 1    sr_mpos_x = table(21)    sr_mpos_y = table(22)    hit_pos = ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 111, -1) '只有按下时可以改变击中位置    is_redraw = 1    endif
    if mouse_scan(21) = -1 then      '扫描鼠标松开操作    is_set_roi_m_down = 0    sr_mpos_x = table(21)    sr_mpos_y = table(22)    ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 111, hit_pos)    is_redraw = 1    endif
  if (is_set_roi_m_down and MOUSE_state(21)) then    sr_mpos_x = table(21)    sr_mpos_y = table(22)    ZV_HMIADJRECT(sr_mpos_x, sr_mpos_y, 111, hit_pos)    is_redraw = 1  endif
  if (1 = is_redraw) then    '控件roi坐标转图像roi坐标    is_redraw = 0    ZV_POSTOIMG(0, 2, 111, 50) 'TABLE(50)作为中间变量临时使用    d_locator_roi(0) = TABLE(50)    d_locator_roi(1) = TABLE(51)    d_locator_roi(2) = TABLE(52)    d_locator_roi(3) = TABLE(53)    SET_REDRAW  endif
END SUB
'根据更新的鼠标位置坐标绘制定位器roiGLOBAL SUB draw_locator()  DRAWRECT(TABLE(111), TABLE(112), TABLE(113), TABLE(114))
  local cx,cy  cx = (TABLE(111) + TABLE(113)) / 2  cy = (TABLE(112) + TABLE(114)) / 2
  DRAWLINE(cx-5, cy, cx+5, cy)  '中心十字线  DRAWLINE(cx, cy-5, cx, cy+5)
END SUB



在main.bas文件中添加【截取模板】按钮响应的函数并关联动作函数。



↓'创建模板界面按下截取模板按钮后响应的函数global sub btn_getSubImg()  LOCAL mod_w,mod_h  ZV_IMGGETSUB(grabImg, subImg, d_locator_roi(0), d_locator_roi(1), d_locator_roi(2)-d_locator_roi(0)+1, d_locator_roi(3)-d_locator_roi(1)+1)
  ZV_IMGINFO(subImg,0)  mod_w = TABLE(0)  mod_h = TABLE(1)
  ZV_REGENRECT(modRe,0,0,mod_w, mod_h)  ZV_LATCHCLEAR(1)  ZV_LATCH(subImg, 1)
end sub↓




点击[元件]→[新建窗口],新建编辑模板窗口,设计窗口布局。



注意:需要设置窗口垄断属性。



在draw.bas文件中添加创建模板界面【橡皮擦】按钮响应的函数并关联动作函数。



↓'创建模板界面按下橡皮擦按钮时响应的函数GLOBAL SUB btn_sel_erase()  ZV_LATCHSETSIZE(1, HMI_CONTROLSIZEX(12, 1), HMI_CONTROLSIZEY(12, 1)) '设置锁存的大小  SET_COLOR(RGB(0,255,0))             '设置绘制时画笔使用的颜色
  ZV_LATCHCLEAR(1)                    '清空锁存  ZV_IMGCOPY(subImg, copy_subImg)      '复制模板子图像到copy_subImg图像变量中  ZV_REGION(copy_subImg, modRe, 1, 0)  '在模板图像上绘制modRe图像的非有效区域,绘制颜色为黑色,用于掩模  ZV_LATCH(copy_subImg, 1)             '显示复制的模板图

  HMI_SHOWWINDOW(12)                  '打开编辑模板窗口
end sub↓




在draw.bas文件中添加橡皮擦更新绘制函数。
'根据鼠标操作更新橡皮擦擦除/恢复区域的位置GLOBAL SUB update_eraser()  DIM c_size_eraser '橡皮擦在控件上对应的尺寸  DIM eraser_pos_x,eraser_pos_y   d_mouse_s = MOUSE_STATE(21)     '鼠标处于按下状态时  eraser_pos_x = TABLE(21)  eraser_pos_y = TABLE(22)
  c_size_eraser = ZV_LENFROMIMG(0, d_eraser_size)    '将橡皮擦的图像尺寸转换成控件尺寸  c_rect(0, eraser_pos_x - c_size_eraser, eraser_pos_y - c_size_eraser, eraser_pos_x + c_size_eraser, eraser_pos_y + c_size_eraser)  '绘制以(eraser_pos_x,eraser_pos_y)为中心,2*c_size_eraser为边长的正方形橡皮擦区域
  DIM hmi_w,hmi_h  if (eraser_pos_x >= c_size_eraser) and (eraser_pos_y >= c_size_eraser) and  (eraser_pos_x <= HMI_CONTROLSIZEX(12, 1) - c_size_eraser)and (eraser_pos_y <= HMI_CONTROLSIZEy(12, 1) - c_size_eraser) THEN    SET_REDRAW(0,0, HMI_CONTROLSIZEX(12, 1), HMI_CONTROLSIZEY(12, 1))'重新绘制编辑模板窗口上的锁存通道0区域  endif
  if d_mouse_s = 1 and d_edit_m = 1 then '如果鼠标处于按下状态且编辑模板标志=1时    btn_pro_eraser()                   '执行处理橡皮擦函数  endif
END SUB
'处理橡皮擦函数global sub btn_pro_eraser()  ZVOBJECT tmp_re  TABLE(121, c_rect(0), c_rect(1))  ZV_POSTOIMG(1, 1, 121, 121)  ZV_REGENRECT(tmp_re, TABLE(121), TABLE(122), 2 * d_eraser_size + 1, 2 * d_eraser_size + 1)
  if (d_isMask_m = 1) then '屏蔽    ZV_REDIFF(modRe, tmp_re, modRe)   '计算modRe和tmp_re的差集并存放到modRe中  else  '恢复    ZV_REUNION(modRe, tmp_re, modRe)  '计算modRe和tmp_re的并集并存放到modRe中  endif
  ZV_IMGCOPY(subImg, copy_subImg)        '复制模板子图像到copy_subImg图像变量中  ZV_REGION(copy_subImg, modRe, 1, 0)    '在模板图像上绘制modRe图像的非有效区域,绘制颜色为黑色,用于掩模  ZV_LATCH(copy_subImg, 1)               '显示复制的模板图
end sub
'更新绘制橡皮擦区域GLOBAL SUB draw_eraser()  if d_edit_m = 0 then                   '如果编辑模板标志         return                             '返回子函数,不继续往下执行  endif
  DRAWRECT(c_rect(0), c_rect(1), c_rect(2), c_rect(3))'绘制橡皮擦区域
END SUB



在main.bas文件中添加编辑模板界面【创建模板】按钮响应的函数并关联动作函数。




'编辑模板界面按下创建模板按钮时响应的函数GLOBAL SUB btn_loc_creModel()  d_is_creModel = 1  ZV_SHAPECREATERE(subImg, modRe,s_mod, d_mod_param(0), d_mod_param(1), d_mod_param(2), d_mod_param(3), d_mod_param(4), d_mod_param(5), d_mod_param(6), d_mod_param(7), d_mod_param(8))    '创建模板
  ZV_SHAPECONTOURS(s_mod, contlist1, 0)   '获取第0层金字塔上的模板轮廓  ZV_GRAYTORGB(subImg, colorSubImg)        '灰度图转换成RGB图  ZV_IMGINFO(colorSubImg, 0)               '获取colorSubImg图像信息,并存放到table0中  ZV_GETRIGIDVECTOR(mat_rigid1, 0, 0, 0, TABLE(0)/2, TABLE(1)/2, 0)'计算刚性变换矩阵  ZV_CONTAFFINE(contlist1, mat_rigid1, tsContlist1)'对轮廓或轮廓序列进行仿射变换  ZV_CONTLIST(colorSubImg, tsContlist1, ZV_COLOR(0, 255, 0), 0)'在colorSubImg图像上绘制绿色的轮廓序列
  ZV_LATCHCLEAR(2)  ZV_LATCH(colorSubImg, 2)
end sub↓




在draw.bas文件中添加编辑模板界面【确定】按钮响应的函数并关联动作函数。



↓'编辑模板界面按下确定按钮时执行的函数GLOBAL SUB btn_erase_cfm()  ZV_LATCHCLEAR(0)  ZV_LATCH(grabImg, 0) '显示图像在锁存上  HMI_CLOSEWINDOW(12)  '关闭编辑模板窗口
END SUB↓




在main.bas文件中添加创建模板界面【测试】按钮响应的函数并关联动作函数。




'创建模板界面按下测试按钮时响应的函数GLOBAL SUB btn_loc_test()  if (d_is_creModel = 0) then      ?"未创建模板!"    return  endif
  '开始匹配  TICKS = 0  ZVOBJECT match_rst, sImg, colorImg  ZV_GAUSSBLUR(grabImg, sImg, 3)  ZV_SHAPEFIND(s_mod, sImg, match_rst, d_match_param(0), d_match_param(1), d_match_param(2), d_match_param(3), d_match_param(4), d_match_param(5), d_match_param(6))
  ZV_MATINFO(match_rst, 0)  ZV_GRAYTORGB(sImg, colorImg)
  if TABLE(0) > 0 then    local rowr    for rowr = 0 to TABLE(0)-1      ZV_MATGETROW(match_rst, rowr, 5, 3)  '获取match_rst矩阵中第rowr行的数据到table中,table最大长度5
      if(rowr = 0) then        d_match_rst(0) = TABLE(3)        d_match_rst(1) = TABLE(4)        d_match_rst(2) = TABLE(5)        d_match_rst(3) = TABLE(6)        d_match_rst(4) = TABLE(7)
        ZV_GETRIGIDVECTOR(mat_rigid1, 0, 0, 0, TABLE(4), TABLE(5), TABLE(6))'计算刚性变换矩阵        ZV_CONTAFFINE(contlist1, mat_rigid1, tsContlist1)'对轮廓或轮廓序列进行仿射变换        ZV_CONTLIST(colorImg, tsContlist1, ZV_COLOR(0, 255, 0), 0)'在colorSubImg图像上绘制绿色的轮廓序列      endif    next  else    d_match_rst(0) = -1    d_match_rst(1) = -1    d_match_rst(2) = -1    d_match_rst(3) = -1    d_match_rst(4) = -1  endif
  d_match_time = abs(TICKS) '匹配时间  ZV_LATCH(colorImg, 0)
end sub





在draw.bas文件中添加创建模板界面【确定】按钮响应的函数并关联动作函数。



↓'创建模板界面按下确定按钮时响应的函数GLOBAL SUB btn_loc_cfm()  grab_switch = 0 '关闭补正源的连续采集  d_is_rtn_loc = 1  ZV_LATCHCLEAR(0)  ZV_LATCH(grabImg, 0) '显示图像在锁存上  ZV_LATCH(grabImg, 1) '显示图像在锁存上
  HMI_CLOSEWINDOW(11)
END SUB↓




在main.bas文件中添加主界面【单次执行】按钮响应的函数并关联动作函数。


↓'主界面按下单次执行按钮时响应的函数GLOBAL SUB btn_test()  btn_grab()           '单次采集图像  btn_loc_test()       '匹配测试函数
END SUB↓




在main.bas文件中添加主界面【连续运行】按钮响应的函数并关联动作函数。



↓'主界面点击连续运行按钮时响应的函数GLOBAL SUB btn_run()    if(run_switch = 1) then      ?"已开启连续运行,请勿重复操作!"     return   endif
  run_switch = 1  if (1 = run_switch) then    if (0 = PROC_STATUS(main_task_id)) then      RUNTASK  main_task_id, main_task    endif  endifEND SUB
'连续运行主任务内容main_task:  while(1)    if (0 = run_switch) then      exit while    endif
    '以下执行相关定位操作    btn_grab()    btn_loc_test()  wend
END↓




在main.bas文件中添加主界面【停止运行】按钮响应的函数并关联动作函数。




'主界面点击停止执行按钮时响应的函数GLOBAL SUB btn_stop()    if(run_switch = 0) then      ?"未开启连续运行!"     return   endif
  run_switch = 0END SUB↓


仿真演示效果





本次,VPLC系列机器视觉运动控制一体机快速入门(三)——基于形状匹配的视觉定位就分享到这里,更多精彩内容请关注“正运动小助手”公众号。

本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。

回顾往期内容

VPLC系列机器视觉运动控制一体机快速入门(二)相机的基本使用

VPLC系列机器视觉运动控制一体机快速入门(一)基础知识

运动控制卡应用开发教程之ROS(下)

运动控制卡应用开发教程之ROS(上)

运动控制卡应用开发教程之激光振镜控制

运动控制卡应用开发教程之C++

运动控制卡应用开发教程之C#

运动控制卡应用开发教程之Python

运动控制卡应用开发教程之Linux

运动控制卡应用开发教程之VB.NET

运动控制卡应用开发教程之VB6.0

运动控制卡应用开发教程之VC6.0

运动控制卡应用开发教程之使用Qt

运动控制卡应用开发教程之LabVIEW

正运动技术丨高精度硬件比较输出在视觉飞拍上的应用

正运动技术丨UVW 对位平台控制算法在视觉引导上的应用

正运动技术XPLC516E 的开放式Linux 平台使用(上)

正运动技术XPLC516E 的开放式Linux 平台使用(下)

关于正运动技术

正运动技术是一家专注于运动控制技术研发与应用的国家级高新技术企业,主要从事运动控制器、运动控制卡、视觉运动控制一体机以及IO扩展模块等产品的研发、生产、销售和服务。

公司汇集了来自华为、中兴等公司的优秀人才,在坚持自主创新的同时,积极联合各大高校致力于运动控制技术研究与应用,是国内工控领域发展最快的企业之一,也是国内完整掌握运动控制核心技术和实时工控软件平台技术的企业。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则