前面我已经逐个介绍了一维测量,卡尺测量以及相关的模板匹配内容,那么这篇文章呢,我们就完整的介绍下如何去使用模板匹配和测量去完成一个简单的测量项目,这里还是只介绍像素精度的情况下的,有关相机标定的内容后面会单独讲解,话不多说了,我们直奔主题!
原图如下(这也是halcon里面案例的图片集):
代码如下:
read_image (Image, 'C:/Users/Public/Documents/MVTec/HALCON-12.0/examples/images/board/board-01.png')
*框选出模板区域
draw_rectangle1 (3600, Row1, Column1, Row2, Column2)
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
reduce_domain (Image, Rectangle, ImageReduced)
*创建模板,创建模板后面的一些参数不知道怎么选择的时候,我们可以先利用halcon自带的Matching
*工具完成模板匹配的工作,然后复制相关的参数即可,肯定比自己选的参数更准确。
create_shape_model (ImageReduced, 5, rad(0), rad(360), rad(1), ['none','no_pregeneration'], 'use_polarity', [30,30,0], 10, ModelId)
get_shape_model_contours (ModelContours, ModelId, 1)
*gen_region_points (pointup, -100, 0)
*gen_region_points (pointdown, 108, 0)
stop()
list_files ('C:/Users/J。in/Desktop/board', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
get_image_size (Image, Width, Height)
*查找模板
find_shape_model (Image, ModelId, rad(0), rad(360), 0.5, 0, 0.5, 'least_squares', [5,1], 0.75, ModelRow, ModelColumn, ModelAngle, ModelScore)
*求出旋转平移矩阵
vector_angle_to_rigid (0, 0, 0, ModelRow, ModelColumn, ModelAngle, HomMat2D)
affine_trans_contour_xld (ModelContours, ContoursAffinTrans, HomMat2D)
*这一步是关键,这一步完成的就是将我们测量的矩形框跟随我们的模板运动
*随时保证测量位置的准确,主要就是模板区域的中心位置离矩形测量框的中心位置的
*点的距离,可以直接自己用鼠标去找到测量框的中心点,看模板区域的中心点的行列
*坐标和测量框的中心点的行列坐标,然后对比出行列差值,运算到寻找到的模板中心点(0,0)
*注:模板匹配找到的模板的xld区域都是以(0,0)为中心点的。
dev_set_draw ('margin')
affine_trans_pixel (HomMat2D, -102, 0, RowTrans1, ColTrans1)
gen_rectangle2 (Rectangle1, RowTrans1, ColTrans1, ModelAngle, 168, 5)
*生成测量矩形
gen_measure_rectangle2 (RowTrans1, ColTrans1, ModelAngle, 168, 5, Width, Height, 'nearest_neighbor', MeasureHandleUp)
affine_trans_pixel (HomMat2D, 108, 0, RowTrans2, ColTrans2)
gen_rectangle2 (Rectangle2, RowTrans2, ColTrans2, ModelAngle, 168, 5)
*生成测量矩形2
gen_measure_rectangle2 (RowTrans2, ColTrans2, ModelAngle, 168, 5, Width, Height, 'nearest_neighbor', MeasureHandleDown)
*测量边缘对,这里我们需要解释下参数的意义:
*1.measure_pairs用于提取垂直于测量矩形或环形弧的长轴的直边对
*2.边缘分组成对:如果Transition =“positive”,则返回的点(RowEdgeFirst,ColumnEdgeFirst)
*为矩形长轴方向上由黑到亮的边缘点,点(RowEdgeSecond,ColumnEdgeSecond)为由亮至暗的边缘点。
*如果Transition =“negative”,则相反。
*3.如果Transition ='all',则第一个检测到的边缘定义RowEdgeFirst和ColumnEdgeFirst的转换。这适合于测量具有相对于背景的不同亮度的物体。
*4.提取的边缘作为位于矩形长轴上的单个点返回。相应的边沿幅度的值为AmplitudeFirst和AmplitudeSecond。
*此外,每个边对之间的距离以IntraDanceance返回,并且InterDistance之间返回连续边源对之间的距离。
*这里,IntraDistance [i]对应于EdgeFirst [i]和EdgeSecond [i]之间的距离,而InterDistance [i]对应于EdgeSecond [i]和EdgeFirst [i + 1]之间的距离。
dev_set_line_width (3)
measure_pairs (Image, MeasureHandleUp, 1, 130, 'all', 'all', RowEdgeFirstUp, ColumnEdgeFirstUp, AmplitudeFirstUp, RowEdgeSecondUp, ColumnEdgeSecondUp, AmplitudeSecondUp, IntraDistanceUp, InterDistanceUp)
measure_pairs (Image, MeasureHandleDown, 1, 130, 'all', 'all', RowEdgeFirstDown, ColumnEdgeFirstDown, AmplitudeFirstDown, RowEdgeSecondDown, ColumnEdgeSecondDown, AmplitudeSecondDown, IntraDistanceDown, InterDistanceDown)
disp_line (3600, RowEdgeFirstUp-5*cos(ModelAngle), ColumnEdgeFirstUp-5*sin(ModelAngle), RowEdgeFirstUp+5*cos(ModelAngle), ColumnEdgeFirstUp+5*sin(ModelAngle))
disp_line (3600, RowEdgeSecondUp-5*cos(ModelAngle), ColumnEdgeSecondUp-5*sin(ModelAngle), RowEdgeSecondUp+5*cos(ModelAngle), ColumnEdgeSecondUp+5*sin(ModelAngle))
disp_line (3600, RowEdgeFirstDown-5*cos(ModelAngle), ColumnEdgeFirstDown-5*sin(ModelAngle), RowEdgeFirstDown+5*cos(ModelAngle), ColumnEdgeFirstDown+5*sin(ModelAngle))
disp_line (3600, RowEdgeSecondDown-5*cos(ModelAngle), ColumnEdgeSecondDown-5*sin(ModelAngle), RowEdgeSecondDown+5*cos(ModelAngle), ColumnEdgeSecondDown+5*sin(ModelAngle))
stop()
endfor
处理结果如图所示:
到这里就是完整的实现一个测量跟随定位的案例,具体解释可以看代码里面的注释,如果有什么不懂的地方可私信我。这里只是提供了一个思路,后面有类似相关的项目可以遵循这样的思路来解决项目的问题。其实halcon中案例中方法一大类中有很多我们可以参考的思路,我这里也只是用自己的方式来理解这些方法,其实大家都可以仔细研究。
到这里定位,测量就告一段落了,后面我继续介绍一些综合的项目案例,然后分享下我遇到的比较值得分享的一些项目!