【區域性特徵】ASIFT

一點心青發表於2014-03-04

      由於相機正面白攝物體時,相機的光軸方向可能發生變化,帶來扭曲。而SIFT演算法雖具有完全的尺度不變性,但不具有完全的仿射不變性,對拍攝角度發生大角度空間變化的影象特徵提取有一定的侷限性。ASift通過模擬經度與緯度實現完全的仿射不變,然後用SIFT演算法把模擬影象進行比較,最後實現特徵匹配。

ASIFT演算法的具體步驟如下:

1.選取取樣引數,模擬不同經度與緯度的影象。

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.py

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檢測出特徵點數目差異較大。

相關文章