这两天的模板匹配的学习,发现前面两篇关于匹配的文章有一些理解错误的地方,正在做一些修正。对于关于模板匹配的几种类别,有重新的理解,也在陆续做修正。
在陆续修正的过程中,先切入缺陷检测的学习,今天才搞定的,马上分享一下,《一个基于固定比例尺寸的缺陷检测的实例及逐步图片详解》。
ps:每贴只能显示5张图片,这篇要分4个贴写完。
* This example program shows how to use HALCON's variation model operators
* to perform a typical print quality inspection. The program detects incorrect
* prints on the clips of pens. In the first step, the variation model is constructed
* from images of correct prints. Since the position of the objects can vary, the
* images must be transformed to a reference position (the position of the print
* in the first image in this example). HALCON's shape-based matching is used
* to detect the position and angle of the print in the images. The found position
* and angle are used to transform the images to the reference position.
* In the second part of the program, the prints of the correct clips and of several
* incorect clips is checked and classified.
* 这个例程展示了如何运用Halcon的变化模型来执行一个典型的印刷质量检测。
* 这个段代码用于检测钢笔笔夹上的不正确印刷。
* 第一步,首先从正确的印刷图像建立一个变化模型。
* 由于对象的位置可以变化,图像必须被转化为一个参考位置(在这个例子中的第一图像的打印位置)。
* Halcon的基于形状的匹配是用来检测打印图像中的位置和角度。把找到的位置和角度转换成图像的参考位置。
* 第二部分代码,展示了检查和分类出正确与错误的笔夹上的印刷图案。
dev_update_pc ('off')
dev_update_window ('off')
dev_update_var ('off')
read_image (Image, 'pen/pen-01')

get_image_size (Image, Width, Height) dev_close_window () dev_open_window (0, 0, Width, Height, 'black', WindowHandle) get_system ('operating_system', OS) if (OS{0:2} = 'Win') set_font (WindowHandle, '-Courier New-18-*-*-*-*-') else set_font (WindowHandle, '-adobe-courier-bold-r-normal--25-*-*-*-*-*-*-*') endif * 这段获取系统信息是可以取消的。 dev_set_color ('red') dev_display (Image) * Note: the shape model will be constructed from a ROI that is computed * automatically based on a simple image segmentation. * 将从一个基于简单图像分割的自动计算的ROI中创建这个形状模型。 stop() threshold (Image, Region, 100, 255) * 灰白色区域被选中,这个区域中有灰黑色部分。  fill_up (Region, RegionFillUp) * 将整个区域填充起来。

difference (RegionFillUp, Region, RegionDifference) * 将RegionFillUp和Region不同的部分获取出来,得到中间灰黑色部分。  dev_clear_window() dev_display (RegionDifference) * 清空窗口来显示一些过程图片。 shape_trans (RegionDifference, RegionTrans, 'convex') * 变换一个区域的形状,把difference得到的灰黑色图案变换形状,用convex模式变换,将其变换成整个凸出的填充完整形状。  dilation_circle (RegionTrans, RegionDilation, 8.5) * 将变换得到的RegionTrans区域扩大8.5边缘,并倒圆角

