企业号介绍

全部
  • 全部
  • 文章
  • 资料

正运动技术

18内容数 766看过 2粉丝

深圳市正运动技术有限公司专注于运动控制技术研究和通用运动控制产品的研发,是国内少有、完整掌握运动控制核心技术和实时工控平台软件技术的企业。

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

09-23 43人看过

 视频教程:《视频教程:VPLC系列机器视觉运动控制一体机快速入门(三)》

 

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

  

  

运动控制

  

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

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

  

  

运动控制

  

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

  

  

运动控制

  

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

  

  

运动控制

  形状匹配特点

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

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

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

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

  模板选择

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

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

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

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

  

  

运动控制

  

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

  

  

运动控制

  

  1 目标定位

  

  

运动控制

  

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

  2 产品计数

  

  

运动控制

  

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

  3 位置跟随

  

  

运动控制

  

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

  

  

运动控制

  

运动控制

  形状匹配流程图

  实例演示

  1

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

  

  

运动控制

  

  2

  设计主界面。

  

  

运动控制

  

  3

  在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_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;basler;zmotion"

  CAMERA_TYPE = "mvision"

 

  '相机个数

  GLOBAL cam_num

  cam_num = 0

 

  '相机模式,-1 连续采集,0-触发采集

  GLOBAL cam_mode

  cam_mode = 0

 

  '***********结束定义相机采集相关变量******************

 

  '定义返回主界面标志,1-已返回,0-未返回

  GLOBAL DIM d_is_rtn_loc

  d_is_rtn_loc = 1

 

  '***********定义模板相关变量*************************

 

  '定义创建模板标志位,1-已创建模板,0-未创建模板

  GLOBAL DIM d_is_creModel

  d_is_creModel = 0

 

  '学习模板参数,starAngle、endAngle、minScale、maxScale、thresh、numlevel、reduce、angleStep、scaleStep

  GLOBAL DIM d_mod_param(9)

 

  '***********结束定义模板相关变量**********************

 

  '***********定义编辑模板相关变量*********************

 

  '定义编辑模板标志,0-表示不编辑模板,1-表示编辑模板

  GLOBAL DIM d_edit_m

  d_edit_m = 0

 

  '定义使用橡皮擦功能标志,0-表示恢复擦除的区域,1-表示擦除区域

  GLOBAL DIM d_isMask_m

  d_isMask_m = 1

 

  '定义橡皮擦的roi参数,依次是矩形左上角和右下角图像坐标x、y、x、y

  GLOBAL DIM d_locator_roi(4),d_eraser_roi(4)

 

  '定义正方形橡皮擦尺寸宽度

  GLOBAL DIM d_eraser_size

  d_eraser_size = 5

 

  '定义界面控件上橡皮擦的矩形区域

  GLOBAL DIM c_rect(4)

 

  '定义鼠标状态标志,0-表示鼠标处于松开状态,1-表示鼠标处于按下状态

  GLOBAL DIM d_mouse_s

  d_mouse_s = 0

 

  '***********结束定义编辑模板相关变量******************

 

  '***********定义匹配检测相关变量*********************

 

  '匹配检测参数,minScore、matchNum、minDist、thresh、accuracy、speed、polor

  GLOBAL DIM d_match_param(7)

 

  '定义学习模板的roi参数和橡皮擦的roi参数,依次是矩形左上角和右下角图像坐标x、y、x、y

  GLOBAL 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 grabImg

  GLOBAL ZVOBJECT subImg,copy_subImg,colorSubImg, s_mod

  GLOBAL ZVOBJECT modRe

 

  RUN"Hmi1.hmi",1

 

  4

 

  在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

 

  5

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

  

  

运动控制

  

  6

  在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

 

  7

 

  在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)

      wend

  END

 

  '主界面按下停止采集按钮响应的函数

  GLOBAL SUB btn_stopCgrab()

          if grab_switch =0 then

              ?"未开启连续采集!"

          return
 

      endif

 

      grab_switch = 0

  end sub

  ↓

  

  

运动控制

  

  8
 

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

  

  

运动控制

  

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

 

  9

 

  在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

  ↓

  

运动控制

  

  10

 

  在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

 

  '根据更新的鼠标位置坐标绘制定位器roi

  GLOBAL 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

 

  11

 

  在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

  ↓

  

运动控制

  

  12

 

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

  

  

运动控制

  

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

 

  13

 

  在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

  ↓

  

运动控制

 

  14

 

  在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

 

  15

 

  在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

 

  ↓

  

  

运动控制

 

  16

 

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

  

  

运动控制

  ↓

  '编辑模板界面按下确定按钮时执行的函数

  GLOBAL SUB btn_erase_cfm()

      ZV_LATCHCLEAR(0)

      ZV_LATCH(grabImg, 0) '显示图像在锁存上

      HMI_CLOSEWINDOW(12) '关闭编辑模板窗口

 

  END SUB

  ↓

  

运动控制

  

  17

 

  在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

  ↓

  

  

运动控制

  

  18

 

  在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

  ↓

  

  

运动控制

 

  19

 

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

  

  

运动控制

  ↓

  '主界面按下单次执行按钮时响应的函数

  GLOBAL SUB btn_test()

      btn_grab()            '单次采集图像

      btn_loc_test()       '匹配测试函数

 

  END SUB

  ↓

  

  

运动控制

  

  20

 

  在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

      endif

  END SUB

 

  '连续运行主任务内容

  main_task:

      while(1)

          if (0 = run_switch) then

              exit while

          endif

 

          '以下执行相关定位操作

          btn_grab()

          btn_loc_test()

      wend

 

  END

  ↓

  

运动控制

  

  21

 

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

  

  

运动控制

  ↓

 

  '主界面点击停止执行按钮时响应的函数

  GLOBAL SUB btn_stop()

          if(run_switch = 0) then

              ?"未开启连续运行!"

          return

      endif

 

      run_switch = 0

  END SUB

  ↓

  

  

运动控制

  

  仿真演示效果

  

  

运动控制

  

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

 

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

  

  

 

分享:

最近浏览过的用户(0查看全部

为你推荐

  • 运动控制器激光振镜控制上传时间:2021-09-26 11:50

    在激光振镜运动控制系统中不但有运动的控制,还有激光的控制。如何有效地处理振镜运动和激光开关的配合是本节要解决的问题,只有有效的协调了激光和运动的关系,才能运动出精确的轨迹。
    运动控制器 激光 15人看过