模型纹理检查
这个例子利用纹理检测模型检测纹理缺陷。
这个示例程序演示了如何进行微调
*纹理检测模型。
*首先,创建和训练纹理检测模型
*使用一组无错误的纹理图像。
*接下来,对其中一个有缺陷的参数进行微调
*测试图像。
*在最后一步,收集有缺陷的和没有缺陷的
*图像被测试。
*初始化
dev_update_off ()
dev_close_window ()
read_image (Image, 'carpet/carpet_01')
get_image_size (Image, Width, Height)
NumImages := 7
*定义训练图像集。
TrainingImageIndices := [1,2]
*训练图像指数
TextureModelFilename := 'texture_model_carpet'
*纹理模型文件
* 初始可视化.
dev_open_window_fit_size (0, 0, Width, Height, -1, -1, WindowHandle1)
get_window_extents (WindowHandle1, Row, Column, WindowWidth, WindowHeight)
set_display_font (WindowHandle1, 16, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (2)
*
Message := '这个示例程序演示了如何微调'
Message[1] := '用于缺陷检测的纹理检测模型:'
Message[2] := ' '
Message[3] := '(1)创建并训练纹理检查模型
Message[4] := '使用无错误纹理的图像'
Message[5] := ' '
Message[6] := ''(2)对其中一个测试的参数进行了微调'
Message[7] := '图像。'
Message[8] := ' '
Message[9] := '(3)检测缺陷图像和非缺陷图像'
Message[10] := ' '
Message[11] := '要完全理解此程序,请阅读'
Message[12] := '源代码中的注释。'
dev_disp_text (Message, 'window', 12, 12, 'black', [], [])
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
*首先我们尝试读取纹理检测模型
*(仅当示例之前运行过时有效)
file_exists (TextureModelFilename + '.htim', FileExists)
if (FileExists)
read_texture_inspection_model (TextureModelFilename, TextureInspectionModel)
get_texture_inspection_model_param (TextureInspectionModel, 'levels', Levels)
Message := '读取之前训练的纹理检测模型.'
Message[1] := ' '
else
* 训练一个新的纹理检查模型.
*
* 创建内部数据结构.
create_texture_inspection_model ('basic', TextureInspectionModel)
*
* 阅读并添加样本图像进行训练.
for Index := 0 to |TrainingImageIndices| - 1 by 1
read_image (Image, 'carpet/carpet_' + TrainingImageIndices[Index]$'02')
dev_display (Image)
Message := '添加图片 ' + (Index + 1) + ' of ' + |TrainingImageIndices| + '到训练集.'
dev_disp_text (Message, 'window', 12, 12, 'black', [], [])
* 使用整个图像作为纹理样本
*在不同的应用程序中,你可能想先缩小图像域。.
add_texture_inspection_model_image (Image, TextureInspectionModel, Indices)
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
endfor
*
* 训练可能需要一段时间,特别是当使用大图像时.
dev_display (Image)
Message[0] := '训练纹理检测模型.'
Message[1] := ' '
Message[2] := '这可能需要一分钟 (看'
Message[3] := '进度的状态栏).'
dev_disp_text (Message, 'window', 12, 12, 'black', [], [])
*
* 定义训练参数.
* 将归一化设置为“weber”,以允许处理不同亮度的图像.
set_texture_inspection_model_param (TextureInspectionModel, 'patch_normalization', 'weber')
*
* 高分辨率的图像会导致较长的训练和执行时间.
* 在许多情况下,在较低的分辨率下可以检测到缺陷
* (对应于更高的金字塔层次),也.
Levels := [2,3,4]
set_texture_inspection_model_param (TextureInspectionModel, 'levels', Levels)
*
* 开始训练.
train_texture_inspection_model (TextureInspectionModel)
*
* 将纹理模型写入磁盘
write_texture_inspection_model (TextureInspectionModel, TextureModelFilename)
*
Message := '训练很成功.'
Message[1] := ' '
endif
*
Message[2] := '我们现在可以通过评估测试图像上的'
Message[3] := ' 新颖性检测结果来微调参数'
dev_disp_text (Message, 'window', 12, 12, 'black', [], [])
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop()
*
*我们得到了新颖性阈值,以便在测试阶段显示它们.
* 新阈值定义了每一个金字塔级别,在这一点上区分有缺陷和无缺陷的纹理
* 较低的阈值会导致更多的错误检测,但也可能导致更多的误报(无缺陷的纹理区域作为缺陷返回)
get_texture_inspection_model_param (TextureInspectionModel, 'novelty_threshold', NoveltyThreshold)
*
*调试产生的信息在apply_texture_inspection_model执行期间存储了。
* 注意,必须使用clear_texture_inspection_result释放result句柄。
set_texture_inspection_model_param (TextureInspectionModel, 'gen_result_handle', 'true')
*
WindowWidth := 320
WindowHeight := 280
dev_open_window (0, 0, WindowWidth, WindowHeight, 'black', WindowHandle1)
set_display_font (WindowHandle1, 16, 'mono', 'true', 'false')
dev_open_window (0, WindowWidth + 8, WindowWidth, WindowHeight, 'black', WindowHandle2)
set_display_font(WindowHandle2, 16, 'mono', 'true', 'false')
dev_open_window (0, 2 * WindowWidth + 16, WindowWidth, WindowHeight, 'black', WindowHandle3)
set_display_font(WindowHandle3, 16, 'mono', 'true', 'false')
dev_open_window (WindowHeight + 50, WindowWidth / 2 + 8, 2 * WindowWidth, 2 * WindowHeight, 'black', WindowHandle4)
set_display_font(WindowHandle4, 16, 'mono', 'true', 'false')
WindowHandles := [WindowHandle1,WindowHandle2,WindowHandle3]
*
* 检测第一个训练图像的纹理缺陷,以微调参数.
for Index := 1 to 3 by 1
ImageIndex := 5
read_image (TestImage, 'carpet/carpet_' + ImageIndex$'02')
*
* 检查当前图像.
apply_texture_inspection_model (TestImage, NoveltyRegion, TextureInspectionModel, TextureInspectionResultID)
* 检查调试信息.
* 新颖性得分图像可用于单独微调新颖性阈值。.
get_texture_inspection_result_object (NovScoreImage, TextureInspectionResultID, 'novelty_score_image')
get_texture_inspection_result_object (NovRegion, TextureInspectionResultID, 'novelty_region')
* 清理结果句柄
clear_texture_inspection_result (TextureInspectionResultID)
*
* 显示单个尺度的结果
count_obj (NovScoreImage, Number)
for Level := 1 to Number by 1
CurrentWindow := WindowHandles[Level - 1]
dev_set_window (CurrentWindow)
select_obj (NovScoreImage, NovScoreImageL, Level)
select_obj (NovRegion, NovRegionL, Level)
get_image_size (NovScoreImageL, Width, Height)
dev_set_part (0, 0, Height - 1, Width - 1)
dev_display (NovScoreImageL)
Legend := 'Novelty region (level ' + Levels[Level - 1] + ')'
dev_set_color ('red')
*
dev_display (NovRegionL)
dev_disp_text (['Novelty score image (level ' + Levels[Level - 1] + ')','Novelty threshold: ' + NoveltyThreshold[Level - 1]$'.1f'], 'window', 12, 12, 'black', [], [])
dev_disp_text (Legend, 'window', WindowHeight - 30, 12, 'white', ['box_color','shadow'], ['black','false'])
* 注意,apply_texture_inspection_model返回的NoveltyRegion是通过组合各个金字塔层的各个新奇区域而派生的.
endfor
*
* 显示结果
dev_set_window (WindowHandle4)
dev_display (TestImage)
dev_set_color ('red')
dev_display (NoveltyRegion)
area_center (NoveltyRegion, Area, Row, Column)
if (Index < 3)
dev_disp_text ('Result', 'window', 12, 12, 'black', [], [])
else
dev_disp_text ('Final result', 'window', 12, 12, 'black', [], [])
endif
*
* 对于第一个图像,我们微调参数,以确保最佳参数设置
if (Index == 1)
Message[0] := 'There are many small errors in the image.'
Message[1] := 'It is possible to adapt the sensitivity by altering'
Message[2] := 'the novelty thresholds.'
Message[3] := 'For example, this can be done by decreasing the'
Message[4] := 'value of the \'sensitivity\' parameter'
dev_disp_text (Message, 'window', 12, 12, 'black', [], [])
* 微调新颖性阈值。
*
* 设置阈值计算的灵敏度。负值导致更高的阈值,因此检测到的缺陷更少。
set_texture_inspection_model_param (TextureInspectionModel, 'sensitivity', -10)
get_texture_inspection_model_param (TextureInspectionModel, 'novelty_threshold', NoveltyThreshold)
endif
*
if (Index == 2)
Message := 'It is also possible to adapt the sensitivity'
Message[1] := 'of the single levels individually by manipulating'
Message[2] := 'the novelty boundaries directly.'
dev_disp_text (Message, 'window', 12, 12, 'black', [], [])
* 微调新颖性阈值.
*
* 从纹理检测模型中获取(自动确定的)新颖性阈值,并设置适当修改值作为新颖性阈值。
*
* 如果我们明确地设定了新颖性的界限,敏感性就被忽略了。
* 为了避免混淆,我们把它设回0
set_texture_inspection_model_param (TextureInspectionModel, 'sensitivity', 0)
*
Offset := [25,10,30]
get_texture_inspection_model_param(TextureInspectionModel, 'novelty_threshold', NoveltyThreshold)
set_texture_inspection_model_param (TextureInspectionModel, 'novelty_threshold', Offset + NoveltyThreshold)
get_texture_inspection_model_param(TextureInspectionModel, 'novelty_threshold', NoveltyThreshold)
endif
*
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
endfor
*
for Level := 1 to |WindowHandles| by 1
dev_set_window (WindowHandles[Level - 1])
endfor
dev_set_window (WindowHandle4)
Message := 'With the fine-tuned parameters we can now'
Message[1] := 'detect defects in all training and test images...'
dev_disp_text (Message, 'window', 12, 12, 'black', [], [])
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
*
* 在所有测试图像上检测纹理缺陷
for Index := 1 to NumImages by 1
read_image (TestImage, 'carpet/carpet_' + Index$'02')
*
* 检查当前图像
apply_texture_inspection_model (TestImage, NoveltyRegion, TextureInspectionModel, TextureInspectionResultID)
* 检查调试信息
get_texture_inspection_result_object (NovScoreImage, TextureInspectionResultID, 'novelty_score_image')
get_texture_inspection_result_object (NovRegion, TextureInspectionResultID, 'novelty_region')
* 清理结果句柄
clear_texture_inspection_result (TextureInspectionResultID)
*
* 显示单个尺度的结果
count_obj (NovScoreImage, Number)
for Level := 1 to Number by 1
CurrentWindow := WindowHandles[Level - 1]
dev_set_window (CurrentWindow)
select_obj (NovScoreImage, NovScoreImageL, Level)
select_obj (NovRegion, NovRegionL, Level)
get_image_size (NovScoreImageL, Width, Height)
dev_set_part (0, 0, Height - 1, Width - 1)
dev_display (NovScoreImageL)
Legend := 'Novelty region (level ' + Levels[Level - 1] + ')'
dev_set_color ('red')
*
dev_display (NovRegionL)
dev_disp_text (['Novelty score image (level ' + Levels[Level - 1] + ')','Novelty threshold: ' + NoveltyThreshold[Level - 1]$'.1f'], 'window', 12, 12, 'black', [], [])
dev_disp_text (Legend, 'window', WindowHeight - 50, 12, ['red','white'], ['box_color','shadow'], ['black','false'])
* 请注意,apply_texture_inspection_model返回的NoveltyRegion是通过组合各个金字塔层次的各个新奇区域派生出来的。
endfor
*
* 显示结果
dev_set_window (WindowHandle4)
dev_display (TestImage)
dev_set_color ('red')
dev_display (NoveltyRegion)
area_center (NoveltyRegion, Area, Row, Column)
if (Area > 100)
dev_disp_text ('Not OK', 'window', 12, 12, 'white', 'box_color', 'red')
else
dev_disp_text ('OK', 'window', 12, 12, 'white', 'box_color', 'forest green')
endif
*
if (Index < NumImages)
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop()
endif
endfor
stop()
*
* 清理内存
clear_texture_inspection_model (TextureInspectionModel)