halcon學習之產品檢測

 Rinspect_gasket_local_deformable.hdev
 
檢測墊圈局部變形
 
*這個例子演示瞭如何利用局部變形匹配(local deformable matching)來尋找出墊圈是否變形
 
dev_update_off()
 
Smoothness:=25
 
read_image(ModelImage,..
 
read_image( Image,......
 
下面是ModelImage和Image(兩個基本相近,肉眼難辨)
 
 
顯示信息不予贅述。。。
 
一:建立variation model (差別模型)
 
sobel_amp(ModelImage, EdgeAmplitude, 'thin_max_abs', 5)
 
*/        'thin_sum_abs' (thin(|a|) + thin(|b|)) / 4來求得幅值大小, 其中a,b是sobel卷積以後所求單一像素的輸出值(橫向,縱向)/*
 
1 , create_variation_model( 425,410,'byte', 'direct', VariationModelId)
 
create_variation_model( : :  WidthHeightTypeMode :  ModelID)
 
建立一個差別比較的模型
 
描述:這個函數建立一個用於圖像比較的handle, variation model是典型的從不合格產品中分辨出合格產品的應用模型(根據灰度圖比較)。
 
差別模型(VariationModel)包含兩部分,第一部分是理想的標準圖(用於以後的比較,compare_variation_model或者compare_ext_variation_model),第二部分是一張圖片,它包含了訓練圖中各張之間或者平均的差別信息。
 
/*差別模型(VM)使用多張標準圖來進行訓練,它的本質須要這些訓練用的圖片可以在同一個位置合同一個角度,當沒法保證同位置同角度的時候,可使用find_shape_model匹配來使圖片轉換到正確位置(利用affine_trans_image)*/
 
這裏的type指的是對比的圖像類型,Mode參數決定了如何訓練標準圖以及如何進行側視圖和標準圖之間的差別匹配,Mode:
 
' standard' :標準圖由訓練圖的平均值來獲得(通過矯正位置以後的訓練圖),差別值的計算是標準圖與測試圖的標準差  (這種方法的優點是能夠經過迭代來訓練標準圖,直接使用train_variation_model進行訓練,缺點是必須花費很大代價來確認訓練圖的正確性,保證準確率)
 
' robust' : 標準圖由多張訓練圖的中值來計算,差別值的計算是由訓練圖通過正確縮放後與測試圖進行比較獲得的一組數值得中值(這種模式對偏差的容忍度搞,不過不能夠迭代訓練,必須經過concat_obj 和train_variation_model來訓練)
 
2, prepare_direct_variation_model(ModelImage, EdgeAmplitude, VariationModelID, 30, 1.5)
 
prepare_direct_variation_model( RefImageVarImage : :  ModelIDAbsThresholdVarThreshold : )
 
對進行的比較作準備,使用這個函數,前面的建立差別模型時候的mode必須是’direct'。direct在這裏相對於prepare_variation_model的差異是,標準圖和相應的差別圖並非使用train_variation_model計算出來的,而是直接在RefImage和VarImage中指出來,做爲函數輸入。此函數很是適合標準圖只有一張,即沒有多張訓練圖的狀況。這種狀況下,差別圖variation image應該由邊緣函數'sobel_amp, edges_image, gray_range_rect' 等生成。(variation image指的是an image that represents the amount of gray value variation at every point of the object)
 
二:建立本地可變性模型
 
1, create_local_deformable_model(ModelImage, 'auto', rad(-10), rad(20),'auto',0.9,1.1, 'auto', 'none', 'use_polarity', 'auto', 'auto', [],[],ModelID)
 
create_local_deformable_model( Template : :  NumLevelsAngleStartAngleExtentAngleStepScaleRMinScaleRMaxScaleRStepScaleCMin, ScaleCMaxScaleCStepOptimizationMetricContrastMinContrastParamNameParamValue :  ModelID)
 
描述:
 
這個操做把模板Template作準備工做用來後續的局部變形檢測,變形模型的ROI做爲此模板的roi
 
變形檢測用來檢測一個對象是否局部變形,這個檢測模型在保持嚴格的基礎上容許一些細小的變形,
 
和find_shape_model(在圖中找到相應圖形的最佳匹配)不一樣,create_local_deformable_model更加智能化,它能夠預估變形程度而且修正圖像中物體的位置
 
(物體相對於圖像的相對位置),它能夠處理更大的變形。
 
模型中,參照點(reference point)是由標準圖中對象的重力中心點位置決定的,而且使用物體模板的axis-aligned cnclosing rectangle(我的理解就是一個矩形的長短軸相關)來決定搜索區域(使用find_local_deformable_model)
 
參數介紹:
 
Template:輸入多通道圖像,用來建立model
 
NumLevels:輸入integer,用來控制最多有多少層金字塔層數:'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
 
3, get_deformable_model_contours( ModelContours, ModelID,1)
 
get_deformable_model_contours( :  ModelContours :  ModelIDLevel : )
 
獲取可變模型的邊緣, Level決定了返回第幾層金字塔圖像的邊緣
 
area_center( ModelImage, Area, Row, Column)
 
hom_mat2d_identity(HomMat2DIdentity)
 
建立一個單位矩陣,即對角線爲1,其餘爲0,注意:產生的矩陣以tuple形式存在,且最後一行不顯示
 
*                     / 1 0 0 \
 
*  HomMat2DIdentity = | 0 1 0 |
 
*                     \ 0 0 1 /
 
齊次座標(Homogenous Coordinate)
 
以點p(x,y)爲例,若是想把它平移(a,b),至p’(x+a,y+b),是丌可能用矩陣計算完成的,
 
如今換成齊次座標(x,y,1),經過矩陣相乘(左側公式) ,很方便獲得平移後的座標(x+a,y+b)。
 
爲了保持一致把矩陣改爲 右側矩陣,這就是齊次變換矩陣。
 
 
hom_mat2d_translate(HomMat2DIdentity, Row, Colum, HomMat2DTranslate)
 
hom_mat2d_translate( : :  HomMat2DTxTy :  HomMat2DTranslate)
 
對上面建立的單位矩陣進行轉換,公式爲:
 
/ 1 0 Tx \
 
HomMat2DTranslate = | 0 1 Ty | * HomMat2D
 
\ 0 0 1 /
 
注意,這個轉換矩陣使用的右手規則,也就是說x軸對應的是行,y軸對應的是列
 
轉換的意義是:
 
定位中心點,在後面的轉換中,對結果矩陣進行行和列的定位。
 
這裏生成的矩陣主要用於後面對對象圖像的旋轉,位移等等轉換
 
 
(ModelContours樣子)
 
affine_trans_contour_xld(ModelContours, ContoursAffinTrans, HomMat2DTranslate)
 
affine_trans_contour_xld( Contours :  ContoursAffinTrans :  HomMat2D : )
 
對模型的邊緣進行一次任意仿射矩陣轉換(旋轉,位移,輕微扭轉等等,這裏使用的是identity,因此沒有變化)
 
********************************************************
 
下面對圖像進行迭代的處理
 
********************************************************
 
下面對圖像進行迭代的處理
 
NumImages: = 7
 
for Index :=1 to NumImages by 1
 
read_image(Image, 'gasket/gasket_'+Index$'02')
 
dev....顯示。。。
 
*接下來,在測試圖中找到測試的model。 找到修改圖,各自的向量區域和需求的邊界
 
*query the rectified image, the respective vector field and the found contours
 
count_seconds(S1)
 
重點:
 
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'],[Smoothness, 0, 1], Score, Row, Column)
 
find_local_deformable_model( Image :  ImageRectifiedVectorFieldDeformedContours :  ModelIDAngleStartAngleExtentScaleRMinScaleRMaxScaleCMinScaleCMaxMinScoreNumMatchesMaxOverlapNumLevelsGreedinessResultTypeParamNameParamValue :  ScoreRowColumn)
 
 
(find_local_deformable_model的結果)
 
這個函數的功能是在一張圖片中找到local deformable model(ModelID) 的最佳匹配結果(能夠是多個,由NumMatches輸入),
 
模型必須在以前的步驟中使用(create_local_deformable_model或者read_deformable_model)生成。這個函數會返回找到的結果的行,列座標做爲輸出。
 
另外,圖片被修改的部分(ImageRectified),他們分別得向量區域(VectorField)和找到的模型的邊界(DeformedContours)均可以被返回做爲結果。
 
默認狀況下,這些不被返回。爲了應對須要上述一個或者所有對象的狀況,參數ResultType應該被設置爲'image_rectified','vector_field', 'deformed_contours'.
 
其中,ImageRectified和VectorField的大小根據建立local_deformable模型時候的最小圖片來決定(模型大小),可是他們的大小也能夠經過設置
 
ParamName(設定爲expand_border)和ParamValue  (改變number of pixels)來改變。
 
 
(ImageRectified)
 
 
(VectorField)
 
 
(DeformedContours)
 
同時,用戶能夠選擇性的對一個特定方向指定爲結果區域的方向(使用expand_border_top,或者,bottom,left, right),
 
注意VectorField是絕對座標,能夠用來作convert_map_type。
 
ParamName也能夠設定爲'deformation_smoothness'來控制對象的平滑程度。
 
Score是一個0到1之間的值,來表示一個模型存在一張圖片中的程度。例子 三個符合[0.947296, 0.939897, 0.92051]
 
Greediness表示搜索的貪婪性(0-1),0表示徹底準確,可是速度慢,當貪婪爲1時候,速度增快可是可能會錯過一些對象
 
ResultType能夠選擇[], 'image_retified', 'vector_field', 'deformed_contours'
 
count_seconds(S2)
 
Time :=S2-S1
 
if( |Score|>0)      *找到的結果數
 
gen_warped_mesh_region( VectorField, MeshRegion, Smothness)
 
gen_warped_mesh_region( VectorField :  WarpedMesh :  Step : )
 
*********************************gen_warped_mesh***********************************************************
 
 
* Generate a grid of the deformation from the VectorField
 
* The step width is given by the parameter Step.
 
*
 
gen_empty_obj (WarpedMesh)
 
count_obj (VectorField, Number)
 
for Index := 1 to Number by 1
 
select_obj (VectorField, ObjectSelected, Index)
 
vector_field_to_real (ObjectSelected, DRow, DColumn)
 
 
(DRow)
 
 
(DColumn)
 
get_image_size (VectorField, Width, Height)
 
 
* Horizontal lines
 
for ContR := 0.5 to Height[0]-1 by Step
 
tuple_gen_sequence (0.5, Width[0]-1, 1, Column)
 
Height=170時Column數據 [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5, 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, 24.5, 25.5, 26.5, 27.5, 28.5, 29.5, 30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5, 70.5, 71.5, 72.5, 73.5, 74.5, 75.5, 76.5, 77.5, 78.5, 79.5, 80.5, 81.5, 82.5, 83.5, 84.5, 85.5, 86.5, 87.5, 88.5, 89.5, 90.5, 91.5, 92.5, 93.5, 94.5, 95.5, 96.5, 97.5, 98.5, 99.5, 100.5, 101.5, 102.5, 103.5, 104.5, 105.5, 106.5, 107.5, 108.5, 109.5, 110.5, 111.5, 112.5, 113.5, 114.5, 115.5, 116.5, 117.5, 118.5, 119.5, 120.5, 121.5, 122.5, 123.5, 124.5, 125.5, 126.5, 127.5, 128.5, 129.5, 130.5, 131.5, 132.5, 133.5, 134.5, 135.5, 136.5, 137.5, 138.5, 139.5, 140.5]
 
tuple_gen_const (Width[0]-1, ContR, Row)
 
get_grayval_interpolated (DRow, Row, Column, 'bilinear', GrayRow)
 
GrayRow數據
 
[164.767, 164.728, 164.688, 164.648, 164.608, 164.57, 164.537, 164.507, 164.483, 164.468, 164.456, 164.444, 164.432, 164.42, 164.426, 164.448, 164.47, 164.492, 164.52, 164.553, 164.587, 164.622, 164.657, 164.692, 164.731, 164.773, 164.811, 164.846, 164.878, 164.911, 164.95, 164.996, 165.046, 165.078, 165.094, 165.111, 165.128, 165.14, 165.147, 165.153, 165.159, 165.165, 165.171, 165.17, 165.163, 165.157, 165.146, 165.131, 165.111, 165.084, 165.051, 165.015, 164.978, 164.941, 164.904, 164.865, 164.826, 164.787, 164.749, 164.71, 164.671, 164.629, 164.577, 164.514, 164.435, 164.347, 164.259, 164.17, 164.082, 163.994, 163.906, 163.817, 163.729, 163.641, 163.553, 163.464, 163.376, 163.288, 163.2, 163.111, 163.026, 162.951, 162.888, 162.839, 162.801, 162.762, 162.723, 162.684, 162.646, 162.607, 162.568, 162.53, 162.494, 162.457, 162.421, 162.386, 162.355, 162.329, 162.305, 162.281, 162.26, 162.242, 162.226, 162.212, 162.201, 162.192, 162.184, 162.181, 162.183, 162.188, 162.196, 162.204, 162.213, 162.224, 162.236, 162.247, 162.257, 162.271, 162.287, 162.301, 162.313, 162.322, 162.331, 162.336, 162.34, 162.342, 162.34, 162.333, 162.322, 162.308, 162.293, 162.276, 162.256, 162.234, 162.211, 162.182, 162.149, 162.112, 162.075, 162.037, 161.999]
 
*Return gray values of an image at the positions given by tuples of rows and columns.
 
get_grayval_interpolated (DColumn, Row, Column, 'bilinear', GrayColumn)
 
gen_contour_polygon_xld (Contour, GrayRow, GrayColumn)
 
concat_obj (WarpedMesh, Contour, WarpedMesh)
 
endfor
 
 
此時結果
 
* Vertical lines
 
for ContC := 0.5 to Width[0]-1 by Step
 
tuple_gen_sequence (0.5, Height[0]-1, 1, Row)
 
tuple_gen_const (Height[0]-1, ContC, Column)
 
get_grayval_interpolated (DRow, Row, Column, 'bilinear', GrayRow)
 
get_grayval_interpolated (DColumn, Row, Column, 'bilinear', GrayColumn)
 
gen_contour_polygon_xld (Contour, GrayRow, GrayColumn)
 
concat_obj (WarpedMesh, Contour, WarpedMesh)
 
endfor
 
endfor
 
return ()
 
 
 
顯示變換結果
 
 
* This procedure displays the results of Shape-Based Matching.
 
*
 
NumMatches := |Row|
 
if (NumMatches>0)
 
if (|ScaleR|=1)
 
tuple_gen_const (NumMatches, ScaleR, ScaleR)
 
endif
 
if (|ScaleC|=1)
 
tuple_gen_const (NumMatches, ScaleC, ScaleC)
 
endif
 
if (|Model|=0)
 
tuple_gen_const (NumMatches, 0, Model)
 
elseif (|Model|=1)
 
tuple_gen_const (NumMatches, Model, Model)
 
endif
 
for Index := 0 to |ModelID|-1 by 1
 
get_shape_model_contours (ModelContours, ModelID[Index], 1)
 
dev_set_color (Color[Index%|Color|])
 
for Match := 0 to NumMatches-1 by 1
 
if (Index=Model[Match])
 
hom_mat2d_identity (HomMat2DIdentity)
 
hom_mat2d_scale (HomMat2DIdentity, ScaleR[Match], ScaleC[Match], 0, 0, HomMat2DScale)
 
hom_mat2d_rotate (HomMat2DScale, Angle[Match], 0, 0, HomMat2DRotate)
 
hom_mat2d_translate (HomMat2DRotate, Row[Match], Column[Match], HomMat2DTranslate)
 
affine_trans_contour_xld (ModelContours, ContoursAffinTrans, HomMat2DTranslate)
 
dev_display (ContoursAffinTrans)
 
endif
 
endfor
 
endfor
 
endif
 
return ()
 
********************************************************************************************
 
 
MeshRegion
 
gen_region_contour_xld(DeformedContours, EdgeRegion, 'margin')
 
dilation_circle( EdgeRegion, RegionDilation, 2*Smoothness)
 
intersection(RegionDilation, MeshRegion, RegionIntersection)
 
intersection(Region1, Region2 : RegionIntersection : : )
 
兩個region的交集
 
下面依次是DeformedContours, EdgeRegion, RegionDilation, RegionIntersection
 
 
 
 
 
dev 顯示。。。。。
 
compare_variation_model(ImageRectified, Region, VariationModelID)
 
compare_variation_model(Image : Region : ModelID : )
 
拿一張圖片和variation model作比較
 
描述:在比較值錢,variation model 的兩張內部閾值圖片必須被提早建立(使用prepare_variation_model 或者prepare_direct_variation_model)。
 
這裏用c(x,y)來表明輸入圖像Image, t{u,l}來表示兩張內部閾值圖片。
 
輸出region包括了全部的有本質差別的點的集合
 
c(x,y) > t{u}(x,y)   或者  c(x,y) < t{l}(x,y)
 
若是隻須要尋找過亮或者過暗的部分,能夠用compare_ext_variation_model
 
程序中出來的Region爲:
 
connection(Region, ConnectedRegions) select_shape(ConnectedRegions, SelectedRegions, 'area','and' , 30, 99999) count_obj(SelectedRegions, Number) if(Number>0) area_center(SelectedRegions, Area, Row1, Column1) elliptic_axis(SelectedRegions, Ra, Rb, Phi) tuple_gen_const(Number, 1,Ones) PointOder :=[] for Idx := 0 to Number-1 by 1 PointOrder :=[PointOrder, 'possitive'] endfor ????????????????疑問:這裏的Idx怎麼用? gen_ellipse_contour_xld(ContEllipse, Row, Column1, Phi, Ra+10, Rb+10, 0*Ones, 6.28318*Ones, PointOrder, 1.5) 後面是顯示工做, endif和endfor 清除:clear_deformable_model(ModelID) clear_variation_model(VariationModelID) 總結部分,會列出處理的主要過程和每一個過程的主要輸入,輸出,用在什麼地方: 待續
相關文章
相關標籤/搜索