• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

halcon模板匹配和仿射变换

武飞扬头像
code bean
帮助1

前言

        模板匹配和仿射变换,经常一起使用,他们之前的位置变换一般有两种情况!

情况一

        模板是一个很正的图,利用模板的位置,将歪的图像摆正。

学新通

情况二 

模板和图片正不正都无所谓,只需想模板的位置,匹配到当前图片的位置。

学新通

 先从比较简单的第二种情况说起:

我们首先从标准的原图中获取模板(后面会讲到,从图中得到模板,和从模板文件中得到模板的细微区别。)比如从原图里扣出一部分作为模板如:

reduce_domain (Image, RegionErosion, ImageReduced)

创建模板

然后,就可以通过 create_shape_model  创建模板了。

  1.  
    *创建模板
  2.  
    create_shape_model (ImageReduced, 3, 0, rad(360), 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)

观察模板

接下来可以看看,模板大概的样子,帮助后面模板匹配时,确认相关参数(该函数也可忽略):

  1.  
    * 观察模板
  2.  
    inspect_shape_model (ImageReduced, ShapeModelImage, ShapeModelRegion, 4, 65)

模板匹配

接下来就是 抓取新的一张图 做模板匹配。两张图在同一镜头参数,所以共用一坐标系,这是前提,注意这点,方便接下来的理解。

  1.  
    * 模板匹配
  2.  
    find_shape_model (SearchImage, ModelID, 0, rad(360), 0.3, 1, 0.5,
  3.  
    'least_squares', 0, 1,
  4.  
    RowMatch, ColumnMatch, AngleMatch, Score)

这里的 SearchImage就是新的一张图,ModelID就是创建模板时的输出参数,和模板对应。

这里和 仿射变换 密切相关的参数是:  RowMatch, ColumnMatch, AngleMatch。也就是 XY和角度。

find_shape_model 通过 ModelID,获取到模板的相关信息.(比如,模板的形状)

拿到了信息之后,就开始在新图中找匹配,输出匹配的内容的坐标以及旋转角度,这个旋转的角度是相对应模板图像的偏移角度,坐标就是匹配内容区域中心在图中的坐标。

仿射变换

  1.  
    *获取标准图的抠图中心
  2.  
    area_center(ImageReduced, Area, Row1, Column1)
  3.  
    *根据两个中心和角度,算出旋转矩阵
  4.  
    vector_angle_to_rigid (Row1, Column1, 0, RowMatch, ColumnMatch, AngleMatch, MovementOfModel)
  5.  
    *根据旋转中心做仿射变换
  6.  
    affine_trans_region(RegionOpening1, RegionAffineTrans, MovementOfModel,
  7.  
    'nearest_neighbor')

模板匹配只是告诉了我,新的图像中被匹配到的位置(XY)以及对应模板图像的偏移角度。

那,如何将 模板本身 移动到 新图像中匹配到的内容,与之重合?

vector_angle_to_rigid 

我们需要算子:vector_angle_to_rigid 

可以认为,这个算子需要两个输入,需要移动的图形的位姿(xy和角度),以及目标点的位姿(xy和角度)。最后会输出一个矩阵,这个矩阵,这个矩阵可以完成图形仿射变换。

那模板本身在原图中的坐标,我们可以通过 area_center 这个算子计算得到。(需要知道角度吗?答案是不需要,因为模板匹配给出的角度是匹配到的内容和模板的角度偏移量。所以模板的角度默认为0)

所以,就有:

  1.  
    *根据两个中心和角度,算出旋转矩阵
  2.  
    vector_angle_to_rigid (Row1, Column1, 0, RowMatch,
  3.  
    ColumnMatch, AngleMatch, MovementOfModel)

Row1, Column1, 0: 就是 模板的位姿信息。注意这里角度就是0
RowMatch, ColumnMatch, AngleMatch:这个就是模板匹配找到的目标信息。

注意:如果找打的是多个目标,那么这些变量代表的都是数组。

