简介:在这一篇中将讲述如何利用模版来识别电容器,并且标注电容器的型号
文件夹内还有大量类似的图片
思路
要实现使用HALCON自动识别电容,按照操作来说,也就是使用模版来“套出”图片上的电容器,获取在图片上的位置。因此,在执行利用模版来识别电容器之前,我们需要先得到模版。根据图片可以了解到,电容器的表面图案有具体的差别,按照这一差别我们可以比较简单的进行识别。
获得模版ROI
每个电容器都会产生至少一个模版文件,这部分的操作我做的比较简易,仅仅是用ROI工具,依照电容器在画面上面的区域绘制圆形,从而一个一个产生不同的电容器的兴趣区域
该部分的代码:
*读取图片并截取感兴趣区域
*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参数)进行监视,输入图片后执行算子,会输出按照金字塔层级(相当于比例缩放)生成的二值化图像,可用于参考
随后是生成模版的算子create_scaled_shape_model,该算子将产生Model用于之后的匹配,默认的参数如下
需要用户自定义更改的部分,1金字塔层级,2开始角度,3角度范围,4对比度,5最小对比度
对比度和最小对比度都是需要按照模型的原图不断修改的,我认为与图像的明度和灰度相关
在修改后会生成如下的图形
对比度参数数值增加,则生成的模型信息量会相应的减少。
参数设置为10,此时可以看到下图中模型部分被识别出来的边缘好像太多了
参数设置为15,边缘看起来太少
实际上,眼见不一定为实,看似对比度设置后蕴含的信息的量减少了,但主要还是要以验证后,匹配程度作为一个调整参数的标准
代码:
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,这样能提高识别速率
如果识别到,会输出坐标,旋转角度,匹配程度(Score)数据,可以使用一个红色圆形来标注出来,更为的直观
一般建议调整对比度到生成的模型去寻找出原本的图案,匹配程度在0.95左右。如下图左侧的电容器是模版图案,我用这个模版去寻找得到的匹配程度为0.955
如果是一些相似的,例如下图原本是三个图片,我将他们合成到一张图片上便于调整
调整到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')
文件名用数字比较方便
匹配应用
在创建模版后我们应该得到一批模版文件
之后匹配模版的整个程序就是和验证时候差不多,读取一张图片,循环模版进行识别,标注信息,这里我贴上整个程序用于参考
*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
识别的结果