reduce_domain(Image, RegionDilation, ImageReduced) * 从图片抠出扩大边缘的RegionDilation,得到ImageReduced。 
* difference是对比不同部分,把不同的部分提取出来; * 而reduce是从一个图片抠出一个基于另一个图像的大小和位置的图片。 dev_clear_window() read_image (Image1, 'L:/Halcon test/mvrec.jpg')  gen_rectangle1(ROI_0, 210.111, 144.655, 343.111, 554.866)  reduce_domain (Image1, ROI_0, ImageReduced1) 
dev_clear_window() dev_display (ImageReduced1) * 如果一个图片是单色可用gen_rectangle1等创建ROI的话,就不用上面那么繁杂的步骤 dev_clear_window() dev_display (ImageReduced) inspect_shape_model (ImageReduced, ModelImages, ModelRegions, 1, 20) * 创建一个对比的模型,后面两个参数:第一个是层数(NumLevels,如5层) * 第二个是对比度阈值,对比度太高,就只能选中灰黑色的图案;对比值适中,才能选中浅灰色图案;对比度太低,就会把淡灰色部分也选中。  gen_contours_skeleton_xld (ModelRegions, Model, 1, 'filter') * 将框架转换为XLD轮廓(contour)。 area_center (RegionDilation, Area, RowRef, ColumnRef) * 输出面积和中心点位置。  create_shape_model (ImageReduced, 5, rad(-10), rad(20), 'auto', 'none', 'use_polarity', 20, 10, ShapeModelID)
* 创建一个形状模型 create_variation_model (Width, Height, 'byte', 'standard', VariationModelID) * 为图像对比创建一个变化模型。 stop() for I := 1 to 15 by 1 read_image (Image, 'pen/pen-'+I$'02d') find_shape_model (Image, ShapeModelID, rad(-30), rad(60), 0.5, 1, 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score) * 在图片中寻找ShapeModelID的模板匹配的团案。获取匹配图案的行,列,角,分数 if (|Score| = 1) vector_angle_to_rigid (Row, Column, Angle, RowRef, ColumnRef, 0, HomMat2D) * 从点和角度方面计算一个严格的仿射变换。 affine_trans_image (Image, ImageTrans, HomMat2D, 'constant', 'false') * 把任意仿射2D变换应用在图像中。 * 也就是在I=15的15张图片中,有些笔夹印刷图案的位置不一定都能和模板的位置(第一张图片)一致,会有一定的偏移, * 那么将其按照已获取的中心点位置移动到中点。 train_variation_model (ImageTrans, VariationModelID) * 训练一个变化模型。 dev_display (ImageTrans) dev_display (Model)  endif endfor stop() dev_close_window () dev_open_window (0, 0, Width, Height, 'black', WindowHandle) get_variation_model (MeanImage, VarImage, VariationModelID) * 返回图像用于图像对比。 prepare_variation_model (VariationModelID, 20, 3) * 为图像对比准备一个变化模型,后面两个参数是用于调整对比的精度方位,应结合起来用。 * AbsThreshold:图像和变化的模型之间差异的绝对最小阈值 * VarThreshold:基于变化模型的变化的不同的阈值 clear_train_data_variation_model (VariationModelID) * We can now free the training data to save some memory. * 释放变化模型(variation_model)的测试数据的存储空间。 * Note: the checking of the print will be restricted to the region of the clip. * Sometimes the print is also in an incorrect position of the clip. This will lead * to erroneous regions at the top or bottom border of the clip and hence can * be detected easily. * 印刷标签的检查将被限制到笔夹区域。但有时候,印刷标签仍然会在笔夹上不正确的位置出现。 * 这将导致在笔夹的顶部或底部的边界出现错误的区域。因此可以很容易检测到的这些错误的区域。 erosion_rectangle1 (RegionFillUp, RegionROI, 1, 15) * 腐蚀一个矩形结构基础的一个区域。在ROI的长宽下,往内部腐蚀宽度1,高度15,得到RegionROI  dev_display (MeanImage) set_tposition (WindowHandle, 20, 20) * 设置文本光标的位置。 dev_set_color ('green') write_string (WindowHandle, 'Reference image') * 显示参考图片 stop ()  dev_display (VarImage) set_tposition (WindowHandle, 20, 20) dev_set_color ('green') write_string (WindowHandle, 'Variation image') * 显示变化比对模板 stop ()  dev_set_draw ('margin')
for I := 1 to 30 by 1 read_image (Image, 'pen/pen-'+I$'02d') find_shape_model (Image, ShapeModelID, rad(-10), rad(20), 0.5, 1, 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score) * 在图片中寻找ShapeModelID的模板匹配的团案。获取匹配图案的行,列,角,分数 if (|Score| = 1) vector_angle_to_rigid (Row, Column, Angle, RowRef, ColumnRef, 0, HomMat2D) * 从点和角度方面计算一个严格的仿射变换。 affine_trans_image (Image, ImageTrans, HomMat2D, 'constant', 'false') * 把任意仿射2D变换应用在图像中。同训练模板的部分。 reduce_domain (ImageTrans, RegionROI, ImageReduced) * 获得对比图像ImageReduced compare_variation_model (ImageReduced, RegionDiff, VariationModelID) * 将一个图像与一个变化模型(variation_model)相比较。获得区别的图像RegionDiff。 connection (RegionDiff, ConnectedRegions) * 链接所有有区别的地方成为一个图片 select_shape (ConnectedRegions, RegionsError, 'area', 'and', 20, 1000000) * 根据图形特征选择区域。 count_obj (RegionsError, NumError) * 统计一个元组中的对象。 dev_clear_window () dev_display (ImageTrans) dev_set_color ('red') dev_display (RegionsError) set_tposition (WindowHandle, 20, 20) if (NumError = 0) dev_set_color ('green') write_string (WindowHandle, 'Clip OK') 
else dev_set_color ('red') write_string (WindowHandle,'Clip not OK,共有'+ NumError + '处缺陷') * 显示错误的区域,我添加了一个缺陷数量的统计。 
endif endif stop () endfor stop () clear_shape_model (ShapeModelID) clear_variation_model (VariationModelID)
|