BRIEF描述子介绍及其opencv3实现

来源:互联网 发布:外贸crm软件 编辑:程序博客网 时间:2024/05/18 01:25

引出

SIFT特征采用了128维的特征描述子,由于描述子用的浮点数,所以它将会占用512 bytes的空间。类似地,对于SURF特征,常见的是64维的描述子,它也将占用256bytes的空间。如果一幅图像中有1000个特征点(不要惊讶,这是很正常的事),那么SIFT或SURF特征描述子将占用大量的内存空间,对于那些资源紧张的应用,尤其是嵌入式的应用,这样的特征描述子显然是不可行的。而且,越占有越大的空间,意味着越长的匹配时间。

但是实际上SFIT或SURF的特征描述子中,并不是所有维都在匹配中有着实质性的作用。我们可以用PCA、LDA等特征降维的方法来压缩特征描述子的维度。还有一些算法,例如LSH,将SIFT的特征描述子转换为一个二值的码串,然后这个码串用汉明距离进行特征点之间的匹配。这种方法将大大提高特征之间的匹配,因为汉明距离的计算可以用异或操作然后计算二进制位数来实现,在现代计算机结构中很方便。

BRIEF特征描述子应运而生,它提供了一种计算二值串的捷径,而并不需要去计算一个类似于SIFT的特征描述子。 BRIEF算法的核心思想是在关键点P的周围以一定的方式选取N个点对,然后把这N个点对的边角结果组合起来作为该关键点的描述子。

介绍

BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度直方图描述特征点的传统方法,大大的加快了特征描述符建立的速度,同时也极大的降低了特征匹配的时间,是一种非常快速,很有潜力的算法。

BRIEF是一种二进制描述子,其描述向量由许多0和1组成。这里的0和1编码了关键点附近的两个像素(比如p和q)的大小关系:如果p比q小,取1;反之取0。关于p和q个数,作者在论文取了128,256和512。

这里写图片描述

至于p和q的选取,作者在论文给了以下五种方式,大体上都是按照某种概率分布,随机均匀地选择p和q的位置。

这里写图片描述

总体来说,BRIEF是一个效率很高的提取特征描述子的方法,同时,它有着很好的识别率,但当图像发生很大的平面内的旋转,识别率会大打折扣。这是因为原始的BRIEF描述子不具备旋转不变性,因此在图像发生旋转时容易发生丢失。

算法优劣

优点

1.计算速度快,可在SLAM中达到实时计算
2.二进制描述子存储和匹配更加方便,匹配质量较高

缺点

1.对噪声敏感(因为二进制编码是通过比较具体像素值来判定的)
2.不具备旋转不变性
3.不具备尺度不变性

Opencv3实现BRIEF

#include<opencv2/opencv.hpp>#include <opencv2/xfeatures2d.hpp>using namespace std;using namespace cv;using namespace cv::xfeatures2d;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;}