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

发布时间:2024-09-26  

此前,我们依次讲解了软硬件介绍及计数实例、相机的基本使用、基于形状匹配的视觉定位以及BLOB有无检测等。


今天,正运动技术为大家分享一下VPLC系列机器视觉运动控制一体机快速入门(五),和大家一起分享机器视觉常用的检测功能---测量尺寸。


运动控制


测量尺寸:在机器视觉中常用的测量尺寸的原理就是使用两个直线测量器,分别检测出产品两条尺寸边缘的点拟合成直线后取两条直线的距离。

尺寸测量本质是基于边缘检测的测量,它需要先检测出亮暗过渡满足一定阈值的边缘点,然后再提取边缘点数据进行处理计算后输出最终的结果。


测量尺寸特点


1.准确度高

选择合适的硬件选型方案可以达到很高的检测精度。常用远心镜头减少畸变,增大景深,减小测量误差。

2.图像干扰少

单纯的测量尺寸项目常用背光的打光方式,突出产品边缘尺寸,过滤表面干扰因素。

3.实现简单

测量尺寸的算法是基于边缘检测的算法,易于实现。

4.需要位置跟随

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

标定


标定是指将机器视觉处理的像素结果(单位:像素)转换成现实中使用到的实际结果(单位:毫米),或者是将机器视觉中使用的图像坐标转换成世界坐标。

我们在实际测量尺寸时,使用的尺寸单位一般是国际标准单位如米,厘米,毫米等。因此机器视觉测量尺寸项目中需要将获取到的像素尺寸转换成实际尺寸(毫米)输出到用户端,供用户直接使用。


测量尺寸标定方法


1.测量标定

使用已知尺寸的标准模块如圆、小方块、或刻度尺等,在图像中检测到像素尺寸后将已知实际尺寸值除以像素值即可得出像素比例值(单位:mm/pixel)。测量尺寸项目中常用测量标定方法。



运动控制

2.坐标标定

输入几组图像坐标(至少9组),然后再输入图像坐标对应的世界坐标,经过公式计算得出矩阵变换系数,即可实现将图像坐标转换到实际坐标。在测量精度要求比较高的测量尺寸项目可以考虑使用坐标标定,具体实现内容我们在下一期课程再做详细说明。



运动控制


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

'创建模板时保存的直线1基准区域位置向量1,x、y、angle

GLOBAL DIM d_meas_base_v1(3)

d_meas_base_v1(0) = 0

d_meas_base_v1(1) = 0

d_meas_base_v1(2) = 0

''创建模板时保存的直线2基准区域位置向量2,x、y、angle

GLOBAL DIM d_meas_base_v2(3)

d_meas_base_v2(0) = 0

d_meas_base_v2(1) = 0

d_meas_base_v2(2) = 0

'直线1测量结果,依次为结果点stx、sty、endx、endy

GLOBAL DIM d_meas_rst1(4)

'直线2测量结果,依次为结果点stx、sty、endx、endy

GLOBAL DIM d_meas_rst2(4)

'定义显示在界面上的长度变量

GLOBAL DIM d_show_rst

''创建模板时保存的模板基准点,score、x、y、angle、scale

GLOBAL DIM d_match_base_rst(5)

global dim d_meas_param(12)

'定义测量标定时使用到的变量

GLOBAL PixLength,WorldLength,CalibParam

2.补充设计主界面。



运动控制


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



运动控制


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

'主界面按下测量设置按钮时响应的函数

GLOBAL SUB Goto_Meas()

HMI_SHOWWINDOW(13)

END SUB



运动控制


5.在InitLocator.bas文件中初始化测量参数。

'---------------------分割线------------------

'初始化测量参数1

d_meas_param1(0) = 320.0 'roi中心x

d_meas_param1(1) = 240.0 'roi中心y

d_meas_param1(2) = 160 'roi宽

d_meas_param1(3) = 120.0 'roi高

d_meas_param1(4) = 0.0 'roi角度

d_meas_param1(5) = 1 '插值方式

d_meas_param1(6) = 20 '子区域的个数

d_meas_param1(7) = 5 '子区域的尺寸

d_meas_param1(8) = 3 '滤波尺寸

d_meas_param1(9) = 50 '阈值

d_meas_param1(10) = 0 '极性

d_meas_param1(11) = 0 '选择边缘位置

'初始化测量参数2

d_meas_param2(0) = 320.0 'roi中心x

d_meas_param2(1) = 240.0 'roi中心y

d_meas_param2(2) = 160 'roi宽

d_meas_param2(3) = 120.0 'roi高

d_meas_param2(4) = 0.0 'roi角度

d_meas_param2(5) = 1 '插值方式

d_meas_param2(6) = 20 '子区域的个数

d_meas_param2(7) = 5 '子区域的尺寸

