【工程應用二】 多目標多角度的快速模板匹配算法(基於邊緣梯度)

       基於NCC的多目標多角度快速模板匹配算法詳見:https://www.cnblogs.com/Imageshop/p/14559685.html

       乘着研究NCC的熱情,順便也研究了下基於邊緣梯度的匹配。

       基於邊緣梯度方面的匹配,最爲出名的莫過於CodeProject上一篇多年前的印度小哥的文章,鏈接爲:Edge Based Template Matching

       這篇文章的核心計算公式爲:

                           (1)

 

       在國內的中文有關網站上卻常常看到下述公式(分母第二項不同),這明顯是個錯誤的式子,也不知道哪位是原始創造者。

              

        這個核心計算式和基於NCC的看上去相似又有着很多不同。注意式子中的大寫字母G表示圖像的梯度信息,這個是可正亦可負的。即計算式已經脫離原有的像素信息,而使用了梯度相關信息,常用的獲取X和Y方向梯度的方式有:

            

    即Sobel邊緣檢測算子。

         在印度小哥的文章裏,採用了Canny檢測來檢測出邊緣,然後只對模板圖和搜索圖中對應的邊緣位置計算上述得分公式(以模板圖中的邊緣處爲依據), 這樣起到減少取樣點,提高速度的作用。

         我實際測試這種方法如果直接對模板和搜索圖做,很多情況下是可以的,但是還是存在着一些問題,主要有:

         1、雖然Canny的使用減少了很多計算量,但是他完全剔除了其他弱邊緣處的信息,就好像把考試中那些不及格的學生都定型爲差生一樣,是不科學的。這些弱邊緣在一定程度上也有着相當的信息量。

         2、Canny本身是有着很多參數來控制最終的效果的,不是一個固定的參數對每一副圖像都能獲取穩定的效果,因此,這就很難成爲一個穩定的算法了。

         3、如果採用了金字塔等技術,在金字塔層數增加時,Canny所對應的邊緣會越來越不穩定,這會影響最終的精度。

         所以,我覺得不應該使用Canny獲其他的類似技術實現這個過程,我的想法還是對全圖實現上述公式的計算。

         但是,這又會遇到幾個問題。

         1、計算量飆升,這個可以通過金字塔的技術來解決。

         2、我們仔細的觀察公式(1),如果做一個全局的匹配計算,在計算過程中,必然會遇到不少地方的X和Y方向的梯度都爲0或者很小,而且這種像素佔的比例還相當高,畢竟圖像中真正屬於邊緣的地方很少。那麼這樣的一個事實就回到導致很多累加項的值爲0或很小(X和Y梯度都爲0時,式子的分母爲0,程序需要做判斷,但輸出的結果必然也會是0),這樣整體累加後再求平均數我們將獲得一個很小的得分(哪怕和模板圖一模一樣的地方)。

        一種改進的方法就是把模板圖的整體的幅值信息作爲一個因子放入到上述計算公式的分母中,這樣,模板圖中梯度較小的位置,對整體的幅值貢獻就小,從而不會對最後的得分造成影響。

        在實際的編碼中,我們還會遇到很多的其他方面的困難,列舉一些如下:

       1、對於角度的檢測,類似的,我們也創建多個離散的模板,我們需要旋轉模板,然後計算模板的邊緣梯度,但是,旋轉本身產生了新的邊緣,而且是強邊緣,如下所示:

          

     如果把這邊緣帶入式中計算,非常明顯不會得到可靠的結果,我們需要把這個邊緣剔除。

     2、無論採用何種邊緣梯度檢測算子,最小的都會涉及到3*3的局部範圍,那麼對於未旋轉或者旋轉後的模板圖,都存在一個明顯問題,最外一圈像素的梯度如何處理,如果使用重複邊緣像素的方式,那麼就會獲得一個較小的梯度,但是實際在在搜索圖中是不存在這個問題的,只要模板不在搜索圖的邊緣處。因此,如果這樣處理,哪怕模板就是從搜索圖中直接扣取出來的,依據(1)式計算出的結果也不會等於1,而是小於1。

  如何解決這個問題,我目前想到的也只有忽略最外圈的梯度值,即他們不參與相似性計算。這樣就要求在做模板圖時,需要可以在實際需要的模板的基礎上,中心對稱的長和寬每邊各增加一個像素。但是,這樣實際上還是沒有完美解決問題,因爲當有金字塔存在時,這可以增加的1個像素經過下采樣後已經沒有一個像素了,還是有點頭大,暫時沒有想到什麼好辦法。、

IM_Rotate(Template, Rotate, RTI.Mask, Angle, 1, Amount);            //    旋轉圖像,獲取Mask值
IM_Edge_Erode_3X3(RTI.Mask, RTI.Mask);

  想到的另外一個方法就是旋轉時不是旋轉圖像然後再計算梯度,而是直接旋轉X和Y方向的梯度,但是新的難處是梯度值是有正有負的,這種數據的旋轉在使用雙線性插值時,由於四個取樣點的極性不同,是否能直接處理呢,我感覺好像有問題,比如四個數,2正2負,有可能插值後結果就爲0了。

      目前,採用了一些非常規的手段,還是基本有一定的成果了,一些不是特別情況的圖,使用基於邊緣梯度的方式也能獲取到較爲準確的結果,比如基於NCC那個幾個測試圖,也是可以的。

      進一步測試表明,這個算法相對於NCC,在某些情況下確實是有更靠譜的識別結果,而且是對強邊緣的識別效果很不錯。

           

          基於NCC的結果                                               基於邊緣梯度的結果

       由上面的測試圖也可看出,兩種算法對於光照的影響都有一定的抵抗能力。

       再看一個比較有意思的圖:

       

       這裏的MaxOverlap設置爲0.7,MinScore也設置爲0.7.

       對於下面這種複雜的邊緣重疊的對象也有一定的免疫力。

        

 

                                           基於NCC的結果                                                                基於邊緣梯度的結果

     上述測試圖,基於邊緣的成功的鎖定了20個待檢測的目標,而基於NCC的則丟失了一個,當然這並不是說基於NCC的就比基於邊緣的差。

       本算法待進一步改進後可能會集成到國產視覺軟件Malcon中,詳情請看 中國的Malcon跟德國的Halcon的相比的優缺點 

       Malcon官方博客:https://www.cnblogs.com/Malcon

       或者點擊:         https://blog.csdn.net/lindrs/article/details/114113280?spm=1001.2014.3001.5502

       目前可通過下面鏈接獲取一個可視化的Demo:  https://files.cnblogs.com/files/Imageshop/TemplateMatching.rar

       同樣聲明,這個Demo本身是有Bug的(不影響測試使用),請不要將其直接應用到工業環境中,以免造成不必要的損失。

      如果您覺得本博文對您有所幫助,也可慷慨解囊。

     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章