1 Halcon数据结构
2 一致性增强扩散
3 锯片检测
4 序列号读取
5 印刷检测
本次例程是检测继电器上的文字和电路图。检查是否有模糊、飞墨、缺失和移位。
a. 创建可变模型和形状模型
b. 使用形状模型将待检图像与参考图像对齐
c. 使用可变模型比较待测图像得到印刷缺陷
*
* 此示例演示了使用单个参考图像进行印刷检查的过程。
*
* 读取参考图像并初始化程序。
read_image(Image, 'relay/relay_01')
dev_close_window()
dev_open_window_fit_image(Image, 0, 0, 600, 500, WindowHandle1)
set_display_font(WindowHandle1, 16, 'mono', 'true', 'false')
dev_update_off()
dev_display(Image)
get_image_size(Image, Width, Height)
Pi := rad(180)
*
* 读取手动预定义的感兴趣区域。
read_region(ROI, 'relay/relay_inspection_roi.reg')
reduce_domain(Image, ROI, ImageReduced)
*
* 显示参考图像。
dev_clear_window()
dev_display(ImageReduced)
dev_disp_text('参考图像', 'window', 12, 12, 'black', [], [])
disp_continue_message(WindowHandle1, 'black', 'true')
stop()
*
* 在该应用中,通过使用边缘幅度作为标准差的近似值,从单个参考图像创建可变模型。
Sigma := 0.5
edges_image(ImageReduced, ImaAmp, ImaDir, 'canny', Sigma, 'none', 20, 40)
gray_dilation_rect(ImaAmp, VariationImage, 3, 3)
*
* 显示可变图像。
dev_clear_window()
dev_display(VariationImage)
dev_disp_text('可变图像', 'window', 12, 12, 'black', [], [])
disp_continue_message(WindowHandle1, 'black', 'true')
stop()
*
* 创建可变模型
AbsThreshold := 15
VarThreshold := 1
create_variation_model(Width, Height, 'byte', 'direct', VarModelID)
prepare_direct_variation_model(ImageReduced, VariationImage, VarModelID, AbsThreshold, VarThreshold)
*
* 为测试图像的对齐创建形状模型。
* 为了加快匹配,只使用印刷的部分作为模板。
read_region(MatchingROI, 'relay/relay_matching_roi')
reduce_domain(Image, MatchingROI, Template)
create_shape_model(Template, 5, -rad(5), rad(10), 'auto', 'auto', 'use_polarity', 'auto', 'auto', ShapeModelID)
area_center(MatchingROI, ModelArea, ModelRow, ModelColumn)
*
* 仅出于可视化目的提取亚像素精确边缘。
edges_sub_pix(ImageReduced, Edges, 'sobel_fast', 0.5, 10, 20)
*
* 检查几个继电器上的印记。
for Index := 2 to 6 by 1
*
* 读取测试图像。
read_image(Image, 'relay/relay_' + Index$'02d')
*
* 确定测试图像中印记的准确位置。
find_shape_model(Image, ShapeModelID, -rad(5), rad(10), 0.5, 1, 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
*
* 如果可以找到印记,则检查印记。
if(|Score| == 1)
*
* 将图像与参考图像对齐。
vector_angle_to_rigid(Row, Column, Angle, ModelRow, ModelColumn, 0, HomMat2D)
affine_trans_image(Image, ImageAligned, HomMat2D, 'constant', 'false')
*
* 将当前测试图像与参考图像进行比较。
reduce_domain(ImageAligned, ROI, ImageAlignedReduced)
compare_variation_model(ImageAlignedReduced, RegionDiff, VarModelID)
*
* 选择表示印记错误的区域。
MinComponentSize := 5
dilation_circle(RegionDiff, RegionDilation, 3.5)
connection(RegionDilation, ConnectedRegions)
intersection(ConnectedRegions, RegionDiff, RegionIntersection)
select_shape(RegionIntersection, SelectedRegions, 'area', 'and', MinComponentSize, ModelArea)
*
* 显示结果。
dev_display(ImageAligned)
count_obj(SelectedRegions, NumberDefects)
if(NumberDefects > 0)
dev_disp_text('Image ' + Index + ': ' + NumberDefects + ' Errors found', 'window', 12, 12, 'black', [], [])
dev_set_color('green')
dev_set_line_width(1)
dev_display(Edges)
dev_set_color('red')
dev_set_line_width(3)
area_center(SelectedRegions, Area, Row, Column)
elliptic_axis(SelectedRegions, Ra, Rb, Phi)
gen_ellipse_contour_xld(ErrorMarker, Row, Column, Phi, Ra + 5, Rb + 5, gen_tuple_const(|Row|,0), gen_tuple_const(|Row|,6.28318), gen_tuple_const(|Row|,'positive'), 1.5)
dev_display(ErrorMarker)
else
dev_disp_text('Image ' + Index + ': OK', 'window', 12, 12, 'black', [], [])
dev_set_color('green')
dev_set_line_width(1)
dev_display(Edges)
endif
else
if(|Score| == 0)
dev_disp_text('Image ' + Index + ': Pattern to be tested could not be found', 'window', 12, 12, 'black', [], [])
else
dev_disp_text('Image ' + Index + ': Pattern to be tested was found ambiguously', 'window', 12, 12, 'black', [], [])
endif
endif
disp_continue_message(WindowHandle1, 'black', 'true')
stop()
endfor
*
* 清理
clear_shape_model(ShapeModelID)
clear_variation_model(VarModelID)
dev_disp_text(' 程序结束 ', 'window', 'bottom', 'right', 'black', [], [])
a. 创建可变模型和形状模型
*
* 创建可变模型
AbsThreshold := 15
VarThreshold := 1
create_variation_model(Width, Height, 'byte', 'direct', VarModelID)
prepare_direct_variation_model(ImageReduced, VariationImage, VarModelID, AbsThreshold, VarThreshold)
*
* 为测试图像的对齐创建形状模型。
* 为了加快匹配,只使用印刷的部分作为模板。
read_region(MatchingROI, 'relay/relay_matching_roi')
reduce_domain(Image, MatchingROI, Template)
create_shape_model(Template, 5, -rad(5), rad(10), 'auto', 'auto', 'use_polarity', 'auto', 'auto', ShapeModelID)
area_center(MatchingROI, ModelArea, ModelRow, ModelColumn)
b. 使用形状模型将待检图像与参考图像对齐
*
* 读取测试图像。
read_image(Image, 'relay/relay_' + Index$'02d')
*
* 确定测试图像中印记的准确位置。
find_shape_model(Image, ShapeModelID, -rad(5), rad(10), 0.5, 1, 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
*
* 如果可以找到印记,则进行对齐。
if(|Score| == 1)
*
* 将图像与参考图像对齐。
vector_angle_to_rigid(Row, Column, Angle, ModelRow, ModelColumn, 0, HomMat2D)
affine_trans_image(Image, ImageAligned, HomMat2D, 'constant', 'false')
endif
c. 使用可变模型比较待测图像得到印刷缺陷
*
* 将当前测试图像与参考图像进行比较。
reduce_domain(ImageAligned, ROI, ImageAlignedReduced)
compare_variation_model(ImageAlignedReduced, RegionDiff, VarModelID)
*
* 选择表示印记错误的区域。
MinComponentSize := 5
dilation_circle(RegionDiff, RegionDilation, 3.5)
connection(RegionDilation, ConnectedRegions)
intersection(ConnectedRegions, RegionDiff, RegionIntersection)
select_shape(RegionIntersection, SelectedRegions, 'area', 'and', MinComponentSize, ModelArea)
本次印刷检测程序,演示了如何检测继电器上的印刷缺陷。要点是利用形状模型对齐图像和利用可变模型检测缺陷。上述程序必须保证待测图像的照明条件与参考图像一致,才能使用可变模型,大家可以思考一下如何应对光照条件变化,欢迎评论区留言。
《机器视觉算法与应用》