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.