打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
机器视觉之halcon入门(8)-一文弄懂如何用相机测量物体长度

第三节 测量

3.3.1 简单的啰嗦几十句

所谓的测量,主要是测量出物理尺寸,就是我们现实中所说的尺寸。毕竟算出像素尺寸实在是不是太难。Halcon里面的物理尺寸测量分1d,2d,3d测量,作为入门书籍我们这儿只讲1d的,就是长度测量。比如咱们的标定板长度的测量。有没有很想学?哈哈……

3.3.2 言归正传

图 3-3-2-1

如上图(3-3-2-1),单击助手里面的第四个选项'Measure'。会弹出下图(3-3-3-2),在输入栏有两个参数需要我们来填,第一个是第一红框里面的,待测量图片的来源,可以选择你已经拍好的照片,就是图像文件,单击那一行后面小框框可以选择图片路径,下一行是通过图像采集助手,就是相机采集图片来测量,如果你还没有打开图像采集助手,一选中就会自动弹出图像采集助手来帮你选择相机,本章第一节刚好你学了连接相机,怎么利用图像采集助手实在是难不倒你。如果你选中后面的'实时采集',就可以实时采集每一张图片来进行测量了。一切配置好后,下面一个框内是要相机的内参外参了,上一节刚好学的标定。希望你有保存。'.cal'和'.dat'刚好就对应了两个参数保存文件的格式。还是点击最后面的小框添加。

图 3-2-2-2

一切配置好后,就可以进入第二页选项卡如下图:此时你halcon的图像窗口应该是在实时显示的图片。把标定板放进视野中,如下图(3-3-2-3)。

图 3-3-2-3

图 3-3-2-4

然后选择上图(3-3-2-4)中最上你们的小方框,这是画直线的功能,到halcon图像窗口中画一条测量的线,保证这条线穿过要测量的物体的两个边缘,如下图(3-3-2-5):

图 3-3-2-5

通常情况下,还是要调整下上图(3-3-2-4)中红框框内的三种参数:最小边缘幅度,意思是说halcon自己沿着线路找边缘,当某个地方灰度值差大于这个幅度的时候就认为它为边缘。平滑,是指对图片进行平滑,如果你的图片噪声多,干扰多,则需要平滑。ROI宽,其实halcon测量是在一个矩形ROI里面测量,你画的直线相当于这个矩形的长边中心轴线,这根线的长度就是这个矩形的长了,那这个矩形的宽就取决于你在这儿设置的ROI的宽了,而且halcon会在直线的边缘上显示你的ROI的宽,让你看到它找出来的边缘,所以我通常喜欢把ROI宽设置大一点,如下图(3-3-2-6):

图 3-3-2-6

看图中的垂直的绿线,它显示的就是矩形ROI的宽了,你也可以通过这个看看边缘是否找到,找到的是否准确。第四行的是插值方法,(具体的插值方法简介,详见本节TIPS 1)我建议选第二种吧。

接下来是边缘选择里面的变换和位置,如下图(3-3-2-7):

图 3-3-2-7

变换里面有positive和negative,positive是指灰度值由暗到亮的边缘,negative是指灰度值由亮到暗的边缘,你自己去挨个选择下,然后看看效果就知道了。All就是都选的意思咯。下面的位置里面还有first和last,这个实在不用我去啰嗦什么是first的位置什么是last的位置了吧。善意提醒下,你画的那条线是有方向的,由起始位置指向结束位置。咱们这就两个都选all吧。再往下的那些就是些辅助功能了,有兴趣的自己看下也能一目了然,不用讲解的。选项卡第三栏是模糊,对图像进行各种模糊的,咱们初级的用不上。直接跳过到结果栏:

图 3-3-2-7

