文章目录
- 算子
- Halcon 在单个图像上进行模板差异比较(使用面积)
- Halcon 通过平均灰度值比较颜色差异的缺陷
- Halcon 对于每个字符进行单独检测
注意:此算法只能识别轮廓的差异
算子
binomial_filter 二项滤波器平滑图片
binomial_filter(Image : ImageBinomial : MaskWidth, MaskHeight : )
参数解释如下:Image (输入对象):输入图像。数据类型:byte* / uint2* / real*允许的计算设备:所有输入图像。ImageBinomial (输出对象):平滑后的图像。数据类型:byte / uint2 / real平滑后的图像。MaskWidth (输入控制):滤波器宽度。默认值:5可选数值:1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37MaskHeight (输入控制):滤波器高度。默认值:5可选数值:1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37
create_variation_model 创建用于图像对比的变化模型
create_variation_model( : : Width, Height, Type, Mode : ModelID)
参数解释如下:Width (输入控制):待比较图像的宽度。默认值为:640建议取值:160, 192, 320, 384, 640, 768Height (输入控制):待比较图像的高度。默认值为:480建议取值:120, 144, 240, 288, 480, 576Type (输入控制):待比较图像的类型。默认值为:'byte'建议取值:'byte', 'int2', 'uint2'Mode (输入控制):计算变化模型时使用的方法。默认值为:'standard'建议取值:'standard', 'robust', 'direct'ModelID (输出控制):变化模型的 ID。
prepare_direct_variation_model 准备比较模板
prepare_direct_variation_model(RefImage, VarImage : : ModelID, AbsThreshold, VarThreshold : )
参数解释如下:RefImage (输入对象):目标的参考图像。数据类型:byte / int2 / uint2目标的参考图像。VarImage (输入对象):目标的变化图像。数据类型:byte / int2 / uint2目标的变化图像。ModelID (输入控制,状态被修改):变化模型的 ID。AbsThreshold (输入控制):图像与变化模型之间差异的绝对最小阈值。默认值:10建议取值:0, 5, 10, 15, 20, 30, 40, 50限制条件:AbsThreshold >= 0VarThreshold (输入控制):基于变化模型变化的差异阈值。默认值:2建议取值:1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5限制条件:VarThreshold >= 0
compare_ext_variation_model 比较图片与模板图片的不同
compare_ext_variation_model(Image : Region : ModelID, Mode : )
参数解释如下:Image (输入对象):待比较对象的图像。数据类型:byte / int2 / uint2待比较对象的图像。Region (输出对象):包含与模型差异显著的点的区域。数据类型:region(-array)包含与模型差异显著的点的区域。ModelID (输入控制):变化模型的 ID。Mode (输入控制):用于比较变化模型的方法。默认值:'absolute'建议取值:'absolute', 'light', 'dark', 'light_dark'
train_variation_model 训练一个变异模型
train_variation_model(Images : : ModelID : )
这些参数用于一个涉及图像和变异模型的训练过程。具体解释如下:Images (输入对象):该参数接收待训练对象的图像。指定的格式是单通道图像数组,通常以字节(byte)、int2或uint2数据类型表示。ModelID (输入控制,状态会被修改):该参数指定要用于训练过程的变异模型的ID。
get_variation_model 返回变量模型用于图像比较的图像,返回训练后的图片和差异图像
get_variation_model( : Image, VarImage : ModelID : )
参数解释如下:Image (输出对象):经过训练后的对象的图像。它是一个图像对象,可以表示为字节(byte)、int2或uint2数据类型。VarImage (输出对象):经过训练后的对象的变异图像。它是一个实数类型的图像对象。ModelID (输入控制):变异模型的ID。这个参数用于指定要使用的变异模型的ID。
prepare_variation_model 准备一个变化模型,以便与图像进行比较
prepare_variation_model( : : ModelID, AbsThreshold, VarThreshold : )
以下是参数的解释:ModelID (输入控制,状态被修改):变异模型的ID。用于指定要使用的变异模型的ID。AbsThreshold (输入控制):图像与变异模型之间差异的绝对最小阈值。默认值为10,建议的取值范围为0、5、10、15、20、30、40、50。限制条件为AbsThreshold >= 0。VarThreshold (输入控制):基于变异模型变化的差异阈值。默认值为2,建议的取值范围为1、1.5、2、2.5、3、3.5、4、4.5、5。限制条件为VarThreshold >= 0。
compare_variation_model 将图像与变异模型进行比较
compare_variation_model(Image : Region : ModelID : )
以下是参数的解释:Image (输入对象):待比较对象的图像。这是一个单通道图像数组,通常表示为字节(byte)、int2或uint2数据类型。Region (输出对象):包含与模型差异显著的点的区域。这是一个区域对象,用于标识与模型存在明显差异的点的区域。ModelID (输入控制):变异模型的ID。用于指定要使用的变异模型的ID。
sobel_amp 索贝尔算子检测边缘(振幅)
sobel_amp(Image : EdgeAmplitude : FilterType, Size : )
参数解释如下:Image (输入对象):输入图像。数据类型:byte / int2 / uint2 / real输入图像。EdgeAmplitude (输出对象):边缘幅度(梯度幅度)图像。数据类型:int1 / int2 / uint2 / real边缘幅度(梯度幅度)图像。FilterType (输入控制):滤波器类型。默认值:'sum_abs'值列表:'sum_abs', 'sum_abs_binomial', 'sum_sqrt', 'sum_sqrt_binomial', 'thin_max_abs', 'thin_max_abs_binomial', 'thin_sum_abs', 'thin_sum_abs_binomial', 'x', 'x_binomial', 'y', 'y_binomial'计算设备的值列表:'sum_abs', 'sum_sqrt', 'x', 'y', 'sum_abs_binomial', 'sum_sqrt_binomial', 'x_binomial', 'y_binomial'Size (输入控制):滤波器掩模的大小。默认值:3值列表:3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39
Halcon 在单个图像上进行模板差异比较(使用面积)
*
* This example shows how to employ the new extensions of HALCON's variation model operators
* to perform customary print quality tests.
* In this example the variation model is built upon a single reference image.
* The example consists of three steps:
* 1. align the print objects similar to the reference image using a shape-based model
* 2. define the variation image by smoothing the object's contours
* 3. create the variation model
* Whether a print is labelled as OK or not, depends upon the size (area) of the difference to the reference image
*
dev_close_window ()
read_image (Image, 'pen/pen-01')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_update_off ()
set_display_font (WindowHandle, 12, 'mono', 'true', 'false')
dev_display (Image)
*
* segment the logo and create a shape model for the alignment
* 1.创建形状匹配模板
threshold (Image, Region, 125, 255)
fill_up (Region, RegionFillUp)
* 对比出阈值处理和填充的不同地方
difference (RegionFillUp, Region, RegionDifference)
* 设置一个凸型
shape_trans (RegionDifference, LogoArea, 'convex')
* 进行膨胀
dilation_circle (LogoArea, LogoArea, 7)
* 膨胀后进行裁剪
reduce_domain (Image, LogoArea, ImageReduced)
* 创建匹配模板
create_shape_model (ImageReduced, 'auto', -rad(10), rad(20), 'auto', 'auto', 'use_polarity', [40,50], 40, ShapeModelID)
* 获取模板的面积以及坐标
area_center (LogoArea, Area, ModelRow, ModelColumn)
*
* define the variation image by smoothing the dilated regions obtained from the object's contours:
* Besides a binomial filter a neat trick is applied to get smoothly "polished" regions along the contours.
* In particular, the edges are enlarged and after their conversion into a dilated region the image
* is zoomed back to its original size using a weighting that smoothes the images further.
* 2.获取边缘创建图像变化模板
* 亚像素边缘提取
edges_sub_pix (ImageReduced, Edges, 'sobel_fast', 0.5, 10, 20)
* 产生仿射变换矩阵
hom_mat2d_identity (HomMat2DIdentity)
* 添加一个缩放到齐次二维变换矩阵
hom_mat2d_scale (HomMat2DIdentity, 4, 4, 0, 0, HomMat2DScale)
*亚像素边缘仿射变换
affine_trans_contour_xld (Edges, ZoomedEdges, HomMat2DScale)
* 创建一个具有恒定灰度值的图像
gen_image_const (VarImageBig, 'byte', 4 * Width, 4 * Height)
* 2.1 创建一个灰度图对模板创建灰度模板做准备
* 计算边缘的数量
count_obj (ZoomedEdges, NEdges)
for i := 1 to NEdges by 1select_obj (ZoomedEdges, ObjectSelected, i)*获取亚像素轮廓的行列坐标get_contour_xld (ObjectSelected, RowEdge, ColEdge)*产生多边形区域模型gen_region_polygon (Region1, RowEdge, ColEdge)*膨胀dilation_circle (Region1, RegionDilation, 2.5)*在灰度图像中覆盖区域paint_region (RegionDilation, VarImageBig, VarImageBig, 255, 'fill')
endfor
* 将图片缩放指定大小
zoom_image_size (VarImageBig, VarImageSmall, Width, Height, 'weighted')
* 使用二项滤波器平滑图像
binomial_filter (VarImageSmall, VarImage, 3, 3)
* 创建图像变换模板,使用直接比较法
create_variation_model (Width, Height, 'byte', 'direct', VarModelID)
* 准备一个变化模型,以便与图像进行比较。
prepare_direct_variation_model (Image, VarImage, VarModelID, 15, 4)
dev_display (VarImage)
disp_message (WindowHandle, 'Variation Image', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* print inspection
* 3.进行模板匹配
for i := 1 to 30 by 1read_image (Image, 'pen/pen-' + i$'02d')* locate the logo and align it to the reference imagefind_shape_model (Image, ShapeModelID, -rad(10), rad(20), 0.5, 1, 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score)if (|Score| != 0)* 仿射变换vector_angle_to_rigid (Row, Column, Angle, ModelRow, ModelColumn, 0, HomMat2D)affine_trans_image (Image, ImageAffineTrans, HomMat2D, 'constant', 'false')* 裁剪reduce_domain (ImageAffineTrans, LogoArea, ImageReduced1)* 3.1 进行模板比较,通过面积大小的不同筛选出残次品* 比较不同compare_ext_variation_model (ImageReduced1, RegionDiff, VarModelID, 'absolute')* 形成单独的连通域connection (RegionDiff, ConnectedRegions)* 选择面积select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 10, 99999)* 有残次品进行显示dev_display (ImageAffineTrans)count_obj (SelectedRegions, NDefects)if (NDefects > 0)dev_set_color ('red')dev_set_draw ('margin')dev_set_line_width (2)dev_display (SelectedRegions)dev_set_color ('green')dev_set_line_width (1)dev_display (Edges)disp_message (WindowHandle, 'Image check not OK', 'window', 12, 12, 'red', 'false')elsedisp_message (WindowHandle, 'Image check OK', 'window', 12, 12, 'green', 'false')endifendifdisp_continue_message (WindowHandle, 'black', 'true')stop ()
endfor
*
* clean up
clear_shape_model (ShapeModelID)
clear_variation_model (VarModelID)
Halcon 通过平均灰度值比较颜色差异的缺陷
* This example demonstrates the print inspection using
* a variation model. The variation model is trained
* using a single model image. Before applying the print inspection,
* the images are scaled to the same gray value range like the model.
*
dev_update_off ()
dev_close_window ()
*
* Read model image and init visualization
* 1.读取图片进行显示
read_image (ModelImage, 'cap_illumination/cap_illumination_01')
get_image_size (ModelImage, Width, Height)
dev_open_window (0, 0, Width / 2, Height / 2, 'black', WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
*
* Segment model region
dev_display (ModelImage)
* 2.获取要匹配的区域
get_model_region (ModelImage, RegionROI, ImageReduced)
area_center (RegionROI, Area, RowModel, ColumnModel)
dev_set_draw ('margin')
dev_set_color ('green')
dev_display (RegionROI)
*
* Create model for shape-based-matching
disp_message (WindowHandle, 'Model generation...', 'window', 12, 12, 'black', 'true')
* 3.创建模板
* 创建一个可以缩放的匹配模板
create_scaled_shape_model (ImageReduced, 'auto', 0, rad(360), 'auto', 0.8, 1.2, 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)
* 4.获取模板轮廓,与边缘振幅模板准备比较
get_shape_model_contours (ModelContours, ModelID, 1)
* Transform model contours from the original position for visualization
* 从原始位置转换模型轮廓以实现可视化
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity, RowModel, ColumnModel, HomMat2DTranslate)
affine_trans_contour_xld (ModelContours, ModelContoursAffineTrans, HomMat2DTranslate)
*
* Create variation model for print inspection
* 创建一个图像对比的轮廓模板
create_variation_model (Width, Height, 'byte', 'direct', VariationID)
* Generate variation image
* 检测原图像的边缘振幅
sobel_amp (ModelImage, VarImage, 'sum_abs', 5)
prepare_direct_variation_model (ModelImage, VarImage, VariationID, [20,25], [1.6,1.6])
*
* Get gray value range of the variation model
* 5.获取前景和背景的平均灰度范围
get_grayval_range (ModelImage, RegionROI, RegionForeground, RegionBackground, BackgroundGVModel, ForegroundGVModel)
*
* Perform print inspection
for I := 1 to 9 by 1read_image (rImage, 'cap_illumination/cap_illumination_' + I$'.2')inspect_cap (rImage, RegionROI, WindowHandle, ModelID, VariationID, RowModel, ColumnModel, BackgroundGVModel, ForegroundGVModel)if (I < 9)disp_continue_message (WindowHandle, 'black', 'true')stop ()endif
endfor
*
clear_shape_model (ModelID)
clear_variation_model (VariationID)
get_model_region (ModelImage, RegionROI, ImageReduced) 获取检测的区域函数
*
* Segment label on the cap
* 二值化获取较亮的区域
binary_threshold (rImage, BrightRegion, 'max_separability', 'light', UsedThreshold)
* 膨胀
dilation_circle (BrightRegion, RegionDilation, 1.5)
* 形成单独的连通域
connection (RegionDilation, ConnectedRegions)
* 筛选出形状
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 100, 99999)
* 联合
union1 (SelectedRegions, LabelRegion)
* 区域的最小周边圆
smallest_circle (LabelRegion, Row, Column, Radius)
* 区域的最小周边矩形
smallest_rectangle1 (LabelRegion, Row1, Column1, Row2, Column2)
*
* Define model region
* 产生圆
gen_circle (Region, Row, Column, Radius)
* 产生矩形
gen_rectangle1 (LabelRectangle, Row1, Column1, Row2, Column2)
* 计算出两个区域的交集
intersection (Region, LabelRectangle, RegionIntersection)
* 膨胀
dilation_circle (RegionIntersection, RegionROI, 5.5)
* 裁剪
reduce_domain (rImage, RegionROI, ImageReduced)
return ()
get_grayval_range (ModelImage, RegionROI, RegionForeground, RegionBackground, BackgroundGVModel, ForegroundGVModel) 获取灰度偏差函数
* 裁剪
reduce_domain (Image, RegionROI, ImageReduced)
* 二值化选取较亮的部分的区域
binary_threshold (ImageReduced, RegionBackground, 'max_separability', 'dark', UsedThreshold)
* 获取不同
difference (RegionROI, RegionBackground, RegionForeground)
* 计算平均灰度值
* 利用 intensity 函数分别计算前景区域和背景区域的图像平均灰度值以及灰度值的偏差,
*分别得到前景区域的平均灰度值(ForegroundGVal)和偏差(DeviationFG),
*以及背景区域的平均灰度值(BackgroundGVal)和偏差(DeviationBG)。
intensity (RegionForeground, Image, ForegroundGVal, DeviationFG)
intensity (RegionBackground, Image, BackgroundGVal, DeviationBG)
return ()
inspect_cap (rImage, RegionROI, WindowHandle, ModelID, VariationID, RowModel, ColumnModel, BackgroundGVModel, ForegroundGVModel) 比较灰度值的不同
*
* Find shape model in the input image
count_seconds (StartSeconds)
* 查找模板
find_scaled_shape_model (rImage, ModelID, 0, rad(360), 0.98, 1.02, 0.4, 1, 1, 'least_squares_high', [5,3], 0.9, Row, Column, Angle, Scale, Score)
count_seconds (EndSeconds)
TimeObjSearch := EndSeconds - StartSeconds
*
* 获取模型的轮廓
get_shape_model_contours (ModelContours, ModelID, 1)
*
if (|Row| > 0)* * Align the model region and the found label region* 将模型区域和找到的标签区域对齐vector_angle_to_rigid (Row[0], Column[0], Angle, RowModel[0], ColumnModel[0], 0, HomMat2DImage)affine_trans_image (rImage, ImageAffineTrans, HomMat2DImage, 'constant', 'false')*获取前景和背景的平均灰度范围get_grayval_range (ImageAffineTrans, RegionROI, RegionForegroundImage, RegionBackgroundImage, BackgroundImage, ForegroundImage)* * Scale image to the model's gray value range* 将图像缩放到模型的灰度值范围Mult := (ForegroundGVModel - BackgroundGVModel) / (ForegroundImage - BackgroundImage)Add := ForegroundGVModel - Mult * ForegroundImage* Transform the contours of the models for the visualization* 转换模型的轮廓以实现可视化vector_angle_to_rigid (0, 0, 0, Row[0], Column[0], Angle, HomMat2DContour)affine_trans_contour_xld (ModelContours, ModelContoursTrans, HomMat2DContour)* 图片进行裁剪reduce_domain (ImageAffineTrans, RegionROI, ImageReduced)* 6.将图像的灰度值进行平均缩放,筛选出不同* 缩放图像的灰度值scale_image (ImageReduced, ImageScaled, Mult, Add)* * Print Inspectioncount_seconds (StartSeconds)* 进行模板比较compare_ext_variation_model (ImageScaled, RegionDiff, VariationID, 'light_dark')count_seconds (EndSeconds)* Analyze bright and dark defect regionsdev_display (rImage)* 获取区别个数count_obj (RegionDiff, NumberRegionDiff)for i := 1 to NumberRegionDiff by 1* 选择select_obj (RegionDiff, RegionDiffSelected, i)* 开运算去除噪声opening_circle (RegionDiffSelected, RegionOpening, 2.5)* 形成单个连通域connection (RegionOpening, ConnectedRegions)* 筛选出面积select_shape (ConnectedRegions, DefectRegions, 'height', 'and', 20, 99999)* * Transform regions to the original position in the input image* 仿射运算hom_mat2d_invert (HomMat2DImage, HomMat2DInvert)affine_trans_region (DefectRegions, DefectRegionsTrans, HomMat2DInvert, 'nearest_neighbor')closing_circle (DefectRegionsTrans, DefectRegionsClosing, 1.5)* * Display bright and dark defects using different colorsdev_set_line_width (2)dev_set_draw ('fill')if (i == 1)dev_set_color ('red')elsedev_set_color ('orange')endifdev_display (DefectRegionsClosing)* * Emphasize defect regionsdev_set_color ('magenta')dev_set_draw ('margin')union1 (DefectRegionsClosing, RegionUnion)closing_circle (RegionUnion, RegionClosing, 10)connection (RegionClosing, DefectRegionEnlarged)*计算等效椭圆的参数elliptic_axis (DefectRegionEnlarged, Ra, Rb, Phi)if (|Phi|)*获取坐标点的位置area_center (DefectRegionEnlarged, Area, RowEllipse, ColumnEllipse)* 产生圆gen_ellipse (Ellipse, RowEllipse, ColumnEllipse, Phi, Ra * 2, Rb * 2)dev_display (Ellipse)endifendfordev_set_line_width (1)dev_set_color ('green')dev_display (ModelContoursTrans)* TimePrintInspect := EndSeconds - StartSecondsdisp_message (WindowHandle, 'Inspection Time: ' + ((TimeObjSearch + TimePrintInspect) * 1000.0)$'.04' + ' ms', 'window', 12, 12, 'black', 'true')
elsedisp_message (WindowHandle, 'No shape model found.', 'window', 12, 12, 'red', 'true')
endif
*
return ()
Halcon 对于每个字符进行单独检测
* 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. The program is similar to the program print_check.hdev.
* The main difference is that each character is checked separately. This is not
* a particularly good strategy for this application because it does not detect
* errors that lie on the clip itself and errors because the V moves with respect
* to the other characters. In some applications, however, precisely this
* invariance is useful. This program can be used as a basis for such
* applications. In the first step, variation models for each character are
* constructed from images of correct prints. Since the position of the objects can
* vary, the images of the different characters must be transformed to a reference
* position (the position of the character in the variation model). The position of
* the character in the model is given by selecting a part of the first image that
* to the character and a buffer around the character from the first image. The
* operator affine_trans_image_size is used to perform this task efficiently.
* HALCON's shape-based matching is used to detect the pose of each
* character in the images in a single call to find_shape_models. The found
* poses are used to transform the images of the different characters to their
* respective reference positions. In the second part of the program, the prints
* of the correct clips and of several incorrect clips is checked and classified.
* 1.读取图像,阈值处理
dev_update_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)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_color ('red')
dev_display (Image)
* Note: the shape models will be constructed from ROIs that are computed
* automatically based on a simple image segmentation.
*阈值处理
threshold (Image, Region, 100, 255)
fill_up (Region, RegionFillUp)
* 区分填充的和阈值部分不同的区域
difference (RegionFillUp, Region, RegionDifference)
* 形成一个凸性的图像
shape_trans (RegionDifference, RegionTrans, 'convex')
* 膨胀
dilation_circle (RegionTrans, RegionDilation, 8.5)
* 将膨胀图像和原图进行裁剪
reduce_domain (Image, RegionDilation, ImageReduced)
* 将裁剪图像进行阈值处理
threshold (ImageReduced, Region, 0, 180)
* 形成单独的连通域
connection (Region, ConnectedRegions)
* 排序
sort_region (ConnectedRegions, SortedRegions, 'character', 'true', 'row')
* 膨胀
dilation_circle (SortedRegions, RegionDilation, 1.5)
* 产生最小矩形
smallest_rectangle1 (RegionDilation, Row1, Column1, Row2, Column2)
*gen_rectangle1(Rectangle, Row1, Column1, Row2, Column2)
count_obj (RegionDilation, Number)
Heights := Row2 - Row1 + 5
Widths := Column2 - Column1 + 5
* 2.获取轮廓框架
* 产生一个空的形状模型
gen_empty_obj (ShapeModels)
* 产生一个空的不同形状的模型
gen_empty_obj (VariationModelROIs)
ShapeModelIDs := []
VariationModelIDs := []
RowsRef := []
ColumnsRef := []
for I := 1 to Number by 1select_obj (RegionDilation, ObjectSelected, I)Height := Heights[I - 1]Width := Widths[I - 1]* 移动区域move_region (ObjectSelected, RegionMoved, -Row1[I - 1], -Column1[I - 1])* 裁剪出一个或多个矩形图像区域crop_part (Image, ImagePart, Row1[I - 1], Column1[I - 1], Widths[I - 1], Heights[I - 1])* 将矩形区域和移动的区域裁剪reduce_domain (ImagePart, RegionMoved, ImageReduced)* 加入到形状匹配模型inspect_shape_model (ImageReduced, ModelImages, ModelRegions, 1, [15,15,10])* 产生亚像素框架轮廓gen_contours_skeleton_xld (ModelRegions, ModelContour, 1, 'filter')* 获取裁剪区域的面积和行列坐标area_center (RegionMoved, 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)* 连接两个标志性的对象元组(空的形状模型和框架组成一个轮廓)concat_obj (ShapeModels, ModelContour, ShapeModels)* 连接两个标志性的对象元组(空的不同轮廓和移动的区域组成轮廓)concat_obj (VariationModelROIs, RegionMoved, VariationModelROIs)ShapeModelIDs := [ShapeModelIDs,ShapeModelID]VariationModelIDs := [VariationModelIDs,VariationModelID]RowsRef := [RowsRef,RowRef]ColumnsRef := [ColumnsRef,ColumnRef]
endfor
* Visualize the different shape models.
* 3.可视化不同的形状模型
* 产生一个空的模型,将空的模型与选中的模型拼接
gen_empty_obj (Models)
for I := 1 to Number by 1select_obj (ShapeModels, ModelSelected, I)hom_mat2d_identity (HomMat2DIdentity)hom_mat2d_translate (HomMat2DIdentity, Row1[I - 1], Column1[I - 1], HomMat2D)* 将选中的模板进行仿射变换affine_trans_contour_xld (ModelSelected, ModelTrans, HomMat2D)* 仿射变换后的模板进行拼接concat_obj (Models, ModelTrans, Models)
endfor
dev_display (Image)
dev_set_colored (6)
dev_set_draw ('margin')
dev_set_line_width (3)
dev_display (Models)
dev_set_color ('yellow')
disp_message (WindowHandle, 'Shape models', 'image', 12, 20, 'yellow', 'false')
disp_message (WindowHandle, '(moved to original pos.)', 'image', 45, 20, 'yellow', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* Train the different variation models.
* 3.查找模型,训练不同的模型
for J := 1 to 15 by 1read_image (Image, 'pen/pen-' + J$'02d')* 查找模板find_shape_models (Image, ShapeModelIDs, rad(-10), rad(20), 0.5, [1,1,1,1,1], 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score, Model)for K := 0 to |Score| - 1 by 1vector_angle_to_rigid (Row[K], Column[K], Angle[K], RowsRef[Model[K]], ColumnsRef[Model[K]], 0, HomMat2D)affine_trans_image_size (Image, ImageTrans, HomMat2D, 'constant', Widths[Model[K]], Heights[Model[K]])select_obj (VariationModelROIs, ROI, Model[K] + 1)reduce_domain (ImageTrans, ROI, ImageTransReduced)* 训练出不同的模型train_variation_model (ImageTransReduced, VariationModelIDs[Model[K]])endfor
endfor
* Visualize the variation models' data.
* 4.模板差异比较
get_image_size (Image, Width, Height)
* 产生一个平均图片
gen_empty_obj (MeanImages)
* 产生一个不同的图片
gen_empty_obj (VarImages)
gen_empty_obj (ROIs)
for I := 1 to Number by 1* 返回变量模型用于图像比较的图像,返回训练后的图片和差异图像get_variation_model (MeanImage, VarImage, VariationModelIDs[I - 1])* 准备一个变化模型,以便与图像进行比较prepare_variation_model (VariationModelIDs[I - 1], 20, 3)* 选择物体select_obj (VariationModelROIs, ROI, I)* 移动到指定区域move_region (ROI, ROIMoved, Row1[I - 1], Column1[I - 1])* 平均图片裁剪到指定位置reduce_domain (MeanImage, ROI, MeanImageReduced)* 不同的图片裁剪reduce_domain (VarImage, ROI, VarImageReduced)* 将平均图片concat_obj (MeanImages, MeanImageReduced, MeanImages)concat_obj (VarImages, VarImageReduced, VarImages)concat_obj (ROIs, ROIMoved, ROIs)* We can now free the training data to save some memory.clear_train_data_variation_model (VariationModelIDs[I - 1])
endfor
* 将多个图像对象平铺成具有明确定位信息的大图像。
tile_images_offset (MeanImages, MeanImage, Row1, Column1, gen_tuple_const(Number,-1), gen_tuple_const(Number,-1), gen_tuple_const(Number,-1), gen_tuple_const(Number,-1), Width, Height)
tile_images_offset (VarImages, VarImage, Row1, Column1, gen_tuple_const(Number,-1), gen_tuple_const(Number,-1), gen_tuple_const(Number,-1), gen_tuple_const(Number,-1), Width, Height)
*获取图像的域
get_domain (Image, Domain)
dev_set_color ('black')
dev_set_draw ('fill')
dev_display (Domain)
dev_display (MeanImage)
dev_set_colored (6)
dev_set_draw ('margin')
dev_set_line_width (1)
dev_display (ROIs)
dev_set_color ('yellow')
disp_message (WindowHandle, 'Reference images', 'image', 20, 20, 'yellow', 'false')
disp_message (WindowHandle, '(moved to original pos.)', 'image', 45, 20, 'yellow', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_set_color ('black')
dev_set_draw ('fill')
dev_display (Domain)
dev_display (VarImage)
dev_set_colored (6)
dev_set_draw ('margin')
dev_set_line_width (1)
dev_display (ROIs)
dev_set_color ('yellow')
disp_message (WindowHandle, 'Variation images', 'image', 20, 20, 'yellow', 'false')
disp_message (WindowHandle, '(moved to original pos.)', 'image', 45, 20, 'yellow', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* Find the printing errors.
* 5.查找不同点
for J := 1 to 31 by 1read_image (Image, 'pen/pen-' + J$'02d')* 产生一个错误的空图像gen_empty_obj (RegionsErrorTrans)* 查找模板find_shape_models (Image, ShapeModelIDs, rad(-10), rad(20), 0.5, [1,1,1,1,1], 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score, Model)NumberFound := |Score|* 逐个图像仿射运算for K := 0 to NumberFound - 1 by 1vector_angle_to_rigid (Row[K], Column[K], Angle[K], RowsRef[Model[K]], ColumnsRef[Model[K]], 0, HomMat2D)affine_trans_image_size (Image, ImageTrans, HomMat2D, 'constant', Widths[Model[K]], Heights[Model[K]])select_obj (VariationModelROIs, VariationModelROI, Model[K] + 1)reduce_domain (ImageTrans, VariationModelROI, ImageTransReduced)* 将图像与变化模型进行比较。compare_variation_model (ImageTransReduced, RegionDiff, VariationModelIDs[Model[K]])connection (RegionDiff, ConnectedRegions)* 获取图像区域面积的大小select_shape (ConnectedRegions, RegionsError, 'area', 'and', 20, 1000000)count_obj (RegionsError, NumError)if (NumError > 0)vector_angle_to_rigid (RowsRef[Model[K]], ColumnsRef[Model[K]], 0, Row[K], Column[K], Angle[K], HomMat2D)affine_trans_region (RegionsError, RegionErrorTrans, HomMat2D, 'nearest_neighbor')concat_obj (RegionsErrorTrans, RegionErrorTrans, RegionsErrorTrans)endifendfordev_clear_window ()dev_display (Image)dev_set_color ('red')dev_display (RegionsErrorTrans)count_obj (RegionsErrorTrans, NumError)* 如果错误个数为0 个,找的的图像数量和原有数量相同就OK否则NGif (NumError == 0 and NumberFound == Number)disp_message (WindowHandle, 'Clip OK', 'image', 20, 20, 'green', 'false')elsedisp_message (WindowHandle, 'Clip not OK', 'image', 20, 20, 'red', 'false')endifif (J < 30)disp_continue_message (WindowHandle, 'black', 'true')stop ()endif
endfor
* 6.清除
for I := 1 to Number by 1clear_shape_model (ShapeModelIDs[I - 1])clear_variation_model (VariationModelIDs[I - 1])
endfor