天天看点

HALCON 模版匹配

简介:在这一篇中将讲述如何利用模版来识别电容器,并且标注电容器的型号

HALCON 模版匹配

文件夹内还有大量类似的图片

HALCON 模版匹配

思路

要实现使用HALCON自动识别电容,按照操作来说,也就是使用模版来“套出”图片上的电容器,获取在图片上的位置。因此,在执行利用模版来识别电容器之前,我们需要先得到模版。根据图片可以了解到,电容器的表面图案有具体的差别,按照这一差别我们可以比较简单的进行识别。

获得模版ROI

每个电容器都会产生至少一个模版文件,这部分的操作我做的比较简易,仅仅是用ROI工具,依照电容器在画面上面的区域绘制圆形,从而一个一个产生不同的电容器的兴趣区域

HALCON 模版匹配
HALCON 模版匹配

该部分的代码:

*读取图片并截取感兴趣区域

*Read Image

read_image (Image1,'C:/Users/sinzo/Desktop/halcon/class 3 train/1+8+26.tif')

get_image_size(Image1, Width, Height)

dev_open_window (0, 0, Width/3, Height/3,'black', WindowHandle)

dev_display (Image1)

 

gen_circle (ROI_0, 541, 832.521, 153.075)

reduce_domain (Image1, ROI_0, ImageReduced)

 
           

模版的生成

在获取感兴趣区域后可以对模版进行生成,使用的主要是两个算子,一个是inspect_shape_model,可以通过这个算子辅助我们找到适合的二值化参数,另一个算子是get_shape_model_contours,可以帮助我们生成模版模型

两者在我的算法中是先后调用的关系,先说明inspect_shape_model,这一个算子可以让我们对当前设置的参数(主要是Contrast参数)进行监视,输入图片后执行算子,会输出按照金字塔层级(相当于比例缩放)生成的二值化图像,可用于参考

HALCON 模版匹配

随后是生成模版的算子create_scaled_shape_model,该算子将产生Model用于之后的匹配,默认的参数如下

HALCON 模版匹配

需要用户自定义更改的部分,1金字塔层级,2开始角度,3角度范围,4对比度,5最小对比度

HALCON 模版匹配

对比度和最小对比度都是需要按照模型的原图不断修改的,我认为与图像的明度和灰度相关

在修改后会生成如下的图形

HALCON 模版匹配

对比度参数数值增加,则生成的模型信息量会相应的减少。

参数设置为10,此时可以看到下图中模型部分被识别出来的边缘好像太多了

HALCON 模版匹配

参数设置为15,边缘看起来太少

HALCON 模版匹配

实际上,眼见不一定为实,看似对比度设置后蕴含的信息的量减少了,但主要还是要以验证后,匹配程度作为一个调整参数的标准

代码:

inspect_shape_model(ImageReduced,ModelImages, ModelRegions, 3, 28)

myContrast := 13

myMinContrast := 3

create_scaled_shape_model (ImageReduced, 3,rad(-180), rad(360), 0.0175, 0.9, 1.1, 'auto', 'none', 'use_polarity',myContrast, myMinContrast, ModelID)

get_shape_model_contours (Model, ModelID,1)

 
           

模型匹配验证

在生成模版后,打开图片,使用模版寻找匹配的图案,这里使用find_scaled_shape_model算子,如果图案大小固定,可以吧ScaleMax和ScaleMin设置为1,这样能提高识别速率

HALCON 模版匹配

如果识别到,会输出坐标,旋转角度,匹配程度(Score)数据,可以使用一个红色圆形来标注出来,更为的直观

HALCON 模版匹配

一般建议调整对比度到生成的模型去寻找出原本的图案,匹配程度在0.95左右。如下图左侧的电容器是模版图案,我用这个模版去寻找得到的匹配程度为0.955

如果是一些相似的,例如下图原本是三个图片,我将他们合成到一张图片上便于调整

HALCON 模版匹配

调整到T型和Y型电容不会被识别在同一类型即可。在这里,我将匹配率的阈值设置在0.7到0.75左右,这样就防止找到匹配程度较低的图案

验证生成的模型与标注信息和中心点的代码:

tuple_length(Column,Num)

for Index := 0 to Num-1 by 1

 disp_circle(WindowHandle, Row[Index], Column[Index], 10) 

 set_tposition (WindowHandle, Row[Index]+50, Column[Index])

 write_string (WindowHandle, 'Type:CAP10 '+'Score:'+Score[Index])

endfor
           

如果模版调整到没问题了,保存为模版文件,用于之后的读取

write_shape_model (ModelID,'C:/Users/sinzo/Desktop/halcon/ train/1.shm')
           

文件名用数字比较方便

匹配应用

在创建模版后我们应该得到一批模版文件

HALCON 模版匹配

之后匹配模版的整个程序就是和验证时候差不多,读取一张图片,循环模版进行识别,标注信息,这里我贴上整个程序用于参考

*read image

for ImageIndex := 1 to 33 by 1

   if (ImageIndex <= 16)

       

       read_image (ImageSearch, 'C:/Users/sinzo/Desktop/halcon/class3/IMG1/'+ImageIndex$'d'+'.tif')

   else

       read_image (ImageSearch, 'C:/Users/sinzo/Desktop/halcon/class3/IMG2/'+ImageIndex$'d'+'.tif')

       

   endif

       get_image_size(ImageSearch, Width, Height)

       dev_open_window (0, 0, Width/3, Height/3, 'black', WindowHandle)

       dev_display (ImageSearch)

       for ModelIndex := 2 to 21 by 1

          *read shape model from file

          read_shape_model ('C:/Users/sinzo/Desktop/halcon/class3/shm/'+ModelIndex$'d'+'.shm',ModelID1)

          get_shape_model_contours (Model, ModelID1, 1)

          minpersent := 0.700

          find_scaled_shape_model (ImageSearch, ModelID1, rad(-180), rad(360), 1,1, minpersent, 0, 0.5, 'least_squares', 5, 0.8, Row, Column, Angle, Scale,Score)

          tuple_length(Column,Num)

                for Index := 0 to Num-1 by 1

                      dev_set_color ('green')

                      disp_circle(WindowHandle,Row[Index], Column[Index], 10) 

                      dev_set_color ('magenta')

                      set_tposition (WindowHandle,Row[Index], Column[Index])

                      write_string(WindowHandle, 'Score:'+Score[Index])

                      set_tposition(WindowHandle, Row[Index]+34, Column[Index])

                      write_string(WindowHandle, 'Type:'+ModelIndex)

                      set_tposition(WindowHandle, Row[Index]+68, Column[Index])

                      getCapName(ModelIndex,string)

                      write_string(WindowHandle, 'Name:'+string)

                endfor

      endfor

      stop()

endfor

 
           

为了能通过识别出的类型返回具体的电容器的名称,写了一个另外的自定义算子getCapName

HALCON 模版匹配

识别的结果

HALCON 模版匹配
HALCON 模版匹配

继续阅读