首页 新闻 工控搜 论坛 厂商论坛 产品 方案 厂商 人才 文摘 下载 展览
中华工控网首页
  P L C | 变频器与传动 | 传感器 | 现场检测仪表 | 工控软件 | 人机界面 | 运动控制
  D C S | 工业以太网 | 现场总线 | 显示调节仪表 | 数据采集 | 数传测控 | 工业安全
  电 源 | 嵌入式系统 | PC based | 机柜箱体壳体 | 低压电器 | 机器视觉
VPLC系列机器视觉运动控制一体机快速入门(八)测量点/线/圆
深圳市正运动技术有限公司
收藏本文     查看收藏

 此前,我们依次讲解了软硬件介绍及计数实例、相机的基本使用、基于形状匹配的视觉定位、BLOB有无检测、测量尺寸、机器视觉方案中使用到的标定功能以及ZDevelop软件实现识别条形码和二维码的功能。

 本期课程我们和大家一起分享机器视觉的基本测量功能——测量点/直线/圆。

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

  2.png

  一、检测原理

  机器视觉中使用到的测量点/线/圆的功能都是基于边缘检测的视觉算法。

  边缘检测即是在一定的搜索区域内,按照指定的方向逐像素搜索满足极性变化和对比度要求的过渡边缘点。

  3.png

 二、测量点/线/圆特点

  1.实现简单

  测量点/线/圆的算法是基于边缘检测的算法,易于实现。

  2.需要位置跟随

  测量器本身不具有定位功能,如果检测产品位置不固定将无法确定测量器对应的位置,此时需要依赖匹配等定位功能做位置跟随。

  4.png

  三、量点应用场景

  1.精准定位

  检测特征边缘点的位置并输出对应坐标可实现精准定位,常配合匹配(粗定位)使用。

  2.拟合直线

  可通过检测两个特征边缘点拟合出一条直线,并输出直线数据做进一步检测。

  四、测量线应用场景

  1.精准定位

  通常使用检测两条直线的交点位置坐标作为定位位置,输出的位置精度比匹配输出的位置精度高,常配合匹配(粗定位)使用。

  2.检测直线度

  可通过一个直线测量器检测多个边缘点拟合直线后根据不在直线上的异常边缘点数来判断直线度。

  3.测量尺寸

  可通过检测两条直线并计算两条直线的距离求出产品的边缘尺寸距离。

  五、测量圆应用场景

  1.测量圆

  测量圆形特征,得出圆形的圆心、半径等数据。

  2.定位

  通过测量圆的特征输出圆心位置坐标数据做精准定位,常配合匹配(粗定位)使用。

  3.九点标定

  可通过检测实心圆矩阵标定板上的九个圆心的图像坐标数据,和标定板对应的世界坐标数据计算出标定系数。

  5.png

  测量点/线/圆流程图

  六、实例演示

  1.打开ZDevelop软件:新建项目→新建HMI文件→新建main.bas文件,用于编写界面响应函数→新建global_variable.bas文件用于存放全局变量→新建InitParam.bas文件用于初始化测量参数→新建camera.bas文件用于实现相机采集功能→新建draw.bas文件用于更新绘制图形刷新界面→文件添加到项目。

  6.png

  2.设计运行界面,运行界面只进行采集图像操作和检测执行操作,并显示数据结果。

  7.png

  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参数,属于控件坐标系

  ''table 81-98,表示标定使用到的九个点的图像坐标

  ''table 131-148,表示标定使用到的九个点的世界坐标

  '***********定义程序任务相关变量**********************
 

  '主任务状态

  '0 - 未初始化

  '1 - 停止

  '2 - 运行中

  '3 - 正在停止

  GLOBAL DIM main_task_state

  main_task_state = 1
 

  '是否标定

  global is_ca_success
 

  '运行任务开关

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

  GLOBAL ZVOBJECT subImg,copy_subImg,colorSubImg, s_mod

  GLOBAL ZVOBJECT modRe
 

  '***********定义坐标标定相关变量*********************

  '定义是否使用标定功能标志,0-不使用标定功能,1-使用标定功能

  GLOBAL DIM d_use_calib

  d_use_calib = 0
 

  '定义标定成功标志,0-标定未成功,1-标定成功

  GLOBAL DIM d_calib_success

  d_calib_success = 0
 

  '标定参数

  GLOBAL ZVOBJECT ca_param
 

  '标定参数数组,依次为:标定类型、对比度、极性、最小面积、最大面积、世界坐标点间距

  GLOBAL DIM d_ca_param(6) 'd开头表示数据结构
 

  '标定误差,最小误差、最大误差、平均误差

  GLOBAL DIM ca_min_err,ca_max_err,ca_avg_err

  ca_min_err = 0

  ca_max_err = 0

  ca_avg_err = 0
 

  '常用颜色变量

  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 ZVOBJECT ca_mat

  '***********结束定义坐标标定相关变量******************
 

  '***********定义测量点/线/圆相关变量******************

  '定义检测消耗时间

  GLOBAL DIM d_detect_time
 

  '定义是否使用补正源,0-不使用补正源,1-使用补正源

  GLOBAL DIM d_use_locator

  '

  '是否绘制测量器

  GLOBAL DIM line_status,circle_status,point_status

  line_status=0

  circle_status=0

  point_status=0
 

  '测量点/线/圆参数设置,包括边缘极性/边缘位置/对比度/滤波尺寸/扫描数量/扫描宽度

  GLOBAL DIM d_point_param(4),d_line_param(6), d_circle_parm(6)
 

  '绘制结果参数

  GLOBAL DIM draw_point(2),draw_line(4),draw_circle(3)

  '***********结束定义测量点/线/圆相关变量**************

  '定义点测量器区域/线测量器区域/圆测量器区域

  GLOBAL DIM d_roi_rect1(5),d_roi_rect2(5),d_roi_arc(6)
 

  '设置创建模板的基准坐标

  GLOBAL DIM d_match_base_rst(5)
 

  GLOBAL ZVOBJECT mat_rigid,latch '
 

  '**********************点线圆测量数据结果*****************

  GLOBAL DIM point_result(5),line_result(5),circle_result(5)
 

  '***********定义读取本地文件功能相关变量**************

  ''注意,该功能只在使用仿真器时有效

  '定义是否使用本地图片标志

  GLOBAL DIM d_use_imgfile
 

  '定义本地图片索引

  GLOBAL DIM d_index
 

  '定义读取图片的路径

  GLOBAL DIM File_Name(100)
 

  '***********结束定义读取本地文件功能相关变量**********

  RUN "Hmi1.hmi",1

  

  4.在InitParam.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_point_param(0)=0

     d_point_param(1)=0

     d_point_param(2)=30

     d_point_param(3)=5
 

     '线的测量参数初始化

     d_line_param(0)=0

     d_line_param(1)=0

     d_line_param(2)=30

     d_line_param(3)=5

     d_line_param(4)=10

     d_line_param(5)=8
 

     '圆的测量参数初始化

     d_circle_parm(0)=0

     d_circle_parm(1)=0

     d_circle_parm(2)=20

     d_circle_parm(3)=5

     d_circle_parm(4)=10

     d_circle_parm(5)=8
 

     '初始化坐标标定相关的变量

     d_ca_param(0) = 0 '标定类型

     d_ca_param(1) = 120 '对比度

     d_ca_param(2) = 0 '极性

     d_ca_param(3) = 80 '最小面积

     d_ca_param(4) = 20000 '最大面积

     d_ca_param(5) = 9 '世界坐标点间距

     ca_min_err = 0 '最小误差

     ca_max_err = 0 '最大误差

     ca_avg_err = 0 '平均误差
 

     d_detect_time = 0

     d_use_locator = 0 '默认不使用补正源

     d_use_imgfile = 1

     d_index = 0
 

     TABLE(31,100,100,60,40,60,8,5) '点测量器初始化

     TABLE(231,100,100,60,40,60,8,5) '线测量器初始化

     TABLE(551,100,100,60,50,0,360,8,5) '圆测量器初始化

  END SUB

  5.在运行界面中关联相关变量。

  8.png

  6.在main.bas文件中添加运行界面初始化函数,并关联HMI界面初始化函数名。

  '运行界面初始化函数,上电执行一次

  GLOBAL SUB hmi_init()
 

     grab_switch = 0 '初始化采集任务开关,不开启采集任务

     main_task_state = 1 '初始化定位检测主任务状态为停止状态1

     ZV_SETSYSINT("LineWidth",5) '设置绘制画笔宽度为5个像素

     ZV_RESETCLIPSIZE(1280, 1024) '初始化时依据图像分辨率设置区域的裁剪尺寸,此处图像分辨率为1280x1024

     ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 1), HMI_CONTROLSIZEY(10, 1)) '设置锁存的大小

     init_meas_param() '初始化测量参数
 

     ZV_IMGGENCONST(subImg,40,30,1,0,0) '初始化模板子图像
 

     '定义匹配中间结果变量

     ZVOBJECT contlist1, tsContlist1, mat_rigid1

     ZVOBJECT contlist2, tsContlist2, mat_rigid2
 

     ZV_READIMAGE(grabImg,"\8\calib.bmp",1) '读取...\flash\8目录下的calib.bmp的灰度图像,用于加载本地图片仿真时进行坐标标定

     ZV_LATCHCLEAR(0) '清空锁存通道0

     ZV_LATCH(grabImg,0) '显示到锁存通道0中
 

  END SUB

  

  9.png

  

  7.在camera.bas文件中添加采集相关按钮的功能函数,并关联动作函数名。

  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="\8\"+TOSTR(d_index,1,0)+".bmp" '.../flash/3/目录下的图片所在的路径名称

     ZV_IMGREAD(grabImg,File_Name,0)

     ZV_LATCH(grabImg, 0)

     d_index=d_index+1

  return

  endif

     ''读取本地图片功能结束
 

         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
 

         '重复执行以下操作

         btn_grab()

     wend

  END
 

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

  GLOBAL SUB btn_stopCgrab()

     if grab_switch =0 then '如果已经处于停止采集状态,打印提示信息并退出函数

         ?"未开启连续采集!"

     return

  endif
 

      grab_switch = 0 '将采集任务开关置0

  END SUB

  10.png

  

  8.新建运行界面按下【参数设置】按钮时弹出的参数设置窗口,并设计界面布局。

  11.png

  

  9.添加在运行界面按下【参数设置】按钮时响应的函数,并关联动作函数名。

  '运行界面按下参数设置按钮时响应的函数

  GLOBAL SUB btn_set_param()
 

     ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(11, 1), HMI_CONTROLSIZEY(11, 1)) '设置锁存的大小

     ZV_LATCHCLEAR(0)

     ZV_LATCH(grabImg,0) '显示到锁存通道0中,作为显示区域背景图片

     HMI_SHOWWINDOW(11)
 

  END SUB

  

  12.png

  

  10.参考第三篇“基于形状匹配的视觉定位”,添加形状匹配功能,添加流程如下:

  13.png

  

  end
 

  '和绘制(即选择ROI)有关的界面刷新绘制函数放在这个bas文件里
 

  DIM is_redraw '绘图标志,0表示未进行绘制,1表示正在进行绘制

  is_redraw = 0
 

  DIM sr_mpos_x, sr_mpos_y, hit_pos
 

  '主界面按下学习模板按钮时响应的函数

  GLOBAL SUB btn_sel_loc()

     ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(12, 60), HMI_CONTROLSIZEY(12, 60)) '设置创建模板窗口锁存通道0的锁存大小

     ZV_LATCHSETSIZE(1, HMI_CONTROLSIZEX(12, 38), HMI_CONTROLSIZEY(12, 38)) '设置创建模板窗口锁存通道1的锁存大小

     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(12)
 

  END SUB
 

  '根据鼠标操作更新定位器的区域即学习模板的有效区域

  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
 

  '创建模板界面按下截取模板按钮后响应的函数

  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
 

  '创建模板界面按下橡皮擦按钮时响应的函数

  GLOBAL SUB btn_sel_erase()

     ZV_LATCHSETSIZE(1, HMI_CONTROLSIZEX(13, 1), HMI_CONTROLSIZEY(13, 1)) '设置锁存的大小

     ZV_LATCHSETSIZE(2, HMI_CONTROLSIZEX(13, 15), HMI_CONTROLSIZEY(13, 15)) '设置锁存的大小

     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(13) '打开编辑模板窗口
 

  end sub
 

  '根据鼠标操作更新橡皮擦擦除/恢复区域的位置

  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
 

  '编辑模板界面按下创建模板按钮时响应的函数

  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)
 

     btn_loc_test()

     d_match_base_rst(0) = d_match_rst(0)

     d_match_base_rst(1) = d_match_rst(1)

     d_match_base_rst(2) = d_match_rst(2)

     d_match_base_rst(3) = d_match_rst(3)

     d_match_base_rst(4) = d_match_rst(4)

  END SUB
 

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

  GLOBAL SUB btn_erase_cfm()

     ZV_LATCHCLEAR(0)

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

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

  END SUB
 

  '创建模板界面按下测试按钮时响应的函数

  GLOBAL SUB btn_loc_test()

     if (d_is_creModel = 0) then

             ?"未创建模板!"

         return

     endif
 

  '开始匹配
 

  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

             if(is_ca_success = 1 AND d_use_calib=1) then

                 ZV_CALTRANSW(ca_param, TABLE(4),TABLE(5),8) '像素坐标转世界坐标

                 d_match_rst(0) = TABLE(3)

                 d_match_rst(1) = TABLE(8)

                 d_match_rst(2) = TABLE(9)

                 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图像上绘制绿色的轮廓序列

                 else

                 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

                 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

                 ZV_LATCH(colorImg, 0)

             END SUB

             '创建模板界面按下确定按钮时响应的函数

             GLOBAL SUB btn_loc_cfm()

             grab_switch = 0 '关闭补正源的连续采集

             d_is_rtn_loc = 1

             ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(11, 1), HMI_CONTROLSIZEY(11, 1)) '设置锁存的大小

             ZV_LATCHCLEAR(0)

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

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

             HMI_CLOSEWINDOW(12)

  END SUB

  11.参考第六篇“标定”,添加坐标标定功能,添加流程如下:

  14.png

  

  '参数设置界面按下坐标标定按钮时响应的函数

  GLOBAL SUB btn_calib()
 

      ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(14, 91), HMI_CONTROLSIZEY(14, 91)) '设置坐标标定窗口锁存通道0的锁存大小

     ZV_LATCHCLEAR(0) '将锁存通道0清空

     ZV_LATCH(grabImg, 0) '显示采集图像显示到锁存通道0中

     HMI_SHOWWINDOW(14)
 

  END SUB
 

  '坐标标定界面按下提取mark点按钮时响应的函数

  GLOBAL SUB btn_ca_extract()

  ZVOBJECT inppts, ppts, wpts
 

  '提取像素坐标

  ZV_CALGETSCAPTS(grabImg, inppts, d_ca_param(1), d_ca_param(2), d_ca_param(3), d_ca_param(4))

  ZV_MATINFO (inppts, 400)
 

  DIM row,col

  row = TABLE(400)

  col = TABLE(401)

  if(row * col = 18) then

      TABLE(150) = 1 '提取mark点成功

  else

     TABLE(150) = 0 '提取mark点失败

     return

  endif
 

  '根据mrak点间距和像素坐标计算世界坐标

  ZV_CALGETPTSMAP(inppts,ppts,wpts,d_ca_param(5))

  ZV_MATINFO (ppts, 400)
 

  row = TABLE(400)

  col = TABLE(401)

  if(row * col = 18) then

      TABLE(150) = 1 '提取mark点成功

  else

     TABLE(150) = 0 '提取mark点失败

     return

  endif
 

  '像素坐标和世界坐标放入table中

  DIM i

  FOR i=0 TO row-1

     ZV_MATGETROW (ppts, i, col, 81 + i*col)

     ZV_MATGETROW (wpts, i, col, 131 + i*col)

  NEXT
 

  '设置用于绘制mark点的图像

  ZVOBJECT color

  ZV_GRAYTORGB(grabImg, color)
 

  '和绘制mark点的十字架

  DIM j, pixNum '像素个数

  pixNum = 0

     FOR i=0 TO 2

         FOR j=0 TO 2

             ZV_MARKER(color, TABLE(81 + 2 * pixNum), TABLE(81 + 2 * pixNum + 1), 0, 40, C_GREEN)

             pixNum = pixNum + 1

     NEXT

  NEXT
 

  '用文本绘制mark点的序号

     FOR i=0 TO 8

         ZV_TEXT (color, TOSTR(i,1,0), TABLE(81+2*i)-20, TABLE(81+2*i +1)-40, 20, C_BLUE)

     NEXT
 

     ZV_LATCH(color, 0)
 

  END SUB
 

  '坐标标定界面按下标定按钮时响应的函数

  GLOBAL SUB btn_ca_calib()
 

     ZV_IMGINFO(grabImg,0)

     ZV_CALCAM(ppts,wpts,ca_param,TABLE(0),TABLE(1),d_ca_param(0))

     is_ca_success=1

     '计算标定误差

     ZV_CALERROR(ca_param, ppts, wpts, 0)

     ca_min_err = TABLE(1)

     ca_max_err = TABLE(2)

     ca_avg_err = TABLE(0)
 

  END SUB

  '坐标标定界面按下返回按钮时响应的函数

  GLOBAL SUB btn_ca_param_rtn()

      HMI_CLOSEWINDOW(14)

  END SUB
 

  12.在参数设置界面的【采集图像】按钮关联动作函数名btn_grab。
 

  13.在draw.bas文件中添加点/线/圆测量器区域的更新绘制函数,并在自定义元件属性窗口中关联刷新函数和绘制函数。
 

  '点,线,圆测量器的刷新函数

  GLOBAL SUB update_roi ()
 

      if point_status = 1 then

          SET_REDRAW '绘制第一次点击的

          if (mouse_scan(21) = 1 ) then '扫描按下操作

              hit_pos = ZV_HMIADJRECT2(table(21), table(22), 31, -1) '只有按下时可以改变击中位置

              is_redraw = 1

          endif
 

          if (mouse_scan(21) = -1 ) then '扫描松开操作

              ZV_HMIADJRECT2(table(21), table(22), 31, hit_pos)

              is_redraw = 1

          endif
 

          if (MOUSE_state(21)) then

              ZV_HMIADJRECT2(table(21), table(22), 31, hit_pos)

              is_redraw = 1

          endif
 

          if (1 = is_redraw) then
 

              is_redraw = 0
 

             ZV_POSTOIMG(0, 1, 31, 41)

             d_roi_rect1(0) = TABLE(41)

             d_roi_rect1(1) = TABLE(42)

             d_roi_rect1(2) = ZV_LENTOIMG(0, TABLE(33))

             d_roi_rect1(3) = ZV_LENTOIMG(0, TABLE(34))

             d_roi_rect1(4) = TABLE(35)
 

             SET_REDRAW
 

         endif
 

     elseif line_status=1 then

         SET_REDRAW '绘制第一次点击的

         if (mouse_scan(21) = 1)then '扫描按下操作

             hit_pos = ZV_HMIADJRECT2(table(21), table(22),231, -1) '只有按下时可以改变击中位置

             is_redraw = 1

                 endif
 

         if (mouse_scan(21) = -1) then '扫描松开操作

             ZV_HMIADJRECT2(table(21), table(22), 231, hit_pos)

             is_redraw = 1

         endif
 

         if (MOUSE_state(21)) then

             ZV_HMIADJRECT2(table(21), table(22), 231, hit_pos)

             is_redraw = 1

         endif
 

         if (1 = is_redraw) then
 

             is_redraw = 0
 

             ZV_POSTOIMG(0, 1, 231, 41)

             d_roi_rect2(0) = TABLE(41)

             d_roi_rect2(1) = TABLE(42)

             d_roi_rect2(2) = ZV_LENTOIMG(0, TABLE(233))

             d_roi_rect2(3) = ZV_LENTOIMG(0, TABLE(234))

             d_roi_rect2(4) = TABLE(235)

             SET_REDRAW
 

         endif

         elseif circle_status=1 then

                 SET_REDRAW

                 is_redraw = 0

                 if (mouse_scan(21) = 1 AND TABLE(21)>0 AND TABLE(21)0 AND TABLE(22)

                     hit_pos = ZV_HMIADJARC(table(21), table(22), 551, -1) '只有按下时可以改变击中位置

                     is_redraw = 1

                 endif
 

                 if (mouse_scan(21) = -1 AND TABLE(21)>0 AND TABLE(21)0 AND TABLE(22)

                     ZV_HMIADJARC(table(21), table(22), 551, hit_pos)

                     is_redraw = 1

                 endif
 

                 if (MOUSE_state(21)) then

                     ZV_HMIADJARC(table(21), table(22), 551, hit_pos)

                     is_redraw = 1

                 endif

                 if (1 = is_redraw) then

                 is_redraw = 0
 

                 '控件坐标转图像坐标

                 ZV_POSTOIMG(0, 1, 551, 61)

                 TABLE(63) = ZV_LENTOIMG(0, TABLE(553))

                 TABLE(64) = ZV_LENTOIMG(0, TABLE(554))

                 TABLE(65, TABLE(555), TABLE(556))

                 d_roi_arc(0) = TABLE(61)

                 d_roi_arc(1) = TABLE(62)

                 d_roi_arc(2) = TABLE(63)

                 d_roi_arc(3) = TABLE(64)

                 d_roi_arc(4) = TABLE(65)

                 d_roi_arc(5) = TABLE(66)

                 SET_REDRAW
 

         endif

     else

         SET_REDRAW

     endif
 

  END SUB
 

  '点,线,圆的绘制函数

  GLOBAL SUB draw_roi()
 

     if point_status = 1 and line_status=0 and circle_status=0 then

         SET_COLOR(C_BLUE)

         ZV_HMIRECT2(31, 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
 

     if line_status=1 and point_status=0 and circle_status=0 then

     SET_COLOR(C_BLUE)

     TABLE(236,d_line_param(4),d_line_param(5)) '测量器扫描数量和宽度

     ZV_HMIRECT2(231, 350)

     DRAWLINE(TABLE(350), TABLE(351), TABLE(352), TABLE(353)) '外矩形

     DRAWLINE(TABLE(352), TABLE(353), TABLE(354), TABLE(355))

     DRAWLINE(TABLE(354), TABLE(355), TABLE(356), TABLE(357))

     DRAWLINE(TABLE(356), TABLE(357), TABLE(350), TABLE(351))
 

     DRAWLINE(TABLE(358), TABLE(359), TABLE(360), TABLE(361)) '方向箭头

     DRAWLINE(TABLE(362), TABLE(363), TABLE(360), TABLE(361))

     DRAWLINE(TABLE(364), TABLE(365), TABLE(360), TABLE(361))
 

     if (0 = TABLE(366)) then return
 

     SET_COLOR(C_GREEN)

     DIM idx

     for idx = 0 to TABLE(366)-1

         DRAWLINE(TABLE(367+idx*4), TABLE(368+idx*4), TABLE(369+idx*4), TABLE(370+idx*4))

     next
 

     endif

  if circle_status=1 and line_status=0 and point_status=0 then
 

     SET_COLOR(C_BLUE)

     TABLE(557) = d_circle_parm(4) '子区域的个数

     TABLE(558) = d_circle_parm(5) '子区域宽度

     ZV_HMIARC(551, 400) '绘制圆环
 

     '绘制圆弧

     DRAWARC(TABLE(400), TABLE(401), TABLE(402), TABLE(404), TABLE(405)) '内半径

     DRAWARC(TABLE(400), TABLE(401), TABLE(403), TABLE(404), TABLE(405)) '外半径

     DRAWLINE(TABLE(400), TABLE(401)-5, TABLE(400), TABLE(401)+5)

     DRAWLINE(TABLE(400)-5, TABLE(401), TABLE(400)+5, TABLE(401))

     '绘制边界线
 

     DIM idx

     for idx = 0 to TABLE(406)-1
 

         DRAWLINE(TABLE(407+idx*4), TABLE(408+idx*4), TABLE(409+idx*4), TABLE(410+idx*4))

     next
 

     SET_COLOR(C_GREEN)

     DIM startid

     startid = 407+TABLE(406)*4

     for idx = 0 to TABLE(startid)-1

     DRAWLINE(TABLE(startid+1+idx*4), TABLE(startid+2+idx*4), TABLE(startid+3+idx*4), TABLE(startid+4+idx*4))

     next

  endif

  END SUB
 

  14.在main.bas文件中添加参数设置界面按下【点测试】按钮时响应的函数,并关联动作函数名。

  '参数界面按下点测量按钮时响应的函数

  GLOBAL SUB btn_meas_p()

     Point_measure()

     ZV_GRAYTORGB(grabImg, latch) '在绘制图形前需要先将灰度图转成RGB图

     ZV_MARKER(latch, draw_point(0), draw_point(1), 0, 20, C_GREEN) '绘制标志点

     ZV_LATCH(latch,0)'显示图像结果

  END SUB
 

  '测量点的实现子函数

  GLOBAL SUB Point_measure()

      ZVOBJECT mr_p, tmp
 

  if d_use_locator=0 then '如果没有使用补正源

          '生成矩形测量器

      ZV_MRGENRECT2(mr_p, d_roi_rect1(0), d_roi_rect1(1),d_roi_rect1(2), d_roi_rect1(3),d_roi_rect1(4), 1)

  endif

  '检测点

      ZV_MRPOS(mr_p, grabImg,tmp,d_point_param(3),d_point_param(2),d_point_param(0),d_point_param(1))

     '获取矩阵对应行的数据

      ZV_MATGETROW(tmp, 0, 3, 386)

          '赋值结果变量,用于绘制图形

      draw_point(0)=TABLE(386)

      draw_point(1)=TABLE(387)
 

     if d_use_calib=1 and is_ca_success=1 then '如果使用标定功能且已经标定成功

         ZV_CALTRANSW(ca_param, TABLE(386),TABLE(387),386) '像素坐标转世界坐标

     endif

  '赋值结果变量,用于显示数据结果

  point_result(0)=TABLE(386)

  point_result(1)=TABLE(387)

  END SUB

  

  15.png

  

  15.在main.bas文件中添加参数设置界面按下【线测试】按钮时响应的函数,并关联动作函数名。

  参数界面按下线测量按钮时响应的函数

  GLOBAL SUB btn_meas_l()

         btn_ml_test()

     ZV_GRAYTORGB(grabImg, latch)'在绘制图形前需要先将灰度图转成RGB图

     ZV_LINE(latch,draw_line(0),draw_line(1),draw_line(2),draw_line(3),zv_color(0,255,0)) '绘制线

     ZV_LATCH(latch,0)'显示图像结果
 

  END SUB
 

  '测量直线的实现子函数

  GLOBAL SUB btn_ml_test()
 

      ZVOBJECT mr_l, tmp
 

     if d_use_locator=0 then '如果没有使用补正源

             '生成直线测量器

         ZV_MRGENLINE(mr_l,d_roi_rect2(0), d_roi_rect2(1),d_roi_rect2(2), d_roi_rect2(3), d_roi_rect2(4), 1,d_line_param(4),d_line_param(5))

     endif

     '设置测量器区域的高级参数,包括滤波尺寸、边缘阈值、边缘极性和边缘位置

     ZV_MRSETADV(mr_l, d_line_param(3), d_line_param(2), d_line_param(0),d_line_param(1))

     '初始化结果数组

     TABLE(486, 0, 0, 0, 0)

     '检测直线,并将结果赋值给起始地址为486的数组

     ZV_MRLINE(mr_l, grabImg, tmp, 486)

     '赋值结果变量,用于绘制图形

     draw_line(0)=TABLE(486)

     draw_line(1)=TABLE(487)

     draw_line(2)=TABLE(488)

     draw_line(3)=TABLE(489)
 

     if d_use_calib=1 and is_ca_success=1 then '如果使用标定功能且已经标定成功

         ZV_CALTRANSW(ca_param, TABLE(486),TABLE(487),486) '像素坐标转世界坐标

         ZV_CALTRANSW(ca_param, TABLE(488),TABLE(489),488) '像素坐标转世界坐标

     endif
 

     '赋值结果变量,用于显示数据结果

     line_result(0)=TABLE(486)

     line_result(1)=TABLE(487)

     line_result(2)=TABLE(488)

     line_result(3)= TABLE(489)
 

  END SUB

  

  16.png

  

  16.添加在main.bas文件中添加参数设置界面按下【圆测试】按钮时响应的函数,并关联动作函数名。

  '参数界面按下圆测量按钮时响应的函数

  GLOBAL SUB btn_meas_c()

             btn_mc_test()'测量圆实现子函数

         ZV_GRAYTORGB(grabImg, latch)'在绘制图形前需要先将灰度图转成RGB图

         ZV_CIRCLE(latch, draw_circle(0),draw_circle(1),draw_circle(2), C_GREEN)'绘制圆

         ZV_LATCH(latch,0)'显示图像结果
 

  END SUB
 

  '测量圆的实现子函数

  GLOBAL SUB btn_mc_test()'测量圆
 

  ZVOBJECT mr_c, tmp

  if d_use_locator=0 then

     '生成环形测量器

     ZV_MRGENCIRCLE(mr_c,d_roi_arc(0), d_roi_arc(1), d_roi_arc(2), d_roi_arc(3),d_roi_arc(4),d_roi_arc(5), 1, d_circle_parm(4),d_circle_parm(5))

  endif
 

  '设置测量参数,包括滤波尺寸、边缘阈值、边缘极性和边缘位置

  ZV_MRSETADV(mr_c,d_circle_parm(3), d_circle_parm(2), d_circle_parm(0),d_circle_parm(1))
 

  '初始化结果数组

  TABLE(586, 0, 0, 0)

  '测量圆,并将结果赋值给起始地址为586的数组

  ZV_MRCIRCLE(mr_c, grabImg, tmp, 586)
 

  '赋值结果变量,用于绘制图形

  draw_circle(0)=TABLE(586)

  draw_circle(1)=TABLE(587)

  draw_circle(2)=TABLE(588)

  if d_use_calib=1 and is_ca_success=1 then '如果使用标定功能且已经标定成功
 

         ZV_CALTRANSW(ca_param, TABLE(586),TABLE(587),590) '像素坐标转世界坐标

         ZV_CALTRANSW(ca_param, TABLE(586)+TABLE(588),TABLE(587),592) '圆心加半径的坐标
 

         '赋值标定结果变量,用于显示数据结果

         circle_result(0)=TABLE(590)

         circle_result(1)=TABLE(591)

         '半径等于圆心点和圆上的点之间的距离

         circle_result(2)=ZV_DISTPP(TABLE(590),TABLE(591),TABLE(592),TABLE(593))
 

         ZV_LATCH(grabImg, 0)
 

         RETURN

     endif
 

     '赋值像素结果变量,用于显示数据结果

     circle_result(0)=TABLE(586)

     circle_result(1)=TABLE(587)

     circle_result(2)=TABLE(588)
 

  END SUB

  17.png

  

  17.在main.bas文件中添加参数设置界面按下【返回运行界面】按钮时响应的函数,并关联动作函数名。

  '参数设置界面按下返回运行界面按钮时响应的函数

  GLOBAL SUB btn_goto_main()

      HMI_CLOSEWINDOW(11)

  END SUB

  18.png

  

  18.添加在运行界面按下【测试】按钮时响应的函数,并关联动作函数名。

  '运行界面按下测试按钮时响应的函数

     GLOBAL SUB btn_test()
 

         TICKS=0'开始计时

     if(d_use_locator=1) then '如果使用补正源
 

         btn_loc_test() '定位

     endif
 

     btn_measure_test() '测量点/线/圆

     d_detect_time=ABS(TICKS)'计算检测消耗时间

  END SUB
 

  '运行界面按下测试按钮时响应的函数

  GLOBAL SUB btn_test()
 

         TICKS=0'开始计时

     if(d_use_locator=1) then '如果使用补正源

         btn_loc_test() '定位
 

     endif
 

     btn_measure_test() '测量点/线/圆

     d_detect_time=ABS(TICKS)'计算检测消耗时间

  END SUB
 

  '点线圆同时测试子函数

  GLOBAL SUB btn_measure_test()
 

     if d_use_locator=1 then '如果使用补正源
 

         '初始化测量器

         ZV_MRGENRECT2(mr_p, d_roi_rect1(0), d_roi_rect1(1),d_roi_rect1(2), d_roi_rect1(3),d_roi_rect1(4), 1)

         ZV_MRGENLINE(mr_l,d_roi_rect2(0), d_roi_rect2(1),d_roi_rect2(2), d_roi_rect2(3), d_roi_rect2(4), 1,d_line_param(4),d_line_param(5))

         ZV_MRGENCIRCLE(mr_c,d_roi_arc(0), d_roi_arc(1), d_roi_arc(2), d_roi_arc(3),d_roi_arc(4),d_roi_arc(5), 1, d_circle_parm(4),d_circle_parm(5))
 

         '计算刚性变换矩阵

         ZV_GETRIGIDVECTOR(mat_rigid2, d_match_base_rst(1), d_match_base_rst(2), d_match_base_rst(3),TABLE(4),TABLE(5), d_match_rst(3))

         ZV_MRCORRECT (mr_p, mat_rigid2, mr_p) '点测量器补正

         ZV_MRCORRECT (mr_l, mat_rigid2, mr_l) '线测量器补正

         ZV_MRCORRECT (mr_c, mat_rigid2, mr_c) '圆测量器补正
 

     endif

     Point_measure() '测量点

     btn_ml_test() '测量线

     btn_mc_test() '测量圆

     ZV_GRAYTORGB(grabImg, latch)

     ZV_MARKER(latch, draw_point(0), draw_point(1), 0, 20, C_BLUE)

     ZV_LINE(latch,draw_line(0),draw_line(1),draw_line(2),draw_line(3),C_BLUE)

     ZV_CIRCLE(latch, draw_circle(0),draw_circle(1),draw_circle(2), C_BLUE)

     ZV_LATCH(latch,0)
 

  END SUB

  19.png

  

  19.添加在运行界面按下【运行】按钮时响应的函数,并关联动作函数名。

  '运行界面按下运行按钮时响应的函数

  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
 

         '持续采集图像,对图像进行操作

         btn_grab()

         btn_test()
 

     wend

  END

  20.png

  

  20.添加在运行界面按下【停止】按钮时响应的函数,并关联动作函数名。

  '运行界面按下停止按钮时响应的函数

  GLOBAL SUB btn_stop()
 

     if (2 = main_task_state) then

                     main_task_state = 3

     endif
 

  END SUB

  21.png

  

  八、仿真效果

  22.png

  23.png

  24.png

  25.png

  26.png

  本次,正运动技术VPLC系列机器视觉运动控制一体机快速入门(八)——测量点/直线/圆,就分享到这里,更多精彩内容请关注“正运动小助手”公众号。

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

  正运动技术专注于运动控制技术研究和通用运动控制软硬件产品的研发,是国家级高新技术企业。正运动技术汇集了来自华为、中兴等公司的优秀人才,在坚持自主创新的同时,积极联合各大高校协同运动控制基础技术的研究,是国内工控领域发展最快的企业之一,也是国内少有、完整掌握运动控制核心技术和实时工控软件平台技术的企业。主要业务有:运动控制卡_运动控制器_EtherCAT运动控制卡_EtherCAT控制器_运动控制系统_视觉控制器__运动控制PLC_运动控制_机器人控制器_视觉定位_XPCIe/XPCI系列运动控制卡等等。


 

状 态: 离线

公司简介
产品目录

公司名称: 深圳市正运动技术有限公司
联 系 人: 戴德弟
电  话: 0755-32976042
传  真: 0755-2606 6955
地  址: 深圳市宝安区西乡洲石路阳光工业园A1栋5楼
邮  编: 518100
主  页:
 
该厂商相关技术文摘:
简单易用的以太网数据采集卡应用开发之C#
机器视觉运动控制一体机在点胶胶路检测上的应用
正运动技术与合作伙伴邀您共聚2024武汉光博会
EtherCAT运动控制器Delta机械手应用
厦门工博会:正运动技术邀您探索智能制造新趋势
开放式激光振镜运动控制器的视觉校正振镜精度解决方案
重庆国际电池展:正运动邀您共赴电池智造交流会
EtherCAT运动控制器的MATLAB开发
成都工博会:正运动技术邀您探索智能制造新趋势
运动控制卡/运动控制器的ZCAN总线ZMIO310扩展模块使用
EtherCAT运动控制器在ROS上的应用(下)
运动控制器/运动控制卡配套ZCAN总线ZIO模块的使用
更多文摘...
立即发送询问信息在线联系该技术文摘厂商:
用户名: 密码: 免费注册为中华工控网会员
请留下您的有效联系方式,以方便我们及时与您联络

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 不良信息举报
工控网客服热线:0755-86369299
版权所有 中华工控网 Copyright©2022 Gkong.com, All Rights Reserved