最后一个参数,MovementOfModel,就是输出的 变换矩阵

affine_trans_region

最后,移动这个操作可以通过,affine_trans_region,完成:

  1.  
    *根据旋转中心做仿射变换
  2.  
    affine_trans_region(RegionOpening1, RegionAffineTrans, MovementOfModel,
  3.  
    'nearest_neighbor')

如果是移动图片可以使用,affine_trans_image。

图像摆正

摆正的思路就是,先去一个获取一个正的模板。读取的图片可能是偏的。所以这次不动的是模板,移动的是图片。

  1.  
    * 图像摆正
  2.  
    area_center(SearchImage, Area, Row2, Column2)
  3.  
     
  4.  
    vector_angle_to_rigid (RowMatch, ColumnMatch, AngleMatch, Row2, Column2, 0, MovementOfModel)
  5.  
     
  6.  
    affine_trans_image (SearchImage, ImageAffineTrans, MovementOfModel,
  7.  
    'constant', 'false')

所以这次,在算子vector_angle_to_rigid 中,模板匹配得到的坐标放在前面(谁动,谁放在前面),而图片坐标放在后面。如果只考虑摆正,这里其实有用的只是角度。

图中得到模板,和从模板文件中得到模板的细微区别

如果是从图像里得到模板,那么模板的位置,以及其他信息可以直接拿到。

还有更常见的一种用法,就是先将模板保存成文件。也就是先制作一个模板。

  1.  
    create_shape_model (ImageReduced, 2, 0, rad(360), 'auto', 'auto',
  2.  
    'use_polarity', 'auto', 'auto', ModelID)
  3.  
    write_shape_model (ModelID, name '.mb')

write_shape_model

创建模板之后,通过 write_shape_model 将创建的模板进行保存。

read_shape_model 

需要使用模板匹配时,在将其读出:

  1.  
    * 读取模板
  2.  
    read_shape_model ('数字05.mb', ModelID)
  3.  
    * 产生的轮廓在原点
  4.  
    get_shape_model_contours (ModelContours, ModelID, 1)

get_shape_model_contours 

读出模板,得到 ModleID, 然后 get_shape_model_contours 可以根据 ModleID 得到模板的轮廓。

但是此时,轮廓的位置时在图片原点上。(所以,保存的模板文件是不包含位置信息的)

所以要通过 vector_angle_to_rigid  计算矩阵时,位置参数XY可以填0,角度当然也是0.

学新通

这个就是通过模板生成的轮廓,可以看到有点小瑕疵,我们要处理一下:

  1.  
    select_contours_xld (UnionContours, SelectedContours,
  2.  
    'contour_length', 20, 20000, -0.5, 0.5)

上面这句话的意思就是较短的轮廓线不要:

学新通

还有些轮廓线虽然连在一起,但是不是一个整体,这样不利于我们进行填充(有时,我们需要对轮廓线进行填充)。

union_adjacent_contours_xld

union_adjacent_contours_xld,可以将连着的轮廓线变成一个对象:

学新通

 gen_region_contour_xld 

gen_region_contour_xld ,对轮廓线进行填充

  1.  
    * 填充
  2.  
    gen_region_contour_xld (SelectedContours, RegionXLD, 'filled')

但是,如果此时填充,会遇到一个问题,前面说到,get_shape_model_contours 获取的轮廓中心坐标在图片原点,那么,就会有部分的轮廓在图片的外面,在外面的部分无法填充。所以,一般我们需要将轮廓移到图片内在填充。不过这里需要注意的是,再进行仿射变换的话,起始坐标,必须是这个移到后的点,而不是(0,0)。

小结

        这篇文章,主要介绍了模板匹配和仿射变换的相关内容,模板匹配的很多相关参数,没有一个一个地讲解。我觉得 模板匹配和仿射变换 的关系 这个更为重要,也更难理解。后续有时间,我也会将模板匹配的关参数记录一下。欢迎评论区讨论。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfkfah
系列文章
更多 icon
同类精品
更多 icon
继续加载