halcon——缺陷檢測常用方法總結(模板匹配(定位)+差分)


引言

機器視覺中缺陷檢測分為一下幾種:

本篇主要總結一下缺陷檢測中的定位+差分的方法。即用形狀匹配,局部變形匹配去定位然后用差異模型去檢測缺陷。


 模板匹配(定位)+差分

💚整體思路(形狀匹配):

  1. 先定位模板區域后,求得模板區域的坐標,創建物品的形狀模板create_shape_model,注意把模板的旋轉角度改為rad(0)和rad(360)。
  2. 匹配模板find_shape_model時,由於物品的缺陷使形狀有局部的改變,所以要把MinScore設置小一點,否則匹配不到模板。並求得匹配項的坐標。
  3. 關鍵的一步,將模板區域仿射變換到匹配成功的區域。由於差集運算是在相同的區域內作用的,所以必須把模板區域轉換到匹配項的區域。
  4. 之后求差集,根據差集部分的面積判斷該物品是否有缺陷。

模板匹配(定位)+差分的方法主要用來檢測物品損壞,凸起,破洞,缺失,以及質量檢測等。

🤎halcon例程分析:


 1,印刷質量缺陷檢測(print_check.hdev)


 該例程用到了差異模型,將一個或多個圖像同一個理想圖像做對比,去找到明顯的不同。進而鑒定出有缺陷的物體。差異模型的優勢是可以直接通過它們的灰度值做比較,並且通過差異圖像,比較可以被空間地加權。

變化模型檢測缺陷的整體思路:

  1. create_variation_model —— 創建一個差異模型
  2. get_variation_model —— 獲得差異模型
  3. train_variation_model —— 訓練差異模型
  4. prepare_variation_model —— 准備差異模型
  5. compare_variation_model —— 比較模型與實例
  6. clear_variation_model —— 清除差異模型
