引言
機器視覺中缺陷檢測分為一下幾種:
- blob分析+特征
- 模闆比對(定位)+差分:halcon——缺陷檢測常用方法總結(模闆比對(定位)+差分) - 唯有自己強大 - 部落格園 (cnblogs.com)
- 光度立體:halcon——缺陷檢測常用方法總結(光度立體) - 唯有自己強大 - 部落格園 (cnblogs.com)
- 特征訓練
- 測量拟合:halcon——缺陷檢測常用方法總結(測量拟合) - 唯有自己強大 - 部落格園 (cnblogs.com)
- 頻域+空間域結合:halcon——缺陷檢測常用方法總結(頻域空間域結合) - 唯有自己強大 - 部落格園 (cnblogs.com)
- 深度學習
本篇博文主要是對缺陷圖像的紋理特征訓練進行詳細分析。
特征訓練
在紋理中找瑕疵。基于高斯混合模型(GMM)分類器的紋理檢查模型,适用于圖像金字塔,可以分析紋理的多個頻率範圍。
要求:訓練樣本必須完美無瑕疵。
整體步驟:
- 建立模型create_texture_inspection_model或讀取模型read_texture_inspection_model
- 添加訓練樣本add_texture_inspection_model_image
- 檢視樣本get_texture_inspection_model_image
- 訓練模型train_texture_inspection_model
每層金字塔都會訓練一個GMM模型,并确定該層的\'novelty_threshold\'(區分有無瑕疵的門檻值)。
參數擷取:get_texture_inspection_model_param
參數設定:set_texture_inspection_model_param
參數分析:\'patch_normalization\':\'weber\'對亮度魯棒,‘none’需要亮度作為評判(預設)
\'patch_rotational_robustness\':\'true\'對旋轉魯棒,\'false\'需要旋轉作為評判(預設)
\'levels\':設定具體的金字塔層參與訓練,紋理越粗糙,則較低的金字塔層級越可省略。預設auto。
\'sensitivity\':靈敏度,影響\'novelty_threshold\'的計算結果。負值會導緻更高的門檻值,進而更少的發現缺陷。預設0。
\'novelty_threshold\',門檻值,自動計算得到,若結果不理想,可以手動微調。
- 進行檢測apply_texture_inspection_model
-
模型儲存與釋放write_texture_inspection_model
若模型不再需要,則釋放clear_texture_inspection_model
halcon案例分析(apply_texture_inspection_model.hdev)
一,建立模型,添加訓練樣本(完好無損的圖像)
TrainingImageIndices := [1,2]
TextureModelFilename := \'texture_model_carpet\'
dev_open_window_fit_size (0, 0, Width, Height, -1, -1, WindowHandle1)
dev_display (Image)
*建立模型
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)
endfor

二,初步設定參數後,開始訓練
*參數設定\'patch_normalization\':\'weber\'對亮度魯棒,‘none’需要亮度作為評判(預設)
set_texture_inspection_model_param (TextureInspectionModel, \'patch_normalization\', \'weber\')
Levels := [2,3,4]
* \'levels\':設定具體的金字塔層參與訓練,紋理越粗糙,則較低的金字塔層級越可省略。預設auto。
set_texture_inspection_model_param (TextureInspectionModel, \'levels\', Levels)
* 開始訓練
train_texture_inspection_model (TextureInspectionModel)
*檢視樣本參數\'novelty_threshold\',門檻值,自動計算得到,若結果不理想,可以手動微調。
get_texture_inspection_model_param (TextureInspectionModel, \'novelty_threshold\', NoveltyThreshold)
* 檢視各個金字塔等級的新穎性得分圖像和新穎性區域,可以把\'gen_result_handle\'設定為\'true\',
*之後get_texture_inspection_result_object讀取\'novelty_score_image\'和\'novelty_region\'。
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)
* 檢查調試資訊。
*檢視各個金字塔等級的新穎性得分圖像(NovScoreImage)和新穎性區域(NovRegionL)
* 新穎性評分圖像可用于單獨微調新穎性門檻值。
get_texture_inspection_result_object (NovScoreImage, TextureInspectionResultID, \'novelty_score_image\')
get_texture_inspection_result_object (NovRegion, TextureInspectionResultID, \'novelty_region\')
* 顯示每層(金字塔)的結果
count_obj (NovScoreImage, Number)
for Level := 1 to Number by 1
CurrentWindow := WindowHandles[Level - 1]
dev_set_window (CurrentWindow)
dev_clear_window ()
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_set_line_width (2)
*
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\'])
endfor
*顯示結果
dev_set_window (WindowHandle4)
dev_display (TestImage)
dev_set_line_width (2)
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] := \'圖像中有很多小錯誤.\'
Message[1] := \'可以通過改變 novelty thresholds的值來調整靈敏度(sensitivity—)\'
Message[2] := \'例如減少靈敏度參數的值\'
dev_disp_text (Message, \'window\', 12, 12, \'black\', [], [])
* 設定門檻值計算的靈敏度。 負值導緻更高的門檻值,是以檢測到的缺陷更少。
* \'sensitivity\':靈敏度,影響\'novelty_threshold\'的計算結果。負值會導緻更高的門檻值,進而更少的發現缺陷。預設0。
set_texture_inspection_model_param (TextureInspectionModel, \'sensitivity\', -10)
get_texture_inspection_model_param (TextureInspectionModel, \'novelty_threshold\', NoveltyThreshold)
endif
if (Index == 2)
Message := \'也可以通過直接操縱新穎性邊界來單獨調整單個級别的敏感度\'
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
endfor
for Level := 1 to |WindowHandles| by 1
dev_set_window (WindowHandles[Level - 1])
dev_clear_window ()
endfor
dev_set_window (WindowHandle4)
dev_clear_window ()
五,至此,模型準備完畢,将全部圖像進行缺陷檢測并顯示
*檢測所有測試圖像上的紋理缺陷。
NumImages := 7
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\')
* 顯示單個金字塔層數的結果
count_obj (NovScoreImage, Number)
for Level := 1 to Number by 1
CurrentWindow := WindowHandles[Level - 1]
dev_set_window (CurrentWindow)
dev_clear_window ()
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_set_line_width (2)
*
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\'])
endfor
* 顯示結果
dev_set_window (WindowHandle4)
dev_display (TestImage)
dev_set_line_width (2)
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
【術語解釋】
- Patch:相鄰像素的集合。
- Novelty Score:在測試過程中,将測試圖像的紋理特征與紋理檢查模型進行比較,并計算它們的\'novelty score\'。 該值越大,單個紋理特征越不适合紋理檢查模型的可能性越大。
- Novelty Threshold:Novelty Score高于該門檻值,則紋理有缺陷。
-
“ novelty_region”是通過組合不同金字塔等級的新穎性區域而生成的,即不同層級金字塔組成的交集區域。如果隻有單層金字塔,那麼該層的新穎性區域直接就是novelty_region。
若想檢視各個金字塔等級的新穎性得分圖像和新穎性區域,可以把\'gen_result_handle\'設定為\'true\',之後get_texture_inspection_result_object讀取\'novelty_score_image\'和\'novelty_region\'。
參考博文:Halcon 紋理缺陷檢測 apply_texture_inspection_model - 夕西行 - 部落格園 (cnblogs.com)