基於NCC的多目標多角度快速模板匹配算法詳見:http://www.javashuo.com/article/p-vqdbukfw-vk.htmlhtml
乘着研究NCC的熱情,順便也研究了下基於邊緣梯度的匹配。算法
基於邊緣梯度方面的匹配,最爲出名的莫過於CodeProject上一篇多年前的印度小哥的文章,連接爲:Edge Based Template Matching。測試
這篇文章的核心計算公式爲:網站
(1)編碼
在國內的中文有關網站上卻經常看到下述公式(分母第二項不一樣),這明顯是個錯誤的式子,也不知道哪位是原始創造者。spa
這個核心計算式和基於NCC的看上去類似又有着不少不一樣。注意式子中的大寫字母G表示圖像的梯度信息,這個是可正亦可負的。即計算式已經脫離原有的像素信息,而使用了梯度相關信息,經常使用的獲取X和Y方向梯度的方式有:.net
即Sobel邊緣檢測算子。code
在印度小哥的文章裏,採用了Canny檢測來檢測出邊緣,而後只對模板圖和搜索圖中對應的邊緣位置計算上述得分公式(以模板圖中的邊緣處爲依據), 這樣起到減小取樣點,提升速度的做用。htm
我實際測試這種方法若是直接對模板和搜索圖作,不少狀況下是能夠的,可是仍是存在着一些問題,主要有:對象
一、雖然Canny的使用減小了不少計算量,可是他徹底剔除了其餘弱邊緣處的信息,就好像把考試中那些不及格的學生都定型爲差生同樣,是不科學的。這些弱邊緣在必定程度上也有着至關的信息量。
二、Canny自己是有着不少參數來控制最終的效果的,不是一個固定的參數對每一副圖像都能獲取穩定的效果,所以,這就很難成爲一個穩定的算法了。
三、若是採用了金字塔等技術,在金字塔層數增長時,Canny所對應的邊緣會愈來愈不穩定,這會影響最終的精度。
因此,我以爲不該該使用Canny獲其餘的相似技術實現這個過程,個人想法仍是對全圖實現上述公式的計算。
可是,這又會遇到幾個問題。
一、計算量飆升,這個能夠經過金字塔的技術來解決。
二、咱們仔細的觀察公式(1),若是作一個全局的匹配計算,在計算過程當中,必然會遇到很多地方的X和Y方向的梯度都爲0或者很小,並且這種像素佔的比例還至關高,畢竟圖像中真正屬於邊緣的地方不多。那麼這樣的一個事實就回到致使不少累加項的值爲0或很小(X和Y梯度都爲0時,式子的分母爲0,程序須要作判斷,但輸出的結果必然也會是0),這樣總體累加後再求平均數咱們將得到一個很小的得分(哪怕和模板圖如出一轍的地方)。
一種改進的方法就是把模板圖的總體的幅值信息做爲一個因子放入到上述計算公式的分母中,這樣,模板圖中梯度較小的位置,對總體的幅值貢獻就小,從而不會對最後的得分形成影響。
在實際的編碼中,咱們還會遇到不少的其餘方面的困難,列舉一些以下:
一、對於角度的檢測,相似的,咱們也建立多個離散的模板,咱們須要旋轉模板,而後計算模板的邊緣梯度,可是,旋轉自己產生了新的邊緣,並且是強邊緣,以下所示:
若是把這邊緣帶入式中計算,很是明顯不會獲得可靠的結果,咱們須要把這個邊緣剔除。
二、不管採用何種邊緣梯度檢測算子,最小的都會涉及到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的(不影響測試使用),請不要將其直接應用到工業環境中,以避免形成沒必要要的損失。
若是您以爲本博文對您有所幫助,也可慷慨解囊。