是的,结果已经出来啦!如上图(3-3-2-7),单位在右上角是mm。因为有两个边缘,所以有两行数据,每一行分别是每个边缘点的坐标和幅度,这个幅度是指,沿着你画的测量直线的方向,每个边缘点左右两边的灰度差。本例中第1个点是由黑色背景到白色标定板,所以灰度值上升了39.7639,第2个点是由白色标定板重新进入黑色背景,所以幅度变化就是负值了。那为什么两个幅值的绝对值不一样呢?因为我打光不均匀呗~笨!下面一个就是你最关注的的距离了,表示距离下一个边缘点的距离,因为只有两个点,所以第二个点的距离参数就没有了。那么这个70.526mm就是两个点之间的物理距离了,也就是这块标定板中间白色部分的宽度。测的准不准呢?你自己看吧!如下图(3-3-2-8)。(友情提示:如果你的数据一直在跳动,就说明你一开始点击了实时采集,所以它就在一直对新采集的图片进行测量,我的就是这样。)

图 3-3-2-8

到这儿,这个测量咱们算是结束啦。感兴趣的话可以继续拿一些其它东西来测测,看看准不准。但是如果要写代码怎么写呢?让我们在选项卡代码生成里面点击'插入代码'吧。代码如下图(3-3-2-9)。

图 3-3-2-9

别被这一页纸的陌生代码吓到了,其实关键代码没几步,很多都是赋值和重复,让我来一点点的分析给你听。首先是打开相机,接下来是相机的内参外参赋值,这些你都有的,也都会的。然后设置了边缘最小幅度,就是之前在助手里面第二页选项卡边缘下设置的第一个参数。然后是ROI的宽的一半,看我上面截图里面是60,这儿它设置成30了,当然自有妙用,五分钟后你就知道了。接下来是算子:

set_system ('int_zooming', 'true'):这个算子是设置系统的意思,怎么个设置法?第一个参数就是你要设置的系统参数名,第二个就是系统参数值,相当于一个是name,一个是value。本例中这个参数的意思就是说,你如果选择了true,那么对图像缩放的时候所有的数值都用整数来算,减少运算量嘛。

接下来四行代码就是画那根线的起始终止点的坐标了。不要被它的命名吓唬到了,其实就是两个点的纵横坐标,再接下来的七行又是什么呢,就是测量用的那个矩形了。还记得我说的其实halcon里面的测量是在一个矩形内吗?那你还记得如果生成一个带角度的矩形需要哪些参数吗?就是gen_rectangele2()后面的参数啦。需要矩形的中心点坐标(两个参数),矩形的角度(一个参数),矩形的长宽的一半(两个参数)。一共五个参数。分别对应接下来七行里面的17,18,21,22,23行。19,20行是用来求角度phi的。因为这个矩形的角度你又没设置,只好自己算了,拿你画的那条线的起始点的纵坐标做差,横坐标再做差,然后atan()就可以了,就是21行的算子啦。这样分析是不是好懂很多。。有了这些参数就要画测量的矩形了!

gen_measure_rectangle2(TmpCtrl_Row,TmpCtrl_Column,TmpCtrl_Phi,TmpCtrl_Len1, TmpCtrl_Len2, 2588, 1940, 'bilinear', MsrHandle_Measure_01_0):这才是本例第一个灵魂算子,就是生成一个测量用的2型矩形。第一第二个参数就是矩形中心点的坐标啦,第三个参数就是矩形的角度,第四第五个参数就是这个矩形长短边的二分之一长度啦。第六第七个参数就是整张图片的宽高,第八个参数是插值方法,本例我选的是双线性插值法;第九个参数就是生成这个矩形所存的句柄。

生成这个测量的矩形后,就是要开始测量了嘛!可是我们好像还没有图片。。。所以接下来肯定是抓取图片啦,如下图(3-3-2-10):

图 3-3-2-10

因为我在助手第一页选择了实时获取,所以这儿给加了一个死循环while(true)。不要在意这些细节。接着看里面的循环体:

grab_image (Image, AcqHandle):抓取图片,属于同步获取。第一个参数是抓到的图片,第二个参数是抓图片的相机的句柄。这个算子很简单了,没什么好讲的。下面一个是重点:

