本文最后更新于:2024年1月14日 晚上

Halcon 在 2022年5月对外宣布更新了异常检测深度学习算法,本文记录使用方法。

简介

Halcon 深度学习异常检测可以用若干没有瑕疵的数据训练模型,用于检测出现问题 (异常) 的数据。

官网简介

核心流程

  1. 准备数据

    需要准备一个包含数据的字典列表,每个字典表示一张数据图像,字典中 image 字段下存放图像,其他字段记录该图像配套的信息

    过程中对图像做需要的预处理

    数据集建议使用 MVTec 自己的异常检测数据集

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116

    list_image_files (train_dir, 'default', [], ImageFiles)

    train_samples := []

    image_width := image_size[0]
    image_height := image_size[1]


    for Index := 0 to |ImageFiles|-1 by 1

    image_path := ImageFiles[Index]
    create_dict (sample_info)
    set_dict_tuple (sample_info, 'image_id', Index)
    set_dict_tuple (sample_info, 'anomaly_label', 'ok')
    set_dict_tuple (sample_info, 'anomaly_label_id', 0)
    read_image (Image, image_path)
    convert_image_type (Image, Image, 'real')

    if (Index < 1)
    image_sum := Image
    else
    add_image (Image, image_sum, image_sum, 1, 0)
    endif

    endfor

    sub_image (image_sum, image_sum, Imagezero, 1, |ImageFiles|)

    div_image (image_sum, Imagezero, ImageResult, 1, 0)

    count_channels (ImageResult, Channels)

    * 初始化均值和方差列表
    MeanValues := []
    DeviationValues := []

    if (Channels == 3)
    * 处理彩色图像
    decompose3(ImageResult, Image1, Image2, Image3)

    else
    Image1 := ImageResult
    Image2 := ImageResult
    Image3 := ImageResult
    endif

    gen_empty_obj (EmptyObject)

    concat_obj (EmptyObject, Image1, EmptyObject)
    concat_obj (EmptyObject, Image2, EmptyObject)
    concat_obj (EmptyObject, Image3, EmptyObject)

    * 计算每个通道的均值和标准差
    for ChannelIndex := 1 to 3 by 1
    select_obj (EmptyObject, ObjectSelected, ChannelIndex)
    intensity(ObjectSelected, ObjectSelected, Mean, Deviation)
    MeanValues := [MeanValues, Mean]
    DeviationValues := [DeviationValues, Deviation]
    endfor

    create_dict (data_param)
    set_dict_tuple (data_param, 'DeviationValues', DeviationValues)
    set_dict_tuple (data_param, 'MeanValues', MeanValues)


    for Index := 0 to |ImageFiles|-1 by 1

    image_path := ImageFiles[Index]
    create_dict (sample_info)
    set_dict_tuple (sample_info, 'image_id', Index)
    set_dict_tuple (sample_info, 'anomaly_label', 'ok')
    set_dict_tuple (sample_info, 'anomaly_label_id', 0)

    read_image (Image, image_path)
    convert_image_type (Image, Image, 'real')
    zoom_image_size (Image, Image, image_width, image_height, 'bilinear')

    count_channels (Image, Channels)

    if (Channels == 3)
    * 处理彩色图像
    decompose3(Image, Image1, Image2, Image3)
    else
    Image1 := Image
    Image2 := Image
    Image3 := Image
    endif

    gen_empty_obj (ImageScaled)

    Scale1 := 1.0 / DeviationValues[0]
    Shift1 := - Scale1 * MeanValues[0]
    scale_image (Image1, ImageScaled1, Scale1, Shift1)
    append_channel (ImageScaled, ImageScaled1, ImageScaled)

    Scale2 := 1.0 / DeviationValues[1]
    Shift2 := - Scale1 * MeanValues[1]
    scale_image (Image2, ImageScaled2, Scale2, Shift2)
    append_channel (ImageScaled, ImageScaled2, ImageScaled)

    Scale3 := 1.0 / DeviationValues[2]
    Shift3 := - Scale3 * MeanValues[2]
    scale_image (Image3, ImageScaled3, Scale3, Shift3)
    append_channel (ImageScaled, ImageScaled3, ImageScaled)

    gen_empty_obj (ImagesScaled)
    concat_obj (ImagesScaled, ImageScaled, ImagesScaled)

    set_dict_object (ImagesScaled, sample_info, 'image')

    train_samples :=[train_samples, sample_info]
    endfor


    return ()
  2. 训练参数

    需要配置训练时的部分参数,主要包括提前停止阈值、数据使用率、训练轮数、正则项水平等

    1
    2
    3
    4
    TrainParamAnomaly := dict{error_threshold: 0.001}
    TrainParamAnomaly.MaxNumEpochs := 30
    TrainParamAnomaly.domain_ratio := 0.25
    TrainParamAnomaly.regularization_noise := 0.01
  3. 初始化模型

    模型初始化,使用 Halcon 的模型加载算子加载预训练的异常检测模型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ImageWidth := 256
    ImageHeight := 256

    Complexity := 15
    query_available_dl_devices (['runtime', 'id'], ['gpu', 0], DLDevice)

    read_dl_model ('initial_dl_anomaly_medium.hdl', DLModelHandle)
    set_dl_model_param (DLModelHandle, 'image_width', ImageWidth)
    set_dl_model_param (DLModelHandle, 'image_height', ImageHeight)
    set_dl_model_param (DLModelHandle, 'complexity', Complexity)
    set_dl_model_param (DLModelHandle, 'device', DLDevice)
  4. 训练模型

    将上述数据用训练算子一起训练

    1
    train_dl_model_anomaly_dataset (DLModelHandle, train_samples, TrainParamAnomaly, DLTrainResult)
  5. 模型保存

    保存训练完成的模型

    1
    2
    model_file_name := result_home_dir + '/model.hdl'
    write_dl_model (DLModelHandle, model_file_name)
  6. 模型推断

    加载测试数据,与训练好的模型一起送入推断算子

    1
    apply_dl_model (DLModelHandle, test_dataset, [], DLResultBatch)

参考资料



文章链接:
https://www.zywvvd.com/notes/coding/halcon/halcon-anomaly-det/halcon-anomaly-det/


“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”

微信二维码

微信支付

支付宝二维码

支付宝支付

Halcon 进行基于深度学习的异常检测
https://www.zywvvd.com/notes/coding/halcon/halcon-anomaly-det/halcon-anomaly-det/
作者
Yiwei Zhang
发布于
2024年1月10日
许可协议