机器视觉运动控制一体机应用例程(六)液位检测

顺应现代生活的不断发展,瓶装液体成为人们日常生活中不可或缺的消费品。它的包装中产品净含量是否达标是检测产品质量的一个重要指标,对于同一规格的包装瓶中,其液位高度直接反映了瓶中液体的净含量。
在传统的瓶装液体灌装工序中,其灌装后的液位高度检测通常采用的是人眼去目测液位高度,生产效率低下,且会产生较大误差。随着生产的规模的不断扩大,因此对瓶装液体的液位高度全自动检测的需求越来越大。
目前市面上已有光电传感器检测、超声波检测和机器视觉液位检测等液位检测方法,其中机器视觉液位检测是一种非接触式、无损的检测方法。因此它具有效率高、检测精度高、设备维护简单等优点,被广泛应用于液位检测项目中。
本次课程我们将与大家一起分享机器视觉运动控制一体机实现液位检测的功能。
16:11
液位检测:在机器视觉解决方案中,通常使用背向打光的方式将瓶内有液体的部分和没有液体的部分加以区分,再计算出液体最高位与瓶底的距离即液位。检测有颜色的液体通常使用普通背光源即可,如需检测透明液体或瓶子上有字符或颜色干扰可使用穿透性较强的红外背光。
视觉算法:使用两个直线测量器获得瓶底和液位的数据,再计算瓶底和液位的距离。使用形状匹配结果作为直线测量器的补正源,使直线测量器跟随产品移动。


(一)软件实现
1.打开ZDevelop软件:打开项目“基于形状匹配的视觉定位”→在“global_variable.bas”文件中定义测量尺寸需要用到的全局变量。
'----------------------------分割线-----------------------------------------
'直线1测量参数数组,依次为中心cx、cy、w、h、angle、interp、sub_num、sub_width、filter_size、thresh、polor、select,都是图像坐标GLOBAL DIM d_meas_param1(12) 'd开头表示数据结构
'直线2测量参数数组,依次为中心cx、cy、w、h、angle、interp、sub_num、sub_width、filter_size、thresh、polor、select,都是图像坐标GLOBAL DIM d_meas_param2(12) 'd开头表示数据结构
'定义常用颜色变量,用于绘制图形GLOBAL C_RED, C_GREEN, C_BLUE, C_YELLOWC_RED = RGB(255, 0, 0)C_GREEN = RGB( 0,255, 0)C_BLUE = RGB( 0, 0,255)C_YELLOW= RGB(255,255, 0)
'创建模板时保存的直线1基准区域位置向量1,x、y、angleGLOBAL DIM d_meas_base_v1(3)d_meas_base_v1(0) = 0d_meas_base_v1(1) = 0d_meas_base_v1(2) = 0
'创建模板时保存的直线2基准区域位置向量2,x、y、angleGLOBAL DIM d_meas_base_v2(3)d_meas_base_v2(0) = 0d_meas_base_v2(1) = 0d_meas_base_v2(2) = 0
'直线1测量结果,依次为结果点stx、sty、endx、endyGLOBAL DIM d_meas_rst1(4)
'直线2测量结果,依次为结果点stx、sty、endx、endyGLOBAL DIM d_meas_rst2(4)
''创建模板时保存的模板基准点,score、x、y、angle、scaleGLOBAL DIM d_match_base_rst(5)global dim d_meas_param(12)
'定义ROI标志变量,0-液位ROI,1-瓶底ROIGLOBAL DIM roi_flagroi_flag=0
'定义形状匹配模板ZVOBJECT shape_model
'定义保存配模板标志,1-已保存,0未保存GLOBAL DIM is_saveMod2.修改设计HMI界面。

3.新建主界面按下【液位设置】按钮时弹出的液位参数设置窗口“Set_Select”,并设计界面布局。

4.关联液位参数设置窗口“Set_Select”界面上的变量。