measure_pos(Image,MsrHandle_Measure_01_0,1,AmplitudeThreshold,'all','all',Row_Measure_01_0,Column_Measure_01_0,Amplitude_Measure_01_0,Distance_Measure_01_0):提取垂直于矩形的边缘并测量。这个算子参数本来就多,halcon还给每个参数起这么长的名字。实在是醉了,也不怕吓到我的读者……,话说回来,以后我们会遇到参数更多的算子的。下面我来说说每个参数的意思吧,第一个参数就是要测量的图像啦;第二个参数是测量矩形的句柄;就是上一个算子画出来的那个矩形啦;第三个参数是高斯平滑系数,这个在助手里面也有设置;第四个参数是最小边缘幅度,开头赋值的那个,在这儿用到了;第五个参数是转换,对应的是第二个选项卡下面边缘里面的那个转换,我们选all的还记得吗?所以第六个参数就是剩下的那个位置参数啦!也是all;第七第八第九第十个参数就是分别对应结果选项卡里面输出的内容,分别为边缘点的纵、横坐标,幅度变化值,以及距离。但是!这些都是相机的像素坐标,以及像素距离,因为我们的相机的内参和外参还没有告诉算子呢。所以我们还需要接下来一步:

image_points_to_world_plane(CameraParameters,CameraPose,Row_Measure_01_0,Column_Measure_01_0,0.001,Column_World_Measure_01_0,Row_World_Measure_01_0):啥意思来着?上一节说过!当时可能有点不知道怎么用,现在是不是有恍然大悟的赶脚?也算是学以致用了。其中scale参数0.001就是mm的意思了呗。这个算子在这儿的作用就是把上面测得的边缘点纵横坐标转换成空间物理坐标。这些转了,再利用欧几里得距离公式,就可以求出来实际距离了,实在是不难:

思路是很简单,但是halcon把它整的有点小复杂,显摆了一个算子,加了一个if判断逻辑。判断求出来的物理边缘点的纵坐标的个数,肯定是2个啦,因为两个边缘点嘛。然后:

tuple_select_range(Row_World_Measure_01_0,0,TmpCtrl_Length-2,TmpCtrl_RowFrom):这个算子的意思是从一个数组里面筛选元素,1个或多个都行。第一个参数是数组,第二个参数,第三个参数是筛选的元素是从数组的序号几到几,第四个参数是输出。本例中,就是提取世界坐标下纵坐标数组(Row_World_Measure_01_0)里面从第0个到第0(TmpCtrl_Length - 2=0)个元素,那就是第0个了呗。这样的算子重复了四次,还有三次分别是世界坐标系下横坐标数组里面从第0个到第0个元素,世界坐标系下纵坐标数组里面从第1个到第1(TmpCtrl_Length - 1=1)个元素,世界坐标系下横坐标参数里面从第1个到第1个元素。说白了就是提取出世界坐标系下两个坐标点的横纵坐标。然后欧几里得:

distance_pp(TmpCtrl_RowFrom,TmpCtrl_ColumnFrom,TmpCtrl_RowTo,TmpCtrl_ColumnTo, Distance_World_Measure_01_0):求点与点之间的距离。pp的意思就是point-point。前面四个参数就是两个点的横纵坐标,第五个参数是输出,即距离。这是一个数学公式。(更多distance相关的算子详见本节 TIPS 2)

这个输出就是结果啦,最后就是:

close_measure (MsrHandle_Measure_01_0):关掉测量对象。毕竟做事有始有终嘛!

至此,一次完整的测量,从使用助手开始,到代码的学习都算是全套完成了。现在如果有一个生产标定板的生产线,需要你在产线最后加一套视觉系统,检测标定板的长宽和各个圆圆心之间的距离是否符合要求。你会怎么做?从相机、镜头、光源的选型开始,平台怎么搭建,怎么打光。一切就绪后,软件部分怎么写?相机的连接,标定,测量等等全套。最后再转成C#代码生成exe执行文件。虽然这个项目暂时不能给你,但是你可以从头到尾想一下。如果全套你都能做,那么我写这本书的目的也算是达到很大一部分了。助手总共有5个,还有两个一个是模板匹配,一个是OCR的识别。这两个我就不讲了。模板匹配的例程我会在后面有讲解,明白了例程,知道了什么是模板匹配,你再回头弄这个助手,简直不要太容易。所以就算我写,那时候你也懒得看了。

