以下是学习HALCON中语义分割例程segment_pill_defects_deep_learning_1_preprocess的笔记。
一、创建个数据集
开始halcon语义分割的第一步是创建一个用于深度学习的语义分割的模型,在这个模型中将设置各种用于深度学习的参数。
1、模型的数据结构如下:
DLDataset
{
'image_dir' : 所有图像文件夹路径
'segmentation_dir' : 所有标签图像文件夹的路径
'class_names'[] : 类名
'class_ids'[] : 类ID
'samples'[] : 样本,将图片和与它相对应标签图片路径配对
{
'image_file_name' : 相对于'image_dir'的图片文件路径(包括图片文件名)
'segmentation_file_name' : 相对于'segmentation_dir'的标签图像文件路径(包括标签图像文件名)
'image_id' : 图像索引号
'split' :所属的子集(训练,验证和测试)
'dlsample_file_name' :对应这个样本的DLSampleBatch保存在硬盘上的文件名
}
'preprocess_param'[] :记录预处理参数的数据结构,在第三段中有详细的记录
'dlsample_dir' :DLSampleBatch的输出路径
'class_weights' :每个类的权重
}
2、在创建模型前要检查以下几点:
二、划分样本,分为三个不相交的子集:训练,验证和测试并在模型的'samples'项中注明
例程中要求按照训练75%、验证15%、测试15%的百分比化分。
三、创建一个预处理参数的数据结构,并保存
结构如下:
DLPreprocessParam
{
'model_type' :结构的类型
‘image_width’ :图片的宽
‘image_heigh' :图片的高
’image_num_channels‘:图片的通道数
'image_range_min' :图片的最小灰度值
‘image_range_max’ :图片的最大灰度值
’contrast_normalization‘:是否归一化
'domain_handling' :域处理
'ignore_class_ids' []:类ID
'set_background_id'[] :设定背景编号
'class_ids_background'[]:类ID背景
}
创建完成,会将这个结构包存在硬盘上,在语义分割时会用到这个结构。
四、预处理
1.创建DLSampleBatch它包括一个索引,一个根据预处理参数处理过的图像和一个与它对应的标签图片。
DLSampleBatch
{
'image_id' :索引号
'image' :样本图片-根据预处理参数处理过的图像
'segmentation_image':标签图片
'weight_image':权重图片
}
2.计算类权重
先统计全部样本的每个类的像素总和,
求全部类像素总和,
计算逆类频率。(就是取反 每个类的像素占像素总和的百分比)
将百分比最高的类的权重缩放为1,其它类同比缩放。
将权重大于1000的权重设为1000。
为DLDataset中的每个训练样本生成一个权重图像,该权重图像用作分割模型中损失函数(loss)的输入。
权重图像就是用权重去标注每个像素所属的类。
*
*此示例是一系列示例的一部分,该示例总结了
* DL细分的工作流程。它使用MVTec药丸数据集。
*
*四个部分是:
* 1.数据集预处理。
* 2.训练模型。
* 3.评估训练后的模型。
* 4.推断新图像。
*
*此示例包含第1部分:“数据集预处理”
*
dev_update_off ()
*
*在此示例中,预处理步骤在图形窗口中进行了说明,
*在执行之前。将以下参数设置为false以便
*跳过此可视化。
ShowExampleScreens := 0
*
*初始示例窗口和参数等
dev_example_init (ShowExampleScreens, ExampleInternals)
*
if (ShowExampleScreens)
*
*示例系列的简介文本。
dev_display_screen_introduction_part_1 (ExampleInternals)
stop ()
dev_display_screen_introduction_part_2 (ExampleInternals)
stop ()
*
*解释分好类后,如何将不同的像素填上不同的颜色
dev_display_screen_segmentation_data (ExampleInternals)
stop ()
*
*说明数据集的使用方法70%用于训练 15%用于验证 15%用于测试
dev_display_screen_split_dataset (ExampleInternals)
stop ()
*
*说明了如何使用hom_系列算子对图像进行缩放、平移的预处理。
dev_display_screen_preprocessing_params (ExampleInternals)
stop ()
dev_display_screen_weight_images (ExampleInternals)
stop ()
*
*解释下一步。
dev_display_screen_next_steps (ExampleInternals)
stop ()
endif
*
* ***************************************
* ***设置输入/输出路径。***
* ***************************************
*
*带有图像数据的目录。
ImageDir := 'pill'
* Directory with ground truth segmentation images.带有地面真相分割图像的目录。
SegmentationDir := 'labels/pill'
*
*所有示例数据都写入此文件夹。
ExampleDataDir := 'segment_pill_defects_data'
*由preprocess_dl_dataset编写的任何输出的数据集目录基本名称。
*该名称将扩展为数据集在预处理后将具有的图像尺寸。
DataDirectoryBaseName := ExampleDataDir + '/dldataset_pill_'
*单独存储预处理参数以便在推理期间使用它。
*该名称将扩展为数据集在预处理后将具有的图像尺寸。
PreprocessParamFileBaseName := ExampleDataDir + '/dl_preprocess_param_'
*
* *************************
* ***设置参数***
* *************************
*
*类名。
ClassNames := ['good','contamination','crack']
* 类 IDs.
ClassIDs := [0,1,2]
*
*分割数据集的百分比。
TrainingPercent := 70
ValidationPercent := 15
*
*图像尺寸在预处理期间会重新缩放到图像。
ImageWidth := 400
ImageHeight := 400
ImageNumChannels := 3
*
*灰度值范围,用于图像的灰度值归一化。
ImageRangeMin := -127
ImageRangeMax := 128
*
*用于图像预处理的其他参数。
ContrastNormalization := 'false'
DomainHandling := 'full_domain'
IgnoreClassIDs := []
SetBackgroundID := []
ClassIDsBackground := []
SeedRand := 42
*
* ***************************************************** ****************************
* **读取标记的数据并将其分为训练/验证和测试***
* ***************************************************** ****************************
*
*设置随机种子。
set_system ('seed_rand', SeedRand)
*
*读取数据集。
read_dl_dataset_segmentation (ImageDir, SegmentationDir, ClassNames, ClassIDs, [], [], [], DLDataset)
*
*生成拆分。
split_dl_dataset (DLDataset, TrainingPercent, ValidationPercent, [])
*
* *************************************
* **预处理数据集***
* *************************************
*
*创建输出目录(如果尚不存在)。
file_exists (ExampleDataDir, FileExists)
if (not FileExists)
make_dir (ExampleDataDir)
endif
*
*创建预处理参数。
create_dl_preprocess_param ('segmentation', ImageWidth, ImageHeight, ImageNumChannels, ImageRangeMin, ImageRangeMax, ContrastNormalization, DomainHandling, IgnoreClassIDs, SetBackgroundID, ClassIDsBackground, [], DLPreprocessParam)
*
*单独存储预处理参数以便在推理期间使用它。
PreprocessParamFile := PreprocessParamFileBaseName + ImageWidth + 'x' + ImageHeight + '.hdict'
write_dict (DLPreprocessParam, PreprocessParamFile, [], [])
*
*数据集目录,用于由preprocess_dl_dataset编写的任何输出。
DataDirectory := DataDirectoryBaseName + ImageWidth + 'x' + ImageHeight
*
*预处理数据集。这可能需要几分钟。
create_dict (GenParam)
set_dict_tuple (GenParam, 'overwrite_files', true)
preprocess_dl_dataset (DLDataset, DataDirectory, DLPreprocessParam, GenParam, DLDatasetFilename)
*
* ***********************************************
* **预览预处理的数据集***
* ***********************************************
*
*在继续进行训练之前,建议先检查预处理后的数据集。
*
*显示10个随机选择的火车图像的DLSamples。
get_dict_tuple (DLDataset, 'samples', DatasetSamples)
find_dl_samples (DatasetSamples, 'split', 'train', 'match', SampleIndices)
tuple_shuffle (SampleIndices, ShuffledIndices)
read_dl_samples (DLDataset, ShuffledIndices[0:9], DLSampleBatchDisplay)
*
create_dict (WindowHandleDict)
for Index := 0 to |DLSampleBatchDisplay| - 1 by 1
*在DLSampleBatchDisplay中循环采样
dev_display_dl_data (DLSampleBatchDisplay[Index], [], DLDataset, ['image','segmentation_image_ground_truth'], [], WindowHandleDict)
get_dict_tuple (WindowHandleDict, 'segmentation_image_ground_truth', WindowHandleImage)
dev_set_window (WindowHandleImage[1])
Text := 'Press Run (F5) to continue'
dev_disp_text (Text, 'window', 400, 40, 'black', [], [])
stop ()
endfor
*
*关闭用于可视化的窗口。
dev_display_dl_data_close_windows (WindowHandleDict)
*
if (ShowExampleScreens)
*提示DL分段训练过程示例。
dev_display_screen_next_example (ExampleInternals)
stop ()
*关闭示例窗口。
dev_close_example_windows (ExampleInternals)
endif