d_meas_param2(8) = 3 '滤波尺寸

d_meas_param2(9) = 50 '阈值

d_meas_param2(10) = 0 '极性

d_meas_param2(11) = 0 '选择边缘位置

'初始化界面上显示的结果值

d_meas_rst1(0) = 0

d_meas_rst1(1) = 0

d_meas_rst1(2) = 0

d_meas_rst1(3) = 0

d_meas_rst2(0) = 0

d_meas_rst2(1) = 0

d_meas_rst2(2) = 0

d_meas_rst2(3) = 0

d_show_rst = 0

'初始化标定参数和像素比例

CalibParam = 0

WorldLength = 0

PixLength = 0

6.新建在“Set_Select”窗口界面按下【选择测量器区域1】按钮时弹出的“Set_Roi1”窗口,用于创建第一条尺寸边缘的直线测量器并设置检测直线的参数。



运动控制


7.在draw.bas文件中添加在“Set_Select”窗口界面按下【选择测量器区域1】按钮时响应的函数并关联动作函数名。

'-----------------分割线-------------------------

'测量器绘制

DIM is_redraw

is_redraw = 0

DIM set_roi_open_init

set_roi_open_init = 0

DIM sr_mpos_x, sr_mpos_y, hit_pos

'''''''''''''''''''''''''''''''''''

'按下选择测量器区域1按钮时响应的函数

GLOBAL SUB btn_sel_roi1()

ZV_LATCHCLEAR(1) '清除锁存

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

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

SET_COLOR(RGB(0,255,0))

'图像roi转控件roi

is_redraw = 0

TABLE(11, d_meas_param1(0), d_meas_param1(1))

ZV_POSFROMIMG(1, 1, 11, 11) '图像坐标转换到HMI控件坐标

TABLE(13) = ZV_LENFROMIMG(1, d_meas_param1(2))

TABLE(14) = ZV_LENFROMIMG(1, d_meas_param1(3))

TABLE(15) = d_meas_param1(4)

HMI_SHOWWINDOW(14)

END SUB



运动控制


8.在draw.bas文件中添加Roi1根据鼠标操作更新ROI位置的函数以及实时绘制Roi1的函数。

'根据鼠标操作更新Roi1的位置

GLOBAL SUB update_roi1()

if mouse_scan(21) = 1 then '

扫描按下操作

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

?TABLE(21),TABLE(22)

is_redraw = 1

endif

if mouse_scan(21) = -1 then '

扫描松开操作

if TABLE(21)<(table(11)-table(13) or=''>(TABLE(11)+TABLE(13)/2) or TABLE(22)<(table(12)-table(14) or=''>(TABLE(12)+TABLE(14)/2) then

hit_pos=-1

endif

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

?*TABLE(11,4)

is_redraw = 1

endif

if (MOUSE_state(21)) then

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

is_redraw = 1

endif

if (1 = is_redraw) then

is_redraw = 0

ZV_POSTOIMG(1, 1, 11, 31)

d_meas_param1(0) = TABLE(31)

d_meas_param1(1) = TABLE(32)

d_meas_param1(2) = ZV_LENTOIMG(1, TABLE(13))

d_meas_param1(3) = ZV_LENTOIMG(1, TABLE(14))

d_meas_param1(4) = TABLE(15)

'如果选择了补正源,就保存roi基准

if(TABLE(110) = 1) then

set_base_roi()

endif

SET_REDRAW

endif

END SUB

'设置测量区域的基准roi

GLoBAL SUB set_base_roi()

d_meas_base_v1(0) = d_meas_param1(0)

d_meas_base_v1(1) = d_meas_param1(1)

d_meas_base_v1(2) = d_meas_param1(4)

d_meas_base_v2(0) = d_meas_param2(0)

d_meas_base_v2(1) = d_meas_param2(1)

d_meas_base_v2(2) = d_meas_param2(4)

END SUB

'更新Roi1位置后实时绘制图形

GLOBAL SUB draw_roi1()

SET_COLOR(C_BLUE)

TABLE(16, d_meas_param1(6), d_meas_param1(7)) '设置子区域个数和宽度两个参数

ZV_HMIRECT2(11, 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))

if (0 = TABLE(316)) then return

SET_COLOR(C_GREEN)

DIM idx

for idx = 0 to TABLE(316)-1

DRAWLINE(TABLE(317+idx*4), TABLE(318+idx*4), TABLE(319+idx*4), TABLE(320+idx*4))

next

END SUB

9.在draw.bas文件中添加在“Set_Roi1”窗口界面按下【确定】按钮时响应的函数并关联动作函数名。

'设置Roi1窗口按下确定按钮时响应的函数

GLOBAL SUB btn_meas_confirm1()

HMI_CLOSEWINDOW(14)

END SUB



运动控制


10.新建在“Set_Select”窗口界面按下【选择测量器区域2】按钮时弹出的“Set_Roi2”窗口,用于创建第二条尺寸边缘的直线测量器并设置检测直线的参数。



运动控制


11.在draw.bas文件中添加在“Set_Select”窗口界面按下【选择测量器区域2】按钮时响应的函数并关联动作函数名。

'按下选择测量器区域2按钮时响应的函数

GLOBAL SUB btn_sel_roi2()

ZV_LATCHCLEAR(1) '清除锁存

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

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

SET_COLOR(RGB(0,255,0))

'图像roi坐标转控件roi

is_redraw = 0

TABLE(11, d_meas_param2(0), d_meas_param2(1))

ZV_POSFROMIMG(1, 1, 11, 11) '图像坐标转换到HMI控件坐标

TABLE(13) = ZV_LENFROMIMG(1, d_meas_param2(2))

TABLE(14) = ZV_LENFROMIMG(1, d_meas_param2(3))

TABLE(15) = d_meas_param2(4)

HMI_SHOWWINDOW(15)

END SUB



运动控制


12.在draw.bas文件中添加Roi2根据鼠标操作更新ROI位置的函数以及实时绘制Roi1的函数。

'根据鼠标操作更新Roi2的位置

GLOBAL SUB update_roi2()

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

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

is_redraw = 1

endif

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

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

is_redraw = 1

endif

if (MOUSE_state(21)) then

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

is_redraw = 1

endif

if (1 = is_redraw) then

is_redraw = 0

ZV_POSTOIMG(1, 1, 11, 31)

d_meas_param2(0) = TABLE(31)

d_meas_param2(1) = TABLE(32)

d_meas_param2(2) = ZV_LENTOIMG(1, TABLE(13))

d_meas_param2(3) = ZV_LENTOIMG(1, TABLE(14))

d_meas_param2(4) = TABLE(15)

'如果选择补正源,就保存roi基准位置

if(TABLE(110) = 1) then

set_base_roi()

endif

SET_REDRAW

endif

END SUB

'更新Roi2位置后实时绘制图形

GLOBAL SUB draw_roi2()

SET_COLOR(C_BLUE)

TABLE(16, d_meas_param2(6), d_meas_param2(7)) '设置子区域个数和宽度两个参数

ZV_HMIRECT2(11, 300) '计算控件的矩形roi相应的顶点和箭头锚点

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

if (0 = TABLE(316)) then return

SET_COLOR(C_GREEN)

DIM idx

for idx = 0 to TABLE(316)-1

DRAWLINE(TABLE(317+idx*4), TABLE(318+idx*4), TABLE(319+idx*4), TABLE(320+idx*4))

next

END SUB

13.在draw.bas文件中添加在“Set_Roi2”窗口界面按下【确定】按钮时响应的函数并关联动作函数名。

'设置Roi2窗口按下确定按钮时响应的函数

GLOBAL SUB btn_meas_confirm2()

HMI_CLOSEWINDOW(15)

END SUB



运动控制


14.新建meas.bas文件用于存放计算两条直线的距离函数和标定函数等测量相关函数,并在文件中添加实现函数。

'计算两条直线的距离宽度

global sub length1()

LOCAL dist,dist1,dist2

local dis_tmp,dst_tmp1

'计算直线2的起始点到直线1之间的距离

dist = ZV_DISTPL(d_meas_rst2(0),d_meas_rst2(1),d_meas_rst1(0),d_meas_rst1(1),d_meas_rst1(2),d_meas_rst1(3))

'计算直线2的终点到直线1之间的距离

dist1 = ZV_DISTPL(d_meas_rst2(2),d_meas_rst2(3),d_meas_rst1(0),d_meas_rst1(1),d_meas_rst1(2),d_meas_rst1(3))

'计算直线2的中点位置坐标

dis_tmp=(d_meas_rst2(0)+d_meas_rst2(2))/2

dst_tmp1=(d_meas_rst2(1)+d_meas_rst2(3))/2

'计算直线2的中点到直线1之间的距离

dist2 = ZV_DISTPL(dis_tmp,dst_tmp1,d_meas_rst1(0),d_meas_rst1(1),d_meas_rst1(2),d_meas_rst1(3))

TABLE(500)=(dist+dist1+dist2)/3 '两直线之间的距离

PixLength=TABLE(500)

?TABLE(500)

end sub

'计算实际尺寸值

global sub length2()

'实际尺寸=像素尺寸*像素比例

TABLE(501)=TABLE(500)*CalibParam

end sub

'计算像素比例,即实际值/像素值

global sub calculation()

CalibParam=WorldLength/TABLE(500)

end sub

15.在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_rigid, 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_rigid, d_meas_base_v1(0), d_meas_base_v1(1),d_meas_base_v1(2), 0)

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>