BRIEF 特徵描述子
Binary Robust Independent Elementary Features
1. BRIEF的基本原理
我們已經知道SIFT特徵採用了128維的特徵描述子,由於描述子用的浮點數,所以它將會佔用512 bytes的空間。類似地,對於SURF特徵,常見的是64維的描述子,它也將佔用256bytes的空間。如果一幅影象中有1000個特徵點(不要驚訝,這是很正常的事),那麼SIFT或SURF特徵描述子將佔用大量的記憶體空間,對於那些資源緊張的應用,尤其是嵌入式的應用,這樣的特徵描述子顯然是不可行的。而且,越佔有越大的空間,意味著越長的匹配時間。
但是實際上SFIT或SURF的特徵描述子中,並不是所有維都在匹配中有著實質性的作用。我們可以用PCA、LDA等特徵降維的方法來壓縮特徵描述子的維度。還有一些演算法,例如LSH,將SIFT的特徵描述子轉換為一個二值的碼串,然後這個碼串用漢明距離進行特徵點之間的匹配。這種方法將大大提高特徵之間的匹配,因為漢明距離的計算可以用異或操作然後計算二進位制位數來實現,在現代計算機結構中很方便。下面來們提取一種二值碼串的特徵描述子。
BRIEF[1]應運而生,它提供了一種計算二值串的捷徑,而並不需要去計算一個類似於SIFT的特徵描述子。它需要先平滑影象,然後在特徵點周圍選擇一個Patch,在這個Patch內通過一種選定的方法來挑選出來$n_d$個點對。然後對於每一個點對$(p,q)$,我們來比較這兩個點的亮度值,如果$I(p)>I(q)$則這個點對生成了二值串中一個的值為1,如果$I(p)<I(q)$,則對應在二值串中的值為-1,否則為0。所有$n_d$個點對,都進行比較之間,我們就生成了一個$n_d$長的二進位制串。
對於$n_d$的選擇,我們可以設定為128,256或512,這三種引數在OpenCV中都有提供,但是OpenCV中預設的引數是256,這種情況下,非匹配點的漢明距離呈現均值為128比特徵的高斯分佈。一旦維數選定了,我們就可以用漢明距離來匹配這些描述子了。
值得注意的是,對於BRIEF,它僅僅是一種特徵描述符,它不提供提取特徵點的方法。所以,如果你必須使一種特徵點定位的方法,如FAST、SIFT、SURF等。這裡,我們將使用CenSurE方法來提取關鍵點,對BRIEF來說,CenSurE的表現比SURF特徵點稍好一些。
總體來說,BRIEF是一個效率很高的提取特徵描述子的方法,同時,它有著很好的識別率,但當影象發生很大的平面內的旋轉。
2. 關於點對的選擇
設我們在特徵點的鄰域塊大小為$S\times S$內選擇$n_d$個點對$(p,q)$,Calonder的實驗中測試了5種取樣方法:
1)在影象塊內平均取樣;
2)$p$和$q$都符合$(0,\frac{1}{25}S^2)$的高斯分佈;
3)$p$符合$(0,\frac{1}{25}S^2)$的高斯分佈,而$q$符合$(0,\frac{1}{100}S^2)$的高斯分佈;
4)在空間量化極座標下的離散位置隨機取樣
5)把$p$固定為$(0,0)$,$q$在周圍平均取樣
下面是上面5種取樣方法的結果示意圖。
2. OpenCV實現BRIEF
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/features2d/features2d.hpp> using namespace cv; int main(int argc, char** argv) { Mat img_1 = imread("box.png"); Mat img_2 = imread("box_in_scene.png"); // -- Step 1: Detect the keypoints using STAR Detector std::vector<KeyPoint> keypoints_1,keypoints_2; StarDetector detector; detector.detect(img_1, keypoints_1); detector.detect(img_2, keypoints_2); // -- Stpe 2: Calculate descriptors (feature vectors) BriefDescriptorExtractor brief; Mat descriptors_1, descriptors_2; brief.compute(img_1, keypoints_1, descriptors_1); brief.compute(img_2, keypoints_2, descriptors_2); //-- Step 3: Matching descriptor vectors with a brute force matcher BFMatcher matcher(NORM_HAMMING); std::vector<DMatch> mathces; matcher.match(descriptors_1, descriptors_2, mathces); // -- dwaw matches Mat img_mathes; drawMatches(img_1, keypoints_1, img_2, keypoints_2, mathces, img_mathes); // -- show imshow("Mathces", img_mathes); waitKey(0); return 0; }
[1] Michael Calonder, Vincent Lepetit, Christoph Strecha, and Pascal Fua, “BRIEF: Binary Robust Independent Elementary Features”, 11th European Conference on Computer Vision (ECCV), Heraklion, Crete. LNCS Springer, September 2010.