dev_update_off ()
* 選擇第1張圖像創建形狀模板
read_image (Image, 'pen/pen-01')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_color ('red')
dev_display (Image)
* 把我感興趣的區域摳出來,原則上范圍越小越好,因為這樣創建模板時干擾會少很多
threshold (Image, Region, 100, 255)
fill_up (Region, RegionFillUp)
difference (RegionFillUp, Region, RegionDifference)
shape_trans (RegionDifference, RegionTrans, 'convex')
dilation_circle (RegionTrans, RegionDilation, 8.5)
reduce_domain (Image, RegionDilation, ImageReduced)
inspect_shape_model (ImageReduced, ModelImages, ModelRegions, 1, 20)
gen_contours_skeleton_xld (ModelRegions, Model, 1, 'filter')
* 獲得摳圖區域的中心,這是參考點
area_center (RegionDilation, Area, RowRef, ColumnRef)
* 創建形狀模板
create_shape_model (ImageReduced, 5, rad(-10), rad(20), 'auto', 'none', 'use_polarity', 20, 10, ShapeModelID)* 創建變化模型(用於和缺陷比較)
create_variation_model (Width, Height, 'byte', 'standard', VariationModelID)
* 文件夾中前15張圖片是質量良好的,可以用來訓練模板
for I := 1 to 15 by 1
    read_image (Image, 'pen/pen-' + I$'02d')
     * 先尋找模板的實例
    find_shape_model (Image, ShapeModelID, rad(-10), rad(20), 0.5, 1, 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
    if (|Score| == 1)
        * 使用仿射變換,將當前圖像平移旋轉到與模板圖像重合,注意是當前圖像轉向模板圖像
        vector_angle_to_rigid (Row, Column, Angle, RowRef, ColumnRef, 0, HomMat2D)
        affine_trans_image (Image, ImageTrans, HomMat2D, 'constant', 'false')
         * 訓練差異模型
        train_variation_model (ImageTrans, VariationModelID)
        dev_display (ImageTrans)
        dev_display (Model)
    endif
endfor
* 獲得差異模型
get_variation_model (MeanImage, VarImage, VariationModelID)
* 做檢測之前可以先用下面這個算子對可變模型進行設參,這是一個經驗值,需要調試者調整
prepare_variation_model (VariationModelID, 20, 3)
dev_set_draw ('margin')
NumImages := 30
* 可變模板訓練完成后,我們終於可以進入主題,馬上對所有圖像進行缺陷檢測,思想就是差分
for I := 1 to 30 by 1
    read_image (Image, 'pen/pen-' + I$'02d')
    * 要注意做差分的兩幅圖像分辨率相同,當然也需要通過仿射變換把待檢測的圖像轉到與模板圖像重合
       * 先尋找模板的實例
    find_shape_model (Image, ShapeModelID, rad(-10), rad(20), 0.5, 1, 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
    if (|Score| == 1)
         * 使用仿射變換,將當前圖像平移旋轉到與模板圖像重合,注意是當前圖像轉向模板圖像
        vector_angle_to_rigid (Row, Column, Angle, RowRef, ColumnRef, 0, HomMat2D)
        affine_trans_image (Image, ImageTrans, HomMat2D, 'constant', 'false')
        * 摳圖
        reduce_domain (ImageTrans, RegionDilation, ImageReduced)
        * 差分 (就是檢查兩幅圖像相減,剩下的區域就是不同的地方了,與模板圖像不同的地方就是缺陷)
       * 這里可不能用difference做差分啊,halcon為變形模板提供了專門的差分算子:compare_variation_model
        compare_variation_model (ImageReduced, RegionDiff, VariationModelID)
        connection (RegionDiff, ConnectedRegions)
        * 特征選擇:用一些特征來判斷這幅圖像印刷是否有缺陷,這里使用面積
       * 其實可以考慮利用區域面積的大小來判斷缺陷的嚴重程度,這里就不過多討論了
        select_shape (ConnectedRegions, RegionsError, 'area', 'and', 20, 1000000)
        count_obj (RegionsError, NumError)
        dev_clear_window ()
        dev_display (ImageTrans)
        dev_set_color ('red')
        dev_display (RegionsError)
        set_tposition (WindowHandle, 20, 20)
        if (NumError == 0)
            dev_set_color ('green')
            write_string (WindowHandle, 'Clip OK')
        else
            dev_set_color ('red')
            write_string (WindowHandle, 'Clip not OK')
        endif
    endif
    if (I < NumImages)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor
* 結語:如果發現前面作為訓練變形模板的良好圖像也被判定為NG,
*      可以調整prepare_variation_model參數
*      或者調整select_shape特征篩選的標准

 相關算子分析:

  • create_variation_model(創建一個差異模型)
create_variation_model(Width, Height, Type, Mode ,ModelID)
//創建一個ID為ModelID,寬為Width,高為Height,類型為Type的差異模型參數

參數Mode決定了創建標准圖像和相應的變化圖像的方法。(可選三種方法)

  1. 'standard'表示標准的訓練方法,標准圖像的位置是各訓練圖像位置的平均,
  2. 'robust'表示魯棒的訓練方法,標准圖像的位置是各訓練圖像的中值,此模式在訓練圖像中可能存在ERROR時使用,
  3. 'direct'表示標准圖像由單張圖像經過處理得到,由此方法得到的標准圖像只能應用prepare_direct_variation_model算子得到variation model。
  • get_variation_model(獲得差異模型)
get_variation_model(Image, VarImage ,ModelID  )
//返回差異模型中的標准圖像(Image)和差異圖像(VarImage),此算子主要用來檢視創建的差異模型是否OK。
  • train_variation_model(訓練差異模型)
train_variation_model(Images, ModelID )
  • prepare_variation_model(准備差異模型)
prepare_variation_model( : : ModelID, AbsThreshold, VarThreshold : )
//設置variation model(差異模型)的絕對閾值和相對閾值。
  //絕對閾值即待檢測圖像與標准圖像的差值,
  //相對閾值即待檢測圖像與variation model與VarThreshold乘積的差值。
  • compare_variation_model(比較模型與實例)
compare_variation_model(Image : Region : ModelID : )
//待檢測圖像與variation model進行比較,超過閾值的區域在Rgion參數中返回。
同threshold一樣,返回的區域被看做一個區域,可以使用connection算子進行連通性分析,然后根據區域的特征(如面積)對區域進行選擇。

總結:

差異模型(Variation Model)使用標准圖像與待檢測圖像灰度值相比較,來判斷產品是否OK,適用於印刷品檢測及產品表面檢測

從實際算法過程可以看出,此檢測實際可分為兩部分:

  • 對於圖像中的大面積灰度一致區域,主要利用待檢測圖像與標准圖像(ideal image)比較得出差異區域,
  • 對於圖像中的邊緣位置(edges)區域,主要利用待檢測圖像與Variation圖像(variation image)比較得出差異區域。

所以在實際應用中,應根據實際情況設置AbsThreshold和VarThreshold的值。


  2,檢測工件孔洞毛刺缺陷 - 局部變形匹配(inspect_gasket_local_deformable.hdev)


 在日常工程應用中,我們通常通過halcon的形狀匹配(shape-based matching)進行各種定位,正如上篇例程,當待匹配物體有輕微變形時,並不影響得到的匹配結果,然后當待匹配物體有較大變形時,如塑料產品在成形時變形、紡織產品的花紋因為褶皺變形等,要想得到精確的定位結果就顯得捉襟見肘,如下圖所示,工件如果有較大變形,在用形狀匹配時,定位結果就不盡如人意,因為形狀匹配本身得到的匹配結果只是一個點(row,col)。

因此本篇例程使用了局部變形匹配(local deformable matching),匹配結果可以根據待匹配物體自動進行變形。而且在這個案例中,create_variation_model (Width, Height, ‘byte’, ‘direct’, VariationModelID) 使用的方法是’direct’,因此是不需要訓練差異模型而可以直接使用的。

1️⃣讀入標准圖像,創建差異模型以及匹配模板

*1.讀入圖像
dev_update_off ()
dev_get_window (WindowHandle)
set_display_font (WindowHandle, 36, 'mono', 'true', 'false')
dev_set_draw ('margin')

read_image (ModelImage, 'gasket/gasket_model')
get_image_size (ModelImage, Width, Height)
read_image (Image, 'gasket/gasket_01')
*2.創建差異模型
create_variation_model (Width, Height, 'byte', 'direct', VariationModelID)
sobel_amp (ModelImage, EdgeAmplitude, 'sum_abs', 3)
*3.直接設參數+標准圖像+邊緣幅度圖像
prepare_direct_variation_model (ModelImage, EdgeAmplitude, VariationModelID, 20, 2)
*4.創建局部變形匹配模板
create_local_deformable_model (ModelImage, 'auto', [], [], 'auto', 0.9, [], 'auto', 0.9, [], 'auto', 'none', 'use_polarity', 'auto', 'auto', [], [], ModelID)
get_deformable_model_contours (ModelContours, ModelID, 1)
area_center (ModelImage, Area, Row, Column)

標准圖像:

 

這里由於是用單幅圖像創建的差異模型,因此參數Mode設置的’direct’,故不需要再去訓練,而是直接使用prepare_direct_variation_model (ModelImage, EdgeAmplitude, VariationModelID, 20, 2)得到差異模型。

2️⃣通過匹配模板將待檢測工件定位矯正

for Index := 1 to 7 by 1
     read_image (Image, 'gasket/gasket_' + Index$'02')
    get_image_size (Image, Width1, Height1)
    *5.查找
    find_local_deformable_model (Image, ImageRectified, VectorField, DeformedContours, ModelID, rad(-10), rad(20), 1, 1, 1, 1, 0.93, 1, 0.7, 0, 0.4, ['image_rectified','vector_field','deformed_contours'], ['deformation_smoothness','expand_border','subpixel'], [25,0,1], Score, Row, Column)
    if (|Score| > 0)
        gen_warped_mesh_region (VectorField, MeshRegion, 25)
        gen_region_contour_xld (DeformedContours, EdgeRegion, 'margin')
        dilation_circle (EdgeRegion, RegionDilation, 2 * 25)
        intersection (RegionDilation, MeshRegion, RegionIntersection)
        dev_set_line_width (1)
        dev_set_color ('yellow')
        dev_display (Image)
        dev_display (RegionIntersection)
        Found[Index] := |Score|
        dev_set_line_width (2)
        dev_set_color ('green')
        dev_display (DeformedContours)
        * 7.注意:這里顯示的是修正過的圖像  
         dev_display (ImageRectified)
       endif

 待檢測圖像:

局部變形匹配定位:                                                                        矯正:

由於局部變形模板匹配在尋找到圖像(find_local_deformable_model)后是自動矯正的,因此我們可以省掉仿射變換的步驟了。

3️⃣通過差異模型差分得到缺陷工件

    *6.差分
    compare_variation_model (ImageRectified, Region, VariationModelID)
    connection (Region, ConnectedRegions)
*缺陷提取(特征選擇,即面積大於60的定義為缺陷) select_shape (ConnectedRegions, SelectedRegions,
'area', 'and', 60, 99999) count_obj (SelectedRegions, Number) *顯示 if(Number>0) disp_message (WindowHandle, 'NG', 'image', 12, 12, 'red', 'false') else disp_message (WindowHandle, 'OK', 'window', 12, 12, 'magenta', 'false') endif dev_set_color ('red') dev_display (SelectedRegions) stop() endfor dev_update_on ()

 

 相關算子分析:

  •  create_local_deformable_model(創建局部變形匹配模板)
create_local_deformable_model(Template , NumLevels, AngleStart, AngleExtent, AngleStep, ScaleRMin, ScaleRMax, ScaleRStep, ScaleCMin,ScaleCMax, ScaleCStep, Optimization, Metric, Contrast, MinContrast, ParamName, ParamValue ,ModelID)

參數列表:
Template  //輸入多通道圖像,用來創建model
NumLevels //金字塔層數:'auto', 0,1,2,3,。。。
AngleStart //輸入起始角度(默認-0.39)
AngleExtent//角度旋轉的范圍(默認0.79)
AngleStep //旋轉的步長,即分辨率,默認’auto'
ScaleRMin//行方向的最小縮放比例,默認1.0,通常大於0小於1
ScaleRMax//行方向的最大縮放比例,默認1.0,通常大於1小於1.5
ScaleRStep//行方向的縮放步長,可影響行方向的分辨率,默認'auto', 0.01,0.02,0.05,。。
ScaleCMin//
ScaleCMax//          列方向,同上
ScaleCStep//
Optimization//生成模型時的優化方式,默認'none'可選,'auto','point_reduction_XXX'
Metric//比較時候的標准,默認'use_polarity'使用極坐標系進行比較
Contrast//在模板圖片的濾波或者磁滯濾波中,控制結果的對比度,默認'auto', 10, 20....
MinContrast//在搜尋對象過程中的最小對比度,默認'auto', 1, 2, 3, 5....
ParamName// 普通參數名字(不太清楚用途,后續研究)默認[], 'min_size','part_size'
ParamValue//參數值, 默認[], 可選'small', 'medium', big'
ModelID// 輸出的模型handle

 變形檢測用來檢測一個對象是否局部變形,這個檢測模型在保持嚴格的基礎上允許一些細小的變形,和find_shape_model(在圖中找到相應圖形的最佳匹配)不同,create_local_deformable_model更加智能化,它可以預估變形程度並且修正圖像中物體的位置(物體相對於圖像的相對位置),它可以處理更大的變形。

  • get_deformable_model_contours(得到局部變形模板的輪廓)
get_deformable_model_contours( ModelContours , ModelID, Level )
//Level決定了返回第幾層金字塔圖像的邊緣
  • find_local_deformable_model (在待匹配圖像中尋找變形模板)
find_local_deformable_model(Image ,ImageRectified, VectorField, DeformedContours : ModelID, AngleStart, AngleExtent, ScaleRMin, ScaleRMax, ScaleCMin, ScaleCMax, MinScore, NumMatches, MaxOverlap, NumLevels, Greediness, ResultType, ParamName, ParamValue : Score, Row, Column)

參數列表:
Image
//輸入待匹配圖像 ImageRectified //輸出匹配到的變形矯正后模板圖像 VectorField//變形矢量區 DeformedContours //匹配到的輪廓,不是矯正后的輪廓 ModelID//模型句柄 AngleStart//起始角度 AngleExtent//角度范圍 ScaleRMin//行縮放最小比例 ScaleRMax//行縮放最大比例 ScaleCMin// ScaleCMax//列同上 MinScore//最小相似度 NumMatches//需要幾個最佳匹配結果 MaxOverlap//最大重疊數 NumLevels//金字塔層數 Greediness//貪婪度(范圍0-1,0表示精確緩慢,1表示迅速精度不高) ResultType//輸出的結果類型([], 'deformed_contours', 'image_rectified', 'vector_field') ParamName//參數名稱 Score//輸出匹配度 Row, Column//輸出行列坐標

 這個函數的功能是在一張圖片中找到變形模型中的最佳匹配結果(可以是多個,由NumMatches輸入),模型必須在之前的步驟中使用(create_local_deformable_model或者read_deformable_model)生成。這個函數會返回找到的結果的行,列坐標(Row, Column)作為輸出。

另外函數在找到匹配的模型后,輸出矯正后的圖像(ImageRectified),向量區域(VectorField)和匹配到的輪廓(DeformedContours) 通過參數ResultType去選擇需要返回哪個(默認[],都不返回)。

ParamName可以調整參數的設置:(比如)
  1. deformation_smoothness:平滑的度,對於變形越大參數越大
  2. expand_border:擴大ImageRecfified VectorField 區域
  • gen_warped_mesh(生成變形網格,封裝函數)
gen_warped_mesh (VectorField, WarpedMesh, 10)
VectorField
// 輸入向量區域 WarpedMesh//輸出變形網格 10 //代表此函數隔10個像素取值

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM