一、BRIEF特征点描述算法简介
BRIEF是Binary Robust Independent Elementary Features的缩写。这个特征描述子是由EPFL的Calonder在ECCV2010上提出的。主要思路就是在特征点附近随机选取若干点对,将这些点对的灰度值的大小,组合成一个二进制串,并将这个二进制串作为该特征点的特征描述子。这种方法摈弃了利用区域灰度直方图描述特征点的传统方法,大大的加快了特征描述符建立的速度,同时也极大的降低了特征匹配的时间,所以它是一种非常快速的算法,可应用于满足实时性的系统。
需要注意的是BRIEF算法是特征点描述子算法,它是用于对已检测到的特征点进行描述的,所以其不涉及特征点的检测,我们常使用其它方法来进行特征点的检测,例如:FAST、SIFT、SURF或Harris等特征点检测算法。
二、BRIEF算法的具体步骤
(1)建立特征点的一个正方形邻域。
(2)对该邻域用σ=2的高斯核卷积,以消除一些噪声。这是因为该描述子随机性强,对噪声较为敏感。
(3)以一定的随机化算法生成点对< x,y>,若点x的亮度小于点y的亮度,则返回值1,否则返回0。
(4)重复第三步若干次(如256次),得到一个256位的二进制编码,即该特征点的描述子。
三、随机点对的选取
设我们在特征点的邻域块大小为S×S内选择nd个点对(p,q),Calonder的实验中测试了5种采样方法:
(1)在图像块内平均采样;
(2)p和q都符合(0 , 1/25 S2)(0 , 1/25 S2)的高斯分布;
(3)p符合(0,1/25 S2)(0,1/25 S2)的高斯分布,而q符合(0,1/100 S2)(0,1/100 S2)的高斯分布;
(4)在空间量化极坐标下的离散位置随机采样;
(5)把p固定为(0,0),q在周围平均采样。
下面是上面5种采样方法的结果示意图。
四、特征点匹配
对特征点进行匹配,这时计算两特征点描述子的Hamming距离。判断是否匹配的依据:经过大量实验数据测试,不匹配特征点的描述子的Hamming距离在128左右,匹配点对描述子的Hamming距离则远小于128。
注:Hamming距离:表示两个(相同长度)字对应位不同的数量。具体来说,就是对两个字符串进行异或运算,并统计结果为1的个数,那么这个数就是汉明距离。
总的来说,特征配对就是利用汉明距离来进行相关判断:
(1)两个特征编码对应bit位上相同元素的个数小于128的,一定不是配对的。
(2)一幅图上特征点与另一幅图上特征编码对应bit位上相同元素的个数最多的特征点配成一对。
五、OpenCV中的实例
1、代码
#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("1.png");
Mat img_2 = imread("2.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;
}
2、运行结果