|  今天,正运动技术为大家分享一下VPLC系列机器视觉运动控制一体机快速入门(四)——BLOB有无检测。   视频教程:《VPLC系列机器视觉运动控制一体机快速入门(四)》      上期课程,我们讲述了机器视觉方案中常用到的基于形状匹配的视觉定位功能,通过上期课程我们掌握了使用ZDevelop软件实现形状匹配功能的方法。   本期课程我们和大家一起分享机器视觉另一个检测功能---使用BLOB检测产品有无。      BLOB又名斑点,是指在二值化图像中暗背景上的一块连通的亮区域或亮背景上一块连通的暗区域。      BLOB检测是使用形态学方法(如二值化、膨胀、腐蚀等)将灰度图像转换成二值化图像,转换同时将检测特征处理成BLOB斑点并将干扰因素处理成图像背景,就可以准确地对检测特征进行处理。      1.依赖形态学处理   需要将检测图像转换成二值化图像,并使用形态学处理图像突出检测特征。   2.不关心形状特征   只要是连通的区域即可检测,不限制产品的形状。   3.适合高对比度产品   BLOB检测要求检测特征和背景要有较好的对比度,否则无法将特征和背景进行区分。   4.执行速度快   转化成二值化图像后搜索BLOB斑点不需要消耗太多时间。      形态学处理是指对图像的局部像素进行处理,用于从图像中提取检测过程中关心的局部特征细节。常用的形态学处理方法有二值化、膨胀、腐蚀、填充孔洞等。    1 二值化   将8位灰度图像(灰度值0~255)转换成非0即1的二值化图像(纯黑和纯白组成的图像)。       2 填充孔洞   在二值化图像中,将某些小面积的黑色或白色的斑点区域进行填充,可过滤噪点。       3 膨胀   将二值化图像中的白色区域扩大,黑色区域缩小,去除黑色小斑点干扰。       4 腐蚀   将二值化图像中的黑色区域扩大,白色区域缩小,可去除白色小斑点干扰。         BLOB检测流程图      // 实例演示 // 1、打开ZDevelop软件:新建项目→新建HMI文件→新建main.bas文件,用于编写界面响应函数→新建global_variable.bas文件用于存放全局变量并开启HMI自动运行任务→新建detectParam.bas文件用于初始化测量参数→新建camera.bas文件用于实现相机采集功能→新建draw.bas文件用于更新绘制图形刷新界面→文件添加到项目。    2、设计HMI界面。    3、在global_variable.bas文件中定义全局变量,定义完成后运行Hmi.hmi文件。    '''''全局变量大部分使用数组结构'''''   ''注:basic编程中很多函数会以TABLE(系统的数据结构)做为参数   ''在这里table均是做为中间变量
   ''table 21-22,鼠标按键,控件坐标系   ''table 31-35,旋转矩ROI参数,cx、cy、width、height、angle,控件坐标系   ''table 41-45,旋转矩形控件坐标转换后对应的图像坐标,图像坐标系
   ''table 51-56,圆环ROI参数,cx、cy、圆环中线半径r、圆环半宽ann_R、起始角度stAngle、角度范围entAngle,控件坐标系   ''table 61-66,圆环控件坐标转换后对应的图像坐标,图像坐标系
   '主任务状态   '0 - 未初始化   '1 - 停止   '2 - 运行中   '3 - 正在停止   GLOBAL DIM main_task_state   main_task_state = 1
   '采集开关   '0 - 停止采集   '1 - 请求采集   GLOBAL DIM grab_switch   grab_switch = 0
   '相机个数   GLOBAL cam_num   cam_num = 0
   '相机种类,"zmotion;mvision;basler;mindvision;huaray"   GLOBAL DIM CAMERA_TYPE(16)   CAMERA_TYPE = "zmotion"
   ' 定义主任务id - 10   GLOBAL DIM main_task_id   main_task_id = 10
   '定义连续采集任务id - 9   GLOBAL DIM grab_task_id   grab_task_id = 9
   '定义全局图像变量   GLOBAL ZVOBJECT grabImg '采集图像   GLOBAL ZVOBJECT binImg '二值化图像   GLOBAL ZVOBJECT disImg '显示图像
   '错误消息   GLOBAL DIM error_msg(256)
   '定义常用颜色变量   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_roi_arc_flag '定义ROI类型标志:0-矩形,1-圆环   GLOBAL DIM d_rlt_area '定义BLOB面积结果   GLOBAL DIM d_rlt_state '定义状态结果
   '旋转矩形ROI参数:cx、cy、width、height、angle   GLOBAL DIM d_roi_rect2(5) 'd开头表示数据结构
   '圆弧ROI参数:cx、cy、圆环中线半径r、圆环半宽ann_R、起始角度stAngle、角度范围entAngle   GLOBAL DIM d_roi_arc(6) 'd开头表示数据结构
   '检测参数:阈值模式(自动阈值或手动阈值)、低阈值、高阈值、极性(黑或白)、最小面积、最大面积、反向(即结果取反,成功变成失败、失败变成成功)   GLOBAL DIM d_detect_param(7) 'd开头表示数据结构
   '开/闭运算参数   GLOBal DIM d_deal_value(2)
   '检测的结果,依次为状态结果、像素面积   GLOBAL DIM d_detect_rst(2)
   '显示打印的字符   GLOBAL ShowString(64)
   '运行HMI文件   RUN "Hmi.hmi",1  4、在detectParam.bas文件中初始化测量参数。   end
   GLOBAL SUB init_detect_param() '初始化测量参数
      d_roi_arc_flag = 0 '默认为矩形      d_rlt_area = 0      d_rlt_state = 0      d_deal_value(0)=1      d_deal_value(1)=1
      '初始化roi参数      d_roi_rect2(0) = 320.0 'roi中心x      d_roi_rect2(1) = 240.0 'roi中心y      d_roi_rect2(2) = 160.0 'roi宽      d_roi_rect2(3) = 120.0 'roi高      d_roi_rect2(4) = 0.0 'roi角度      TABLE(31) = d_roi_rect2(0)      TABLE(32) = d_roi_rect2(1)      TABLE(33) = d_roi_rect2(2)      TABLE(34) = d_roi_rect2(3)      TABLE(35) = d_roi_rect2(4)
      d_roi_arc(0) = 320.0 'roi中心x      d_roi_arc(1) = 240.0 'roi中心y      d_roi_arc(2) = 60.0 '圆环中心线半径      d_roi_arc(3) = 20.0 '圆环半宽      d_roi_arc(4) = 0.0 '起始角度      d_roi_arc(5) = 360.0 '终止角度      TABLE(51) = d_roi_arc(0)      TABLE(52) = d_roi_arc(1)      TABLE(53) = d_roi_arc(2)      TABLE(54) = d_roi_arc(3)      TABLE(55) = d_roi_arc(4)      TABLE(56) = d_roi_arc(5)
      '初始化检测参数:阈值模式(自动阈值 = 1 或 手动阈值 = 0)、低阈值、高阈值、极性(黑或白)、最大、最小、反向(即结果取反,成功变成失败、失败变成成功)      d_detect_param(0) = 0 '手动阈值      d_detect_param(1) = 128 '低阈值      d_detect_param(2) = 255 '高阈值      d_detect_param(3) = 1 '极性白,即检测白色像素面积      d_detect_param(4) = 60000 '最小面积,像素个数      d_detect_param(5) = 90000 '最大面积      d_detect_param(6) = 0 '结果不反向
   END SUB  5、关联HMI界面值显示控件变量。    6、在main.bas文件中添加HMI界面初始化函数并在Hmi系统设置中关联初始化函数。   'HMI界面初始化函数   GLOBAL SUB hmi_init()      grab_switch = 0      main_task_state = 1      ZV_RESETCLIPSIZE(1280, 1024) '初始化时依据图像分辨率设置区域的裁剪尺寸,此处图像分辨率为1280x1024      ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 7), HMI_CONTROLSIZEY(10, 7)) '设置锁存的大小
      init_detect_param() '初始化测量参数
      ZV_SETSYSDBL("CamGetTimeout", 1000) '设置采集超时      ZV_LATCHCLEAR(0)      ZV_LATCH(grabImg, 0)   END SUB
 ↓
  7、在camera.bas文件中添加HMI界面中采集相关按钮响应的函数并关联动作函数。      相机操作相关按钮   具体实现函数前期课程:   VPLC系列机器视觉运动控制一体机快速入门(三)基于形状匹配的视觉定位   VPLC系列机器视觉运动控制一体机快速入门(二)相机的基本使用   VPLC系列机器视觉运动控制一体机快速入门(一)软硬件介绍及计数实例   已经有操作演示,此处不做赘述。 8、在draw.bas文件中添加检测ROI更新绘制函数,并在自定义元件属性窗口中关联刷新函数和绘制函数。   end
   '和绘制(即选择ROI)有关的界面的刷新绘制函数放在这个bas文件里
      DIM is_redraw      is_redraw = 0
      DIM hit_pos
   '根据鼠标操作更新ROI位置区域函数   GLOBAL SUB update_roi()       if d_roi_arc_flag = 0 then           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_rect2(0) = TABLE(41)              d_roi_rect2(1) = TABLE(42)              d_roi_rect2(2) = ZV_LENTOIMG(0, TABLE(33))              d_roi_rect2(3) = ZV_LENTOIMG(0, TABLE(34))              d_roi_rect2(4) = TABLE(35)              SET_REDRAW          endif       else          is_redraw = 0          if mouse_scan(21) = 1 then '扫描按下操作              hit_pos = ZV_HMIADJARC(table(21), table(22), 51, -1) '只有按下时可以改变击中位置              is_redraw = 1          endif
          if mouse_scan(21) = -1 then '扫描松开操作              ZV_HMIADJARC(table(21), table(22), 51, hit_pos)              is_redraw = 1          endif
          if (MOUSE_state(21)) then              ZV_HMIADJARC(table(21), table(22), 51, hit_pos)              is_redraw = 1          endif
      if (1 = is_redraw) then          is_redraw = 0
          '控件坐标转图像坐标          ZV_POSTOIMG(0, 1, 51, 61)          TABLE(63) = ZV_LENTOIMG(0, TABLE(53))          TABLE(64) = ZV_LENTOIMG(0, TABLE(54))          TABLE(65, TABLE(55), TABLE(56))
          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   end if
   END SUB
   'ROI区域更新后实时绘制ROI区域   GLOBAL SUB draw_roi()       if d_roi_arc_flag = 0 then          SET_COLOR(C_BLUE)          ZV_HMIRECT2(31, 300) '将旋转矩形roi分解为HMI支持的绘图图元并添加控制参数,便于HMI绘图显示          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))
       else          SET_COLOR(C_BLUE)          TABLE(57) = 1 '子区域的个数          TABLE(58) = 5 '子区域宽度          ZV_HMIARC(51, 400) '绘制圆环
          '绘制圆弧          DRAWARC(TABLE(400), TABLE(401), TABLE(402), TABLE(404), TABLE(405)) '内半径          DRAWARC(TABLE(400), TABLE(401), TABLE(403), TABLE(404), TABLE(405)) '外半径
           '绘制边界线           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       endif   END SUB
   ↓    9、在main.bas文件中添加HMI界面按下【测试】按钮时响应的函数并关联动作函数名。         ↓   'HMI界面按下测试按钮时响应的函数   GLOBAL SUB btn_test()       ZVOBJECT regionWhite, regionMask, regionBlack,re_connecte
      '生成ROI区域      if d_roi_arc_flag = 0 then          ZV_REGENRECT2(regionMask, d_roi_rect2(0), d_roi_rect2(1), d_roi_rect2(2), d_roi_rect2(3), d_roi_rect2(4))      else          ZV_REGENANNULAR(regionMask, d_roi_arc(0), d_roi_arc(1), d_roi_arc(2) - d_roi_arc(3), d_roi_arc(2) + d_roi_arc(3))      endif
   '二值化处理   if d_detect_param(0) = 0 then '手动阈值处理
      ZV_RETHRESH(grabImg, regionMask, regionWhite, d_detect_param(1), d_detect_param(2))      ZV_REOPENING(regionWhite,regionWhite,d_deal_value(0),d_deal_value(0))      ZV_RECLOSING(regionWhite,regionWhite,d_deal_value(1),d_deal_value(1))
   else
      Dim autoThresh '自动阈值处理      ZV_REAUTOTHRESH(grabImg, regionMask, regionWhite, 500)      ZV_REOPENING(regionWhite,regionWhite,d_deal_value(0),d_deal_value(0))      ZV_RECLOSING(regionWhite,regionWhite,d_deal_value(1),d_deal_value(1))      autoThresh = TABLE(500)      '? "autoThresh = " autoThresh
   endif
   '计算BLOB面积   if d_detect_param(3) = 1 then '极性为白
      ZV_REAREA(regionWhite, 500) '计算regionWhite亮区域的面积      d_rlt_area = TABLE(500) '将获取的像素面积赋值给d_rlt_area变量      ZV_RECONNECT(regionWhite,re_connecte) '计算区域的连通区域      zv_refilter(re_connecte,0,60000,90000,0) '对区域列表中的区域进行过滤,保留面积在 60000 到 90000 的区域,面积不在此范围的区域将被过滤掉      ZV_LISTCOUNT(re_connecte,100) '获取列表中的连通区域的数量      ?"产品个数"TABLE(100)
   else '极性为黑
      ZV_REDIFF (regionMask, regionWhite, regionBlack)      ZV_REAREA(regionBlack, 500)      d_rlt_area = TABLE(500)
      ZV_RECONNECT(regionBlack,re_connecte) '计算区域的连通区域      zv_refilter(re_connecte,0,60000,90000,0) '对区域列表中的区域进行过滤,保留面积在 60000 到 90000 的区域,面积不在此范围的区域将被过滤掉      ZV_LISTCOUNT(re_connecte,100) '获取列表中的连通区域的数量      ?"产品个数"TABLE(100)
   endif
   '对结果进行判断   if d_rlt_area > d_detect_param(4) and d_rlt_area < d_detect_param(5) then '面积结果在设定的面积上下限范围内时       d_rlt_state = 1   else       d_rlt_state = 0   endif
   '是否反向的判断   if d_detect_param(6) then       d_rlt_state = 1 - d_rlt_state   endif
   '绘制效果图   Dim width, height   ZV_IMGINFO (grabImg, 500)   width = TABLE(500)   height = TABLE(501)
   ZV_GRAYTORGB(grabImg,disImg)   ShowString=TOSTR(TABLE(100),1,0) '将BLOB的数量转换成字符串变量
   ZV_TEXT(disImg,"零件统计个数:"ShowString,10,80,80,ZV_COLOR(0,0,0)) '显示结果文本
   ZV_REGION(disImg, regionMask, 0, ZV_COLOR(0,0,0)) '在disImg中绘制黑色的regionMask区域   ZV_REGION(disImg, regionWhite, 0, ZV_COLOR(255,255,255)) '在disImg中绘制白色的regionWhite区域   ZV_LATCH(disImg, 0)
   end sub
   ↓
  
 10、在main.bas文件中添加【运行】按钮响应的函数并关联动作函数。    ↓
   'HMI界面按下运行按钮时响应的函数   GLOBAL SUB btn_run()          if(2 = main_task_state) then              ?"已经开启连续运行任务,请勿重复操作!"          return   endif
   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
          '执行采集和检测函数          CAM_SETPARAM("TriggerSoftware", 0)              CAM_GET(grabImg, 0)          btn_test()
      wend   END   ↓    11、在main.bas文件中添加【停止】按钮响应的函数并关联动作函数。       ↓   'HMI界面按下停止按钮时响应的函数   GLOBAL SUB btn_stop()      if (2 = main_task_state) then          main_task_state = 3      endif
   end sub ↓
          本次,正运动技术VPLC系列机器视觉运动控制一体机快速入门(四)——BLOB有无检测就分享到这里,更多精彩内容请关注“正运动小助手”公众号。   本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。   正运动技术专注于运动控制技术研究和通用运动控制软硬件产品的研发,是国家级高新技术企业。正运动技术汇集了来自华为、中兴等公司的优秀人才,在坚持自主创新的同时,积极联合各大高校协同运动控制基础技术的研究,是国内工控领域发展最快的企业之一,也是国内少有、完整掌握运动控制核心技术和实时工控软件平台技术的企业。主要业务有:运动控制卡_运动控制器_EtherCAT运动控制卡_EtherCAT控制器_运动控制系统_视觉控制器__运动控制PLC_运动控制_机器人控制器_视觉定位_XPCIe/XPCI系列运动控制卡等等。 
 |