引言
機器視覺中缺陷檢測分為一下幾種:
- 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)