还是回到本节,大家一起复习下本节的算子:

1)set_system ('int_zooming', 'true'):

2)gen_measure_rectangle2(TmpCtrl_Row,TmpCtrl_Column, TmpCtrl_Phi, TmpCtrl_Len1, TmpCtrl_Len2, 2588, 1940, 'bilinear', MsrHandle_Measure_01_0):

3)grab_image (Image, AcqHandle):

4)measure_pos(Image,MsrHandle_Measure_01_0,1,AmplitudeThreshold,'all','all',Row_Measure_01_0,Column_Measure_01_0,Amplitude_Measure_01_0,Distance_Measure_01_0):

5)image_points_to_world_plane(CameraParameters,CameraPose,Row_Measure_01_0,Column_Measure_01_0,0.001,Column_World_Measure_01_0,Row_World_Measure_01_0):

6)tuple_select_range(Row_World_Measure_01_0,0,TmpCtrl_Length-2,TmpCtrl_RowFrom):

7)distance_pp(TmpCtrl_RowFrom,TmpCtrl_ColumnFrom,TmpCtrl_RowTo,TmpCtrl_ColumnTo, Distance_World_Measure_01_0):

8)close_measure (MsrHandle_Measure_01_0):

本节TIPS:

1)

,如图,点开这个下拉窗口,会发现插值方法有三种:nearest_neighbor,bilinear和bicubic。先解释下什么叫插值,就是说图片在各种仿射变换或者其它的变换中,会遇到某些像素的像素值缺失的情况,这个时候得补充上,比如你把一个50*50的图像扩大成60*60的图像,那么每一行每一列就都会多出来十个像素,一共多出来3600-2500=1100个像素,这么多像素要给它赋值呀,这个赋值的方法就叫做插值或者内插,插值常用的就是上面的三种方法。第一种(nearest_neighbor)是最近邻域插值法:差不多意思就是找到需要赋值的像素点最邻近的点,把它的像素赋值给这个新像素。这种方法速度最快,但是缺陷最明显:某些直边缘会严重失真。第二种(bilinear)是双线性插值法:它是用新像素四个最邻近的点来估计这个新像素点的灰度值,公式如下:

Gray(x,y)=ax+by+cxy+d

a,b,c,d四个参数刚好可以用邻近四个点带进去联立一个4维方程组,然后求出来。这种方法会比第一种方法好很多,没有太明显的bug,但是运算量也上去了。效果第二好,速度第二快吧。第三种(bicubic)是双三次插值法:根据16个最邻近的点的灰度值来估算该像素点的灰度值。厉害了吧!公式也很变态:

对的,所以你平时是不用管它是怎么算的,只要记住它用了16个点来估算,效果三种方法里面最好的,但是运算量最大,耗时最长。

2)在halcon里面F1,左上角搜索栏输入distance,如下图:

图 3-3-2-11

半页纸的distance。这些都是求距离的算子,复杂的看不懂的暂时也不用弄懂,但是这种学习方法我们要学会,你看到一个重要的单词,觉得还会有其它的相关算子的时候,就可以到这里搜索出来看看。比如tuple,gen,get,contour,read,write等等。我们再回到这个distance。Distance后面挂的c是contour(轮廓),l是line(直线),r是region(区域),p是point(点),s是(line segment)线段。那很多算子就很好理解了,比如distance_rr_min就是两个region之间的最小距离。那distance_rr什么意思呢?哈哈,自己点进去看吧!

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Halcon学习(二十二)摄像机标定(函数详解)
6、Halcon图像边缘提取和轮廓识别
机器视觉之halcon入门(7)-一文弄懂halcon相机标定
HALCON机器视觉算法开发软件
halcon的tuple算子功能总结
Halcon学习(十九)标定文件的生成
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服