【局部特徵】ASIFT

      因爲相機正面白攝物體時,相機的光軸方向可能發生變化,帶來扭曲。而SIFT算法雖具備徹底的尺度不變性,但不具備徹底的仿射不變性,對拍攝角度發生大角度空間變化的圖像特徵提取有必定的侷限性。ASift經過模擬經度與緯度實現徹底的仿射不變,而後用SIFT算法把模擬圖像進行比較,最後實現特徵匹配。python

ASIFT算法的具體步驟以下:git

1.選取採樣參數,模擬不一樣經度與緯度的圖像。github

2.計算模擬圖像的特徵。算法

3.結合全部的模擬圖像的特徵,進行特徵匹配。多線程

注意:ASIFT提供的一種框架,其核心思想是模擬不一樣的經度與緯度的圖像,具體模擬圖像的特徵提取和匹配,可選擇SIFT、SURF等特徵。框架

ASIFT算法代碼資源:異步

http://www.ipol.im/pub/art/2011/my-asift/測試

https://github.com/Itseez/opencv/blob/master/samples/python2/asift.pyspa

OpenCV只提供python實現的asift,若是須要在C++中使用asift,主要有兩種方法可參考。線程

1.利用做者提供的C++代碼,具體使用方法可參考做者提供的文檔。

2.將asift.py翻譯成C++代碼。

asift.py代碼相對清晰,轉換成基於OpenCV的C++代碼比較容易,我主要參用方法2,實現ASIFT算法。

遇到的問題:

1.處理分辨率較大圖片時,出現OpenCV Error: Insufficient memory的錯誤。

  經分析,計算過程須要保存多張模擬圖片的特徵點和特徵描述子,須要大量內存,致使OpenCV分配內存時,沒有連續可用的內存塊,從而出現OpenCV Error: Insufficient memory的錯誤。

  解決方法:下降待處理圖片的分辨率,並計算高分辨率到低分辨率轉換的單應性矩陣scaleH。利用ASift算法計算低分辨率圖片的匹配的單應性矩陣matchH。最終待處理圖片的單應矩陣H=matchH*scaleH。

2.計算複雜度問題。

  因爲須要處理多幅模擬圖片的特徵點檢測,計算複雜度高。目前,主要有兩種思路:1).下降分辨率,減小計算量。2).利用硬件特性進行硬件計算。

ASift做者在文中提到的Two-Resolution Procedure.

(1).採用係數K*K二次採樣查詢圖片u和待搜索圖片v。u = SkGku,v=SkGkv,Gk是反走樣高斯離散濾波器,SK爲K*K二次採樣。

(2).低分辨率下的ASIFT算法:對查詢圖片u和搜索圖片應用ASIFT算法;

(3).肯定u和v中可能產最多匹配對的M種仿射變換;

(4).高分辨率下的ASIFT算法:在原始圖像u和v上使用ASIFT算法,但模擬傾科時只使用這M種仿射變換。

經實驗測試,發現Two-Resolution Procedure雖然能夠在必定下降複雜度,但其對匹配精度會有必定的影響,對於匹配精度要求高的應用不太合適

Asift.py中,利用線程池加速多幅圖像的特徵點檢測,使得多幅圖像的特徵點檢測同時進行。

結合多線程的思想,我利用每一個線程,計算每幅圖像的特徵點的檢測,結果遇到內存不足的問題。

主要緣由:特徵點檢測過程須要內存空間存儲部分中間結果,當多線程同時計算時,所需內存增大,出現內存不足的問題。

解決方法:能夠根據待處理圖片的分辨率大小和系統提供內存資源的多少,自適應肯定多線程的數目。

利用GPU加速ASIFT計算,具體步驟以下:

(1).將待處理圖片傳輸到GPU端。

(2).將待處理圖片模擬變換,獲得模擬圖片,AffineImage_Kernel。

(3).計算模擬圖片的特徵點,KeyPointsDetect_Kernel。

(4).將計算所得的特徵點數據傳輸到CPU端。

(5).循環處理(2)、(3)、(4)步驟,直到全部模擬變換處理完。

(6).在CPU端完成特徵點匹配計算。

注意:(4)與(5)能夠異步執行,重疊計算與特徵點數據傳輸的時間。

基於GPU特徵點計算主要參考:

SiftGPU: http://cs.unc.edu/~ccwu/siftgpu/

CudaSift: https://github.com/Celebrandil/CudaSift

注意:經測試,發現SiftGPU和CudaSift檢測出的特徵點數目與OpenCV的SiftFeatureDetector檢測出特徵點數目差別較大。

相關文章
相關標籤/搜索