5.在“draw.bas”文件中添加“液位Roi”和“瓶底Roi”根据鼠标操作更新ROI位置的函数以及实时绘制Roi的函数,并在自定义元件中关联刷新函数和绘制函数。
'-----------------分割线-------------------------'测量器绘制''''''''''''''''''''''''''''''''''''根据鼠标操作更新Roi的位置GLOBAL SUB update_roi()if roi_flag=0 then '如果选择设置液位ROISET_REDRAW'全区域绘制if (mouse_scan(21) = 1 )then '如果扫描到鼠标按下操作'根据鼠标所在Roi的不同位置返回调整标志hit_pos = ZV_HMIADJRECT2(table(21), table(22), 11, -1)is_redraw = 1'绘图标志置1endifif mouse_scan(21) = -1 then '如果扫描到鼠标松开操作'如果鼠标指在Roi1区域之外if TABLE(21)<(TABLE(11)-TABLE(13)/2) or TABLE(21)>(TABLE(11)+TABLE(13)/2) or TABLE(22)<(TABLE(12)-TABLE(14)/2)or TABLE(22)>(TABLE(12)+TABLE(14)/2) thenhit_pos=-1'调整标志=-1endifZV_HMIADJRECT2(table(21), table(22), 11, hit_pos)'调整Roi1位置is_redraw = 1endifif (MOUSE_state(21)) then'如果鼠标按下时ZV_HMIADJRECT2(table(21), table(22), 11, hit_pos)'调整Roi1位置is_redraw = 1'绘图标志置1endifif (1 = is_redraw ) then'如果绘图标志为1时is_redraw = 0'绘图标志置0'将控件坐标转换到图像坐标,并赋值给相应变量ZV_POSTOIMG(0, 1, 11, 31)d_meas_param1(0) = TABLE(31)d_meas_param1(1) = TABLE(32)d_meas_param1(2) = ZV_LENTOIMG(0, TABLE(13))d_meas_param1(3) = ZV_LENTOIMG(0, TABLE(14))d_meas_param1(4) = TABLE(15)set_base_roi()'设置基准Roi数据SET_REDRAW'全区域绘制endifelse '否则选择设置瓶底ROISET_REDRAW'全区域绘制if (mouse_scan(21) = 1 )then '如果扫描到鼠标按下操作'根据鼠标所在Roi的不同位置返回调整标志hit_pos = ZV_HMIADJRECT2(table(21), table(22), 41, -1)is_redraw = 1'绘图标志置1endifif mouse_scan(21) = -1 then '如果扫描到鼠标松开操作'如果鼠标指在Roi2区域之外if TABLE(21)<(TABLE(41)-TABLE(43)/2) or TABLE(21)>(TABLE(41)+TABLE(43)/2) or TABLE(22)<(TABLE(42)-TABLE(44)/2)or TABLE(22)>(TABLE(12)+TABLE(14)/2) thenhit_pos=-1'调整标志=-1endifZV_HMIADJRECT2(table(21), table(22), 41, hit_pos)'调整Roi2位置is_redraw = 1endifif (MOUSE_state(21)) then'如果鼠标按下时ZV_HMIADJRECT2(table(21), table(22), 41, hit_pos)'调整Roi2位置is_redraw = 1'绘图标志置1endifif (1 = is_redraw ) then'如果绘图标志为1时is_redraw = 0'绘图标志置0'将控件坐标转换到图像坐标,并赋值给相应变量ZV_POSTOIMG(0, 1, 41, 91)d_meas_param2(0) = TABLE(91)d_meas_param2(1) = TABLE(92)d_meas_param2(2) = ZV_LENTOIMG(0, TABLE(43))d_meas_param2(3) = ZV_LENTOIMG(0, TABLE(44))d_meas_param2(4) = TABLE(45)set_base_roi()'设置基准Roi数据SET_REDRAW'全区域绘制endifendifEND SUB

6.在“main.bas”文件中添加“Set_Select”窗口界面按下【测试】按钮时响应的函数并关联动作函数名。
'液位设置界面按下测试按钮时响应的函数GLOBAL SUB btn_mea_test() '选择补正源时先执行定位检测 if(TABLE(110) = 1) then btn_loc_test() endif ZVOBJECT mr1,mr2,mr3,mr4,rst1,rst2,rst3,rst4,colorImg ZVOBJECT contlist, tsContlist, mat_rigid LOCAL show_rst '测量区域roi补正 if(TABLE(110) = 1 AND d_is_creModel = 1) then '如果使用补正源已经开启且模板已经创建 '计算刚性变换矩阵 ZV_GETRIGIDVECTOR(mat_rigid1,d_match_base_rst(1),d_match_base_rst(2),d_match_base_rst(3), d_match_rst(1), d_match_rst(2), d_match_rst(3)) '使用变换矩阵mat_rigid对输入Roi1基准向量进行补正,补正后的向量存入开始索引为0的TABLE中 ZV_VECTORCORRECT(mat_rigid1, d_meas_base_v1(0), d_meas_base_v1(1),d_meas_base_v1(2), 0) '将补正后的坐标数据赋值给测量器区域变量 d_meas_param1(0) = TABLE(0) d_meas_param1(1) = TABLE(1) d_meas_param1(4) = TABLE(2) '使用变换矩阵mat_rigid对输入Roi2基准向量进行补正,补正后的向量存入开始索引为0的TABLE中 ZV_VECTORCORRECT(mat_rigid1, d_meas_base_v2(0), d_meas_base_v2(1),d_meas_base_v2(2), 0) '将补正后的坐标数据赋值给测量器区域变量 d_meas_param2(0) = TABLE(0) d_meas_param2(1) = TABLE(1) d_meas_param2(4) = TABLE(2) endif '生成直线1测量的旋转区域 ZV_MRGENLINE(mr1, d_meas_param1(0), d_meas_param1(1), d_meas_param1(2), d_meas_param1(3), d_meas_param1(4), 1, d_meas_param1(6), d_meas_param1(7)) '设置直线1的检测参数,包括滤波器尺寸,阈值,边缘极性,边缘位置 ZV_MRSETADV(mr1, d_meas_param1(8), d_meas_param1(9), d_meas_param1(10), d_meas_param1(11)) '生成直线2测量的旋转区域 ZV_MRGENLINE(mr2, d_meas_param2(0), d_meas_param2(1), d_meas_param2(2), d_meas_param2(3), d_meas_param2(4), 1, d_meas_param2(6), d_meas_param2(7)) '设置直线2的检测参数,包括滤波器尺寸,阈值,边缘极性,边缘位置 ZV_MRSETADV(mr2, d_meas_param2(8), d_meas_param2(9), d_meas_param2(10), d_meas_param2(11)) '将矩形测量区域测量到的目标直线1端点存储到起始索引为61的TABLE ZV_MRLINE(mr1, grabImg, rst1, 61) '将直线1结果赋值给直线1结果变量 d_meas_rst1(0) = TABLE(61) d_meas_rst1(1) = TABLE(62) d_meas_rst1(2) = TABLE(63) d_meas_rst1(3) = TABLE(64) '将矩形测量区域测量到的目标直线2端点存储到起始索引为71的TABLE ZV_MRLINE(mr2, grabImg, rst2, 71) '将直线1结果赋值给直线2结果变量 d_meas_rst2(0) = TABLE(71) d_meas_rst2(1) = TABLE(72) d_meas_rst2(2) = TABLE(73) d_meas_rst2(3) = TABLE(74) '计算两条直线的距离宽度 length1() '将灰度图转换成RGB图像,用于绘制检测结果图像 ZV_GRAYTORGB(grabImg, colorImg) '绘制液位检测和瓶底检测的测量器 ZV_MEASURER(colorImg,mr1,ZV_COLOR(0,0,255),ZV_COLOR (0,255,0)) ZV_MEASURER(colorImg,mr2,ZV_COLOR(0,0,255),ZV_COLOR (0,255,0)) '绘制直线结果 ZV_LINE(colorImg, TABLE(61), TABLE(62), TABLE(63), TABLE(64), C_BLUE) ZV_LINE(colorImg, TABLE(71), TABLE(72), TABLE(73), TABLE(74), C_BLUE) if(TABLE(110) = 1) then'如果使用补正源 ZV_MARKER(colorImg,TABLE(4),TABLE(5),0,10,C_GREEN)'绘制匹配中心标志点 endif ZV_LATCH(colorImg,0)'显示结果图像 END SUB
7.在“main.bas”文件中添加“Set_Select”窗口界面按下【返回主界面】按钮时响应的函数并关联动作函数名。
'按下返回主界面按钮时响应的函数GLOBAL SUB Goto_Main()'设置锁存通道0的大小,以适应图片元件大小ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10,2), HMI_CONTROLSIZEY(10,2))ZV_LATCHCLEAR(0)'清空锁存通道0ZV_LATCH(grabImg,0)'将图片显示到锁存通道0中HMI_CLOSEWINDOW(13)'关闭测量参数设置窗口END SUB

8.在“main.bas”文件中修改主界面按下【单次执行】按钮时响应的函数并关联动作函数名。
'主界面按下单次执行按钮时响应的函数GLOBAL SUB btn_test()
'采集一帧图像 btn_grab '执行测量测试部分代码 btn_mea_test()
END SUB(一)操作步骤
查看运行效果:将项目下载到仿真器中→运行程序,测试程序运行效果。→使用本地图片→单次采集→学习模板→液位设置→使用补正源→单次执行→结束
