作者:July | 日期:2011年3月12日 | 參考:Rob Hess SIFT庫 | 環境:Windows XP + VC6.0
前兩篇文章已介紹SIFT算法原理及基於第三方庫的編譯運行。有讀者詢問:能否純用C語言實現SIFT,不依賴OpenCV、GSL等外部庫?且Rob Hess庫代碼晦澀難懂。本文將帶你一步步用C語言從零構建SIFT算法,讓你真正洞悉其核心機制。
SIFT算法包含五大核心步驟,對應下圖第2-6張效果圖:






SIFT(Scale-Invariant Feature Transform,尺度不變特徵轉換)是David Lowe於1999年提出、2004年完善的計算機視覺算法,用於檢測與描述圖像局部特徵,具備位置、尺度、旋轉不變性。
通俗來說:使用不同尺度(標準差)的高斯函數對圖像平滑,比較平滑前後差異,差異大的像素即為明顯特徵點。
高斯函數公式:
G(x,y,σ) = 1/(2πσ²) * exp[-(x²+y²)/(2σ²)]
圖像尺度空間 L(x,y,σ) 定義為原始圖像 I(x,y) 與高斯函數卷積:
L(x,y,σ) = G(x,y,σ) * I(x,y)
其中 σ 控制平滑程度:大σ對應粗糙尺度(低分辨率,概貌特徵),小σ對應精細尺度(高分辨率,細節特徵)。
為降低計算複雜度,採用金字塔結構:

直接高斯卷積計算量大,引入高斯差分:
D(x,y,σ) = L(x,y,kσ) - L(x,y,σ) = (G(x,y,kσ) - G(x,y,σ)) * I(x,y)
DoG算子計算簡單,是尺度歸一化的LoG算子近似,能高效檢測穩定關鍵點。


每組相鄰高斯圖像相減得DoG圖像:


在DoG尺度空間中,將每個點與鄰域(同尺度8鄰域+上下尺度各9點,共26點)比較,局部極值點即為候選特徵點。
通過泰勒展開擬合DoG極值,剔除低對比度點與邊緣響應點,獲得精確關鍵點位置與尺度。(詳細數學推導見下篇)