一、SIFT特徵介紹
SIFT全稱是Scale Invariant Feature Transform,即為尺度不變特徵變換,是由David Lowe在1999年提出的一種特徵檢測算法,它可以檢測出圖像中獨特的、穩定的局部特徵並進行描述。SIFT特徵對於縮放、旋轉、仿射變換都具有不變性,也具有一定的光照魯棒性。
通過對SIFT算法的實現,圖像中的每個特徵點都可以被描述成一個向量,這個向量可以作為後續計算識別的基礎。SIFT特徵在圖像識別、增強現實、物體跟蹤等領域都有廣泛的應用。
二、SIFT特徵提取
在SIFT算法中,特徵的提取一般包含四個步驟:尺度空間極值檢測、關鍵點定位、方向確定和特徵描述。
1. 尺度空間極值檢測
由於物體在圖像中出現的大小和方向是不確定的,所以SIFT算法使用了一個高斯金字塔來對圖像進行尺度空間的處理。在高斯金字塔的不同層次上,使用高斯差分來檢測各個尺度下圖像的極值點。
/** * 尺度空間極值檢測函數 * @param DogPyr 差分金字塔 * @param octvs 金字塔的組數 * @param intvls 每組中相鄰兩層的差分結果個數 * @param contr_thr 極值點的閾值 * @param r 極值點的鄰域半徑 * @return 關鍵點 */ vector ScaleSpaceExtrema(const vector<vector>& DogPyr, const int octvs, const int intvls, const double contr_thr, const int r);
2. 關鍵點定位
在檢測到尺度空間中的極值點後,需要對每個極值點進行更加精確的定位,確定其精確位置和尺度大小。
/** * 關鍵點定位函數 * @param DogPyr 差分金字塔 * @param octvs 金字塔的組數 * @param intvls 每組中相鄰兩層的差分結果個數 * @param extrema 尺度空間極值點 * @param contr_thr 極值點的閾值 * @param curv_thr 極值點的曲率閾值 * @return 關鍵點和尺度 */ vector Localization(const vector<vector>& DogPyr, const int octvs, const int intvls, vector& extrema, const double contr_thr, const double curv_thr);
3. 方向確定
在確定了極值點的位置和尺寸後,還需要確定這個點的主要方向。SIFT算法選擇使用極值點周圍一定範圍內梯度幅值最大的方向作為該點的主方向。
/** * 方向直方圖生成函數 * @param img 關鍵點所在圖像 * @param kpt 關鍵點 * @param bins 直方圖個數 * @param sigma 高斯權重方差 * @return 方向直方圖 */ vector OrientationHistogram(const Mat& img, const Keypoint& kpt, const int bins, const double sigma); /** * 方向確定函數 * @param gauss_pyr 已經計算好的高斯差分金字塔 * @param kpt 關鍵點 * @param octv 關鍵點所在組 * @param intvl 關鍵點所在層 * @param n 關鍵點附近每個直方圖的直方圖個數 * @param sigma 關鍵點周圍鄰域的高斯係數 * @return 關鍵點方向(弧度) */ double GetOrientation(const vector<vector>& gauss_pyr, const Keypoint& kpt, const int octv, const int intvl, const int n, const double sigma);
4. 特徵描述
在確定了極值點的位置、尺寸和主要方向後,針對每個關鍵點的周圍區域,選取一些關鍵點方向的特徵點來進行描述。SIFT特徵描述子被設計為對每個關鍵點周圍的16×16個像素塊生成一個128維的向量。向量中每個維度反映的是該像素塊的梯度幅值和方向。
/** * 描述子生成函數 * @param img 關鍵點所在圖像 * @param kpt 關鍵點 * @param ori 關鍵點方向 * @param scl 關鍵點尺度 * @param d 關鍵點描述子所在的維度 * @return 關鍵點描述子 */ vector Descriptor(const Mat& img, const Keypoint& kpt, const double ori, const double scl, const int d);
三、SIFT特徵匹配
在使用SIFT特徵進行圖像匹配時,通常採用關鍵點描述子之間的相似度來計算兩幅圖像之間的相似度。我們可以通過計算兩個描述子之間的歐式距離,來衡量他們之間的相似性。
/** * 計算描述子之間的距離 * @param desc1 描述子1 * @param desc2 描述子2 * @return 描述子之間的距離 */ double Distance(const vector& desc1, const vector& desc2); /** * 通過比較兩個特徵點的描述子,計算它們之間的距離 * @param desc1 特徵點1的描述子 * @param desc2 特徵點2的描述子 * @return 特徵點1和2之間的距離 */ double MatchScore(const vector& desc1, const vector& desc2); /** * 特徵點匹配函數 * @param desc1 特徵點說明子1 * @param desc2 特徵點描述子2 * @return 最佳匹配的位置 */ int BestMatch(const vector& desc1, const vector<vector>& desc2);
四、SIFT特徵的應用
SIFT特徵在計算機視覺中有着廣泛的應用,在圖像識別、目標檢測、增強現實、全景圖像拼接、物體跟蹤等領域都有着非常重要的作用。
例如在目標檢測領域,通過提取圖像中所有的SIFT特徵,可以構建一個描述圖像信息和特徵向量信息的數據庫。當需要檢測一張未知圖像是否包含相同的目標時,我們可以提取這張圖像的SIFT特徵並在數據庫中進行匹配,最終找到相同目標所在的圖像。
原創文章,作者:OLHYC,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/368719.html