我們都知道,HDevelop中,在菜單欄“助手”中,可以通過“Matching”助手輔助模板匹配的建模等操作。
“基於形狀”的模板匹配, 主要有三種類型:find_shape_model、find_scaled_shape_model、find_aniso_shape_model。
那么這三種類型有什么區別呢?我用一張圖來說明。
說明:find_shape_model指的是行列方向均無縮放的模板匹配,find_scaled_shape_model指的是行列等比例縮放的模板匹配,find_aniso_shape_model指的是行列不等比例縮放(各向異性縮放)的模板匹配。
上面三個算子一般如何根據實際情況選擇呢?
① 在實際的視覺項目中,一般工件的大小是基本相同的。如果只有一個相機,那么可以直接用find_shape_model來做模板匹配;
② 如果有多個工站、多個相機,並且用的還是同款相機、同款遠心鏡頭的話,由於遠心鏡頭只有一個固定的對焦距離,因此兩個工位中的工件在圖中的大小是一樣大的。此時還是可以用find_shape_model來做模板匹配;
③ 如果有多個工站、多個相機,但是用的是普通鏡頭的話,由於普通鏡頭的對焦距離是不固定的,因此視野的放大倍率也不固定,此時兩個工位中的工件在圖中的大小是不一樣的。此時適合用find_scaled_shape_model來做模板匹配;
④ find_aniso_shape_model的應用場景較少,很少用於精細的模板匹配定位檢測。在運動速度不固定的線掃項目中,可能會用到這個算子。因為線掃平台速度變化時,待測工件圖像的長寬比經常會發生變化,此時用find_aniso_shape_model就比較合適。一般來說,這個算子的執行時間是三個里面最長的,因為它有最大的不確定性。
find_aniso_shape_model的應用場景有限,因此我不討論它。從上面的分析可以看出:find_scaled_shape_model是完全可以涵蓋find_shape_model的功能的,因此下文以find_scaled_shape_model算子來展開分析。
以下圖為例:
測試的軟硬件環境為:Windows 10、Intel Xeon E5-2630 v3 2.40GHz、Halcon 17.12。
該圖的建模區域,以及初始參數設置如下圖所示:
另外,最小分數為0.3,匹配的最大數為1。除此之外的所有參數均使用默認值。
一鍵生成的代碼精簡后如下:
1 set_system ('border_shape_models', 'false') 2 read_image (Image, 'C:/Users/02/Desktop/形狀模板匹配/接口.png') 3 gen_rectangle1 (ModelRegion, 92, 80, 339, 731) 4 reduce_domain (Image, ModelRegion, TemplateImage) 5 *
6 create_scaled_shape_model (TemplateImage, 4, rad(0), rad(360), rad(0.3386), 0.97, 1.03, 0.0059, ['point_reduction_high','no_pregeneration'], 'use_polarity', [60,80,10], 5, ModelID) 7 *
8 get_shape_model_contours (ModelContours, ModelID, 1) 9 *
10 * Matching 02: Get the reference position 11 area_center (ModelRegion, ModelRegionArea, RefRow, RefColumn) 12 vector_angle_to_rigid (0, 0, 0, RefRow, RefColumn, 0, HomMat2D) 13 affine_trans_contour_xld (ModelContours, TransContours, HomMat2D) 14 *
15 * Matching 02: Display the model contours 16 dev_display (Image) 17 dev_set_color ('green') 18 dev_set_draw ('margin') 19 dev_display (ModelRegion) 20 dev_display (TransContours) 21
22 *開始匹配(這里簡單起見,匹配的就是建模圖像本身) 23 find_scaled_shape_model (Image, ModelID, rad(0), rad(360), 0.97, 1.03, 0.3, 1, 0.5, 'least_squares', [4,1], 0.75, Row, Column, Angle, Scale, Score) 24
25 dev_display (Image) 26 for I := 0 to |Score| - 1 by 1
27 hom_mat2d_identity (HomMat2D) 28 hom_mat2d_scale (HomMat2D, Scale[I], Scale[I], 0, 0, HomMat2D) 29 hom_mat2d_rotate (HomMat2D, Angle[I], 0, 0, HomMat2D) 30 hom_mat2d_translate (HomMat2D, Row[I], Column[I], HomMat2D) 31 affine_trans_contour_xld (ModelContours, TransContours, HomMat2D) 32 dev_set_color ('green') 33 dev_display (TransContours) 34 endfor 35
36 clear_shape_model (ModelID)
一般來說,我們不太在意建模算子create_scaled_shape_model的速度,因為模型文件一般是提前准備好保存在本地的。建模快一點慢一點,問題不大。但是建模中,也有幾個參數對查找模板的速度有較大影響的,它們是:
設置合適的對比度,設置較大的“最小組件尺寸”,可以確保模板輪廓XLD不會過於復雜。過於復雜的XLD是會影響后面的模板查找速度的。
find_scaled_shape_model語句中,對查找速度有明顯影響的算子,我已經標紅了,如下:
find_scaled_shape_model (Image, ModelID, rad(0), rad(360), 0.97, 1.03, 0.3, 1, 0.5, 'least_squares', [4,1], 0.75, Row, Column, Angle, Scale, Score)
上面6個參數的參數名和含義如下:
AngleStart(rad(0)): 搜索時的起始角度。
AngleExtent(rad(360)):搜索時的角度范圍。
ScaleMin(0.97):行列的最小縮放比例。
ScaleMax(1.03):行列的最大縮放比例。
NumLevels(4):搜索時金字塔的層數。
Greediness(0.75):貪婪系數,啟發式搜索,默認值0.75,越高速度越快,但容易出現找不到的情況。這個值我們一般不改它。
① 在我電腦上,上面find_scaled_shape_model 算子的查找時間為:25毫秒。
② find_scaled_shape_model (Image, ModelID, rad(0), rad(360), 0.97, 1.03, 0.3, 1, 0.5, 'least_squares', [3,1], 0.75, Row, Column, Angle, Scale, Score)
將金字塔層級由“4”改成“3”,查找時間為:83毫秒。(金字塔層級一般不會設置為“1”或者“2”,因為此時查找會特別慢,經常超過1秒鍾。如果圖像較大,該值一般最小設置為“4”)
將金字塔層級由“4”改成“7”,查找時間為:25毫秒。(主要是這張圖比較小,當金字塔層級大於4以后,再增加,並不能顯著減少查找時間)
值得說明的是:使用較小的金字塔層級,模板匹配的成功率會大大增加。(但是時間會增加)
另外,NumLevels可以包含第二個值,該值確定跟蹤找到的匹配項的最低金字塔級別。因此,NumLevels值[4,2]表示匹配從第4個金字塔級別開始,並跟蹤匹配到第2個金字塔級別(最低的金字塔級別由值1表示)。該機制可用於減少匹配的運行時間。
然而,應當注意,一般在該模式下提取的姿態參數的精度低於在正常模式中的精度,在正常模式中,匹配被跟蹤到最低金字塔級別(本人注:即級別1)。因此,如果需要高精度,則子像素應至少設置為“least_squares”。
如果要使用的最低金字塔級別選擇得太大,則可能會發生無法實現所需精度的情況,或者由於模型在較高金字塔級別上不夠具體而可能會找到錯誤的模型實例。在這種情況下,要使用的最低金字塔級別(我自己的理解:這里指的應該是NumLevels的第二個值)必須設置為較小的值。 (上面三段話翻譯自find_scaled_shape_model 的幫助文檔)
可以得出結論,一般來說,NumLevels := [4, 2],查找速度應該會略快於NumLevels := [4, 1]和NumLevels := [4]。
NumLevels 的第二個值還可以為負數(通常針對邊緣模糊的圖像的匹配定位),具體參考find_scaled_shape_model 的幫助文檔或find_shape_mode參數詳解及時長優化。
③ find_scaled_shape_model (Image, ModelID, rad(0), rad(360), 1.0, 1.0, 0.3, 1, 0.5, 'least_squares', [4,1], 0.75, Row, Column, Angle, Scale, Score)
將行列最小、最大縮放比例均改為1.0,此時等效於使用find_shape_model算子(查找時間也幾乎一樣)。此時查找時間為:14毫秒。
實測可以發現,ScaleMin、ScaleMax這兩個參數越接近1,查找所需的時間越短。其實也很好理解,當縮放比例變化范圍較大時,准確的模板匹配需要進行更多的嘗試,自然會需要更長的計算時間。
④ find_scaled_shape_model (Image, ModelID, rad(-10), rad(20), 0.97, 1.03, 0.3, 1, 0.5, 'least_squares', [4,1], 0.75, Row, Column, Angle, Scale, Score)
將搜索的起始角度設置為rad(-10), 角度范圍設置為rad(20),即 [rad(-10), rad(10)] ,此時查找時間為:6毫秒!
可見選擇合適的搜索起始角度和角度范圍,可以大幅度提高查找速度。
實驗總結:如果想減少模板查找時間,需要創建輪廓XLD不那么復雜的模板,需要設置較小的角度范圍,需要設置盡可能小的行列縮放比例,需要設置盡可能大的金字塔層級。
但是,金字塔層級不宜設置過大,金字塔層級太大時,很容易查找模板失敗。
另外,還有一篇文章對模板匹配有一些經驗總結,我貼過來:https://www.cnblogs.com/bile/p/8528843.html
基於形狀匹配的參數關系與優化
這里主要是重復說明一下這些參數的作用,再強調一下它們影響匹配速度的程度;在為了提高速度而設置參數之前,有必要找出那些在所有測試圖像中匹配成功的設置,這時需考慮以下情況:
① 必須保證物體在圖像邊緣處截斷,也就是保證輪廓的清晰,這些可以通過形態學的一些方法來處理;
② 如果Greediness值設的太高,就找不到其中一些可見物體,這時最后將其設為0來執行完全搜索;
③ 物體是否有封閉區域,如果要求物體在任何狀態下都能被識別,則應減小MinScore值;
④ 判斷在金字塔最高級上的匹配是否失敗,可以通過find_shape_model()減小NumLevels值來測試;
⑤ 物體是否具有較低的對比度,如果要求物體在任何狀態下都能被識別,則應減小MinContrast值;
⑥ 判斷是否全局地或者局部地轉化對比度極性,如果需要在任何狀態下都能被識別,則應給參數Metric設置一個合適的值;
⑦ 物體是否與物體的其他實例重疊,如果需要在任何狀態下都能識別物體,則應增加MaxOverlap值;
⑧ 判斷是否在相同物體上找到多個匹配值,如果物體幾乎是對稱的,則需要控制旋轉范圍。
如何加快搜索匹配,需要在這些參數中進行合理的搭配,有以下方法可以參考:
① 只要匹配成功,則盡可能增加參數MinScore的值;
② 增加Greediness值直到匹配失敗,同時在需要時減小MinScore值;
③ 如果有可能,在創建模板時使用一個大的NumLevels,即將圖像多分幾個金字塔級;
④ 限定允許的旋轉范圍和大小范圍,在調用find_shape_model()時調整相應的參數;
⑤ 盡量限定搜索ROI的區域。
除上面介紹的以外,在保證能夠匹配的情況下,盡可能的增大Greediness的值,因為在后面的實驗中,用模板匹配進行視頻對象跟蹤的過程中,這個值在很大程度上影響到匹配的速度。
當然這些方法都需要跟實際聯系起來,不同圖像在匹配過程中也會有不同的匹配效果,在具體到某些應用,不同的硬件設施也會對這個匹配算法提出新的要求,所以需要不斷地去嘗試。