SIFT算法:DoG尺度空間生產 |
SIFT算法:KeyPoint找尋、定位與優化 |
SIFT算法:確定特征點方向 |
SIFT算法:特征描述子 |
目錄:
1、確定描述子采樣區域
2、生成描述子
2.1 旋轉圖像至主方向
2.2 生成特征向量
3、歸一化特征向量
附:SIFT開源代碼集
1 確定描述子采樣區域
SIFI 描述子h(x, y, θ)是對特征點附近鄰域內高斯圖像梯度統計結果的一種表示,它是一個三維的陣列,但通常將它表示成一個矢量。矢量是通過對三維陣列按一定規律進行排列得到的。特征描述子與特征點所在的尺度有關,因此,對梯度的求取應在特征點對應的高斯圖像上進行。將特征點附近鄰域划分成Bp X Bp個子區域,每個子區域的尺寸為mσ個像元,其中,m=3,Bp=4。σ為特征點的尺度值。考慮到實際計算時,需要采用雙線性插值,計算的圖像區域為mσ(Bp+ 1)。如果再考慮旋轉的因素,那么,實際計算的圖像區域應大mσ(Bp+ 1)√2。
2 生成描述子
2.1 旋轉圖像至主方向
為了保證特征矢量具有旋轉不變性,需要以特征點為中心,將特征點附近鄰域內(mσ(Bp+ 1)√2 x mσ(Bp+ 1)√2)圖像梯度的位置和方向旋轉一個方向角θ,即將原圖像x軸轉到與主方向相同的方向。旋轉公式如下。
在特征點附近鄰域圖像梯度的位置和方向旋轉后,再以特征點為中心,在旋轉后的圖像中取一個mσBp x mσBp大小的圖像區域。並將它等間隔划分成Bp X Bp個子區域,每個間隔為mσ像元。
2.2 生成特征向量
在每子區域內計算8個方向的梯度方向直方圖,繪制每個梯度方向的累加值,形成一個種子點。與求特征點主方向時有所不同,此時,每個子區域的梯度方向直方圖將0° ~360°划分為8個方向范圍,每個范圍為45°,這樣,每個種子點共有8個方向的梯度強度信息。由於存在4X4(Bp X Bp)個子區域,所以,共有4X4X8=128個數據,最終形成128維的SIFT特征矢量。同樣,對於特征矢量需要進行高斯加權處理,加權采用方差為mσBp/2的標准高斯函數,其中距離為各點相對於特征點的距離。使用高斯權重的是為了防止位置微小的變化給特征向量帶來很大的改變,並且給遠離特征點的點賦予較小的權重,以防止錯誤的匹配。
問題1:對於旋轉之后的點進行三線性插值,具體是怎樣操作的?
Lowe原文如下:
It is important to avoid all boundary affects in which the descriptor abruptly changes as a sample shifts smoothly from being within one histogram to another or from one orientation to another. Therefore, trilinear interpolation is used to distribute the value of each gradient sample into adjacent histogram bins. In other words, each entry into a bin is multiplied by a weight of 1 − d for each dimension, where d is the distance of the sample from the central value of the bin as measured in units of the histogram bin spacing.
表示看不懂OpenCV和vlfeat中插值這一部分具體實現。還請高人指點。
3 歸一化特征向量
為了去除光照變化的影響,需對上述生成的特征向量進行歸一化處理,在歸一化處理后,對特征矢量大於0.2的要進行截斷處理,即大於0.2的值只取0.2,然后重新進行一次歸一化處理,其目的是為了提高鑒別性。

1 float nrm2 = 0; 2 len = d*d*n; 3 for( k = 0; k < len; k++ ) 4 nrm2 += dst[k]*dst[k]; 5 float thr = std::sqrt(nrm2)*SIFT_DESCR_MAG_THR; // SIFT_DESCR_MAG_THR = 4 6 for( i = 0, nrm2 = 0; i < k; i++ ) 7 { 8 float val = std::min(dst[i], thr); //截斷大於0.2的值 9 dst[i] = val; 10 nrm2 += val*val; 11 } 12 nrm2 = SIFT_INT_DESCR_FCTR/std::max(std::sqrt(nrm2), FLT_EPSILON); // SIFT_INT_DESCR_FCTR = 512.f
SIFT開源代碼:
- http://www.vlfeat.org vlfeat開源圖像處理庫,其中http://www.vlfeat.org/api/sift.html關於其代碼中一些細節和SIFT原理的解釋。
- http://robwhess.github.io/opensift/ RobHess sift
- http://www.cs.ubc.ca/~lowe/research.html David Lowe Research Projects中的SIFT
- http://docs.opencv.org/2.4/modules/nonfree/doc/feature_detection.html OpenCV2.4以后的版本已實現了SIFT,其源碼和RobHess的很相似。
參考資料:
- David G. Lowe Distinctive Image Features from Scale-Invariant Keypoints
- 王永明 王貴錦 《圖像局部不變性特征與描述》
- Trilinear interpolation http://en.wikipedia.org/wiki/Trilinear_interpolation