隶属于:
C:\Users\Public\Documents\MVTec\HALCON-23.05-Progress\examples\hdevelop\Deep-Learning\AnomalyDetection
- 本示例展示了全局上下文异常检测(Global Context Anomaly Detection,简称 GC-AD)的推理工作流程。
- 该网络由两个子网络组成:局部网络和全局网络
- 局部网络专注于检测结构异常
- 而全局网络则用于发现逻辑异常
- 更多关于这一主题的详细信息请参阅相关章节
*推理工作流程通常包括以下步骤:
- 1、数据集预处理
- 2、对印刷电路板(PCB)图像进行推理
- 3、(可选)使用局部网络和全局网络检查结果
- 加载全局上下文异常检测模型并设置关键参数。
read_dl_model (‘detect_pcb_gc_anomalies.hdl’, DLModelHandle)
read_dl_model读入的是一个.hdl的后缀名的模型。
DLModelHandle详情如下:
‘layer_names’
[‘lglo_weights’, ‘lglo_target’, ‘lloc_weights’, ‘lloc_target’, ‘zoom_for_patch_size_reference’, ‘zoom_for_patch_size_pass_1’, ‘image’, ‘image_rgb’, ‘image_zoomed_for_global’, ‘tglo_conv1’, ‘tglo_reduction1’, ‘tglo_conv2’, ‘tglo_reduction2’, ‘tglo_conv3’, ‘tglo_output’, ‘rglo_conv1’, ‘rglo_reduction1’, ‘rglo_conv2’, ‘rglo_reduction2’, ‘rglo_conv3’, ‘rglo_output’, ‘eglo_enc_conv1’, ‘eglo_enc_conv2’, ‘eglo_enc_conv3’, ‘eglo_enc_conv4’, ‘eglo_enc_conv5’, ‘eglo_enc_conv6’, ‘eglo_dec_zoom1’, ‘eglo_dec_conv1’, ‘eglo_dec_dropout1’, ‘eglo_dec_zoom2’, ‘eglo_dec_conv2’, ‘eglo_dec_dropout2’, ‘eglo_dec_zoom3’, ‘eglo_dec_conv3’, ‘eglo_dec_dropout3’, ‘eglo_dec_zoom4’, ‘eglo_dec_conv4’, ‘eglo_dec_dropout4’, ‘eglo_dec_zoom5’, ‘eglo_dec_conv5’, ‘eglo_dec_dropout5’, ‘eglo_dec_zoom6’, ‘eglo_dec_conv6’, ‘eglo_dec_dropout6’, ‘eglo_dec_zoom_to_output_size’, ‘eglo_dec_conv7’, ‘eglo_output’, ‘diff_glo_copy’, ‘diff_glo’, ‘diff_glo_squared’, ‘global_normalization’, ‘anomaly_image_global’, ‘lglo_loss_input_scalar’, ‘zoom_for_patch_size_pass_2’, ‘lglo_loss’, ‘lkd_loss’, ‘image_zoomed_for_patch_size’, ‘rloc_conv1’, ‘rloc_reduction1’, ‘rloc_conv2’, ‘rloc_reduction2’, ‘rloc_conv3’, ‘rloc_output’, ‘eloc_conv1’, ‘eloc_reduction1’, ‘eloc_conv2’, ‘eloc_reduction2’, ‘eloc_conv3’, ‘eloc_output’, ‘diff_loc_copy’, ‘diff_loc’, ‘diff_loc_squared’, ‘local_normalization’, ‘anomaly_image_local’, ‘anomaly_image_combined’, ‘lloc_loss_input_scalar’, ‘lloc_loss’]
* 本示例展示了全局上下文异常检测(Global Context Anomaly Detection,简称 GC-AD)的推理工作流程。
* 该网络由两个子网络组成:局部网络和全局网络
* 局部网络专注于检测结构异常
* 而全局网络则用于发现逻辑异常
* 更多关于这一主题的详细信息请参阅相关章节
*推理工作流程通常包括以下步骤:
* 1、数据集预处理
* 2、对印刷电路板(PCB)图像进行推理
* 3、(可选)使用局部网络和全局网络检查结果
dev_update_off ()
dev_close_window ()
set_system ('seed_rand', 73)
*** 0.) 设置输入/输出路径 ***
* ImageDir 是包含所用图像文件夹的基础目录
* ImageDir 中必须有一个名为“good”或“ok”的子文件夹
* 名称不同的子文件夹中的图像将被视为包含异常的图像,可用于后续的定性评估
* 存储预处理样本的文件夹
get_image_dir (HalconImages)
ImageDir := HalconImages + '/pcb_anomaly'
ImageSubDirs := ['good', 'anomaly']
*存储预处理样本的文件夹。
OutputDir := './anomaly_pcb_board_data'
*** 1.) 准备 ***
* 加载并拆分数据集
GenParamDataset := dict{image_sub_dirs: ImageSubDirs}
read_dl_dataset_anomaly (ImageDir, [], [], [], GenParamDataset, DLDataset)
*
* 在进行推理时,将完整数据集排序为测试拆分
split_dl_dataset (DLDataset, 0, 0, [])
*
* 加载全局上下文异常检测模型并设置关键参数。
read_dl_model ('detect_pcb_gc_anomalies.hdl', DLModelHandle)
*
* 设置预处理参数并进行预处理。
create_dl_preprocess_param_from_model (DLModelHandle, 'none', 'full_domain', [], [], [], DLPreprocessParam)
PreprocessSettings := dict{overwrite_files: 'true'}
preprocess_dl_dataset (DLDataset, OutputDir, DLPreprocessParam, PreprocessSettings, DLDatasetFileName)
*
* 可视化检查 10 个随机选择的预处理后的 DLSamples。
WindowDict := dict{}
DatasetSamples := DLDataset.samples
for Index := 0 to 9 by 1
SampleIndex := int(rand(1) * |DatasetSamples|)
read_dl_samples (DLDataset, SampleIndex, DLSample)
GenParam := dict{}
GenParam.display_ground_truth_anomaly_regions := false
GenParam.display_bottom_desc := false
dev_display_dl_data (DLSample, [], DLDataset, 'anomaly_ground_truth', GenParam, WindowDict)
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
dev_set_window (WindowDict.anomaly_ground_truth[0])
dev_disp_text ('Preprocessed image', 'window', 'top', 'left', 'black', [], [])
*
stop ()
endfor
dev_close_window_dict (WindowDict)
*
*根据需要使用 GPU 或 CPU 进行后续推理。
query_available_dl_devices (['runtime', 'runtime', 'id'], \
['gpu', 'cpu', 0], DLDeviceHandles)
if (DLDeviceHandles == [])
throw ('No suitable CPU or GPU was found.')
endif
DLDeviceHandle := DLDeviceHandles[0]
*
* 设置所选设备。如果遇到内存问题,请使用更强大的 GPU 或 CPU
set_dl_model_param (DLModelHandle, 'device', DLDeviceHandle)
*
* 如果可用,使用 AI2 接口进行推理。
get_dl_device_param (DLDeviceHandle, 'type', DeviceType)
query_available_dl_devices ('ai_accelerator_interface', 'tensorrt', DLDeviceHandlesTensorRT)
if (DLDeviceHandlesTensorRT == [] or DeviceType == 'cpu')
* 落到这里意味着两种情况
* DLDeviceHandle 最初被设置为使用 CPU
* 或者 TensorRT 不可用
* 按照上述设置,仅使用 GPU/CPU 设备进行操作
else
try
* 使用 float32 精度,如有需要可调整为其他精度。
get_dl_device_param (DLDeviceHandlesTensorRT, 'optimize_for_inference_params', OptiParams)
optimize_dl_model_for_inference (DLModelHandle, DLDeviceHandlesTensorRT, 'float32', [], OptiParams, DLModelHandleConverted, ConvReport)
DLModelHandle := DLModelHandleConverted
catch (Exception)
* 如果出现异常,请确保使用 GPU/CPU 设备。
stop ()
endtry
endif
*
*
*** 2.) 推理 ***
* 为了演示推理步骤,我们将训练好的模型应用于一些在训练过程中未使用过的随机选择的图像
MaxNumInferenceImages := 15
get_random_test_image_paths (DLDataset, MaxNumInferenceImages, InferenceImagePaths)
*
* 获取用于推理的阈值。这些阈值已与模型一起存储在上面的元数据中
get_dl_model_param (DLModelHandle, 'meta_data', MetaData)
InferenceClassificationThreshold := number(MetaData.anomaly_classification_threshold)
InferenceSegmentationThreshold := number(MetaData.anomaly_segmentation_threshold)
*
* 创建一个包含用于显示的数据集参数的字典
DLDatasetInfo := dict{class_names: ['ok', 'nok'], class_ids: [0, 1]}
*
* 将模型应用于测试图像
WindowDict := dict{}
for IndexInference := 0 to |InferenceImagePaths| - 1 by 1
*
read_image (Image, InferenceImagePaths[IndexInference])
gen_dl_samples_from_images (Image, DLSample)
preprocess_dl_samples (DLSample, DLPreprocessParam)
*
apply_dl_model (DLModelHandle, DLSample, [], DLResult)
*
* 应用阈值以对区域和整个图像进行分类
threshold_dl_anomaly_results (InferenceSegmentationThreshold, InferenceClassificationThreshold, DLResult)
*
* 显示推理结果。
dev_display_dl_data (DLSample, DLResult, DLDatasetInfo, ['anomaly_result', 'anomaly_image'], [], WindowDict)
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'center', 'black', [], [])
stop ()
endfor
dev_close_window_dict (WindowDict)
*
*** 3.) 检查局部网络和全局网络的异常图像 ***
* 在以下内容中,我们将可视化逻辑异常和结构异常之间的差异
* 结果显示,局部网络更有可能检测到结构异常
* 而全局网络则更擅长发现逻辑异常
* 有些缺陷会被两个子网络同时检测到
* 按 F5(继续)
stop ()
*
MaxNumInferenceImages := 12
get_random_test_anomaly_image_paths (ImageDir + '/anomaly', MaxNumInferenceImages, AnomalyInferenceImagePaths)
*
* 使用局部网络和全局网络进行图像推理
WindowDict := dict{}
for IndexInference := 0 to |AnomalyInferenceImagePaths| - 1 by 1
*
read_image (Image, AnomalyInferenceImagePaths[IndexInference])
gen_dl_samples_from_images (Image, DLSample)
preprocess_dl_samples (DLSample, DLPreprocessParam)
*
apply_dl_model (DLModelHandle, DLSample, ['anomaly_image_local', 'anomaly_image_global'], DLResult)
*
* 应用阈值以对区域和整个图像进行分类
threshold_dl_anomaly_results (InferenceSegmentationThreshold, InferenceClassificationThreshold, DLResult)
*
* 显示推理结果。
dev_display_dl_data (DLSample, DLResult, DLDatasetInfo, ['image', 'anomaly_image_local', 'anomaly_image_global'], [], WindowDict)
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'center', 'black', [], [])
stop ()
endfor
dev_close_window_dict (WindowDict)
*
*
*** 4.) 删除文件 ***
*
clean_up_output (OutputDir)