SURF和ORB特征上的BoF描述符(BoF-SURF和BoF-ORB)






4.94/5 (12投票s)
一个基于OpenCV和C++,使用SURF和ORB特征的BoF特征描述符的实现。
引言
词袋模型 (Bag-Of-Feature, BoF) 是一种视觉特征描述符,可用于基于内容的图像或视频检索应用程序。 为了获得 BoF 描述符,我们需要从图像中提取特征。 此特征可以是任何内容,例如 SIFT(尺度不变特征变换)、SURF(加速鲁棒特征)和 ORB(定向 BRIEF)等。
在这个技巧中,提供了 BoF-SURF 和 BoF-ORB 的实现。 本文是在文章 "基于OpenCV的SIFT特征的词袋模型描述符 (BoF-SIFT)" 的读者要求下编写的,该文章详细描述了使用 SIFT 的词袋模型描述符。 本文仅包含为了将其应用于 BoF-SURF 和 BoF-ORB 而对原始代码所做的更改。 请参阅 原始文章 了解更多详情。
背景
SURF 代表加速鲁棒特征,它更像 SIFT,但计算速度更快。 SURF 算法从积分图像表示中获得最大收益,这有助于提高 SURF 的速度。 您可以从这篇 维基百科文章 中阅读更多关于 SURF 的信息。
ORB 代表定向 BRIEF,是 SIFT 和 SURF 的有效替代方案。 您可以从这篇研究论文 "ORB:SIFT 或 SURF 的有效替代方案" 中阅读更多关于 ORB 的信息。
Using the Code
使用 OpenCV,我们可以用几行代码实现 BoF-SURF 和 BoF-ORB。 确保您已安装 OpenCV 2.3 或更高版本以及 Visual Studio 2008 或更高版本。 OpenCV 版本是必须的,但您仍然可以毫无问题地使用其他 C++ 版本。
该代码有两个独立的区域,它们被编译并独立运行。 第一个区域用于获取特征词袋的集合,另一个区域用于获取给定图像/视频帧的 BoF 描述符。 您只需要运行一次代码的第一个区域。 创建词汇表后,您可以随时将其与代码的第二个区域一起使用。 修改以下代码行可以在这两个代码区域之间切换。
DICTIONARY_BUILD 1 // set DICTIONARY_BUILD to 1 for Step 1. 0 for step 2
SURF 特征提取
在字典构建部分,我们需要使用以下代码行提取 SURF 特征
int minHessian = 400; //Hessian Threshold
//Some code lines
SurfDescriptorExtractor detector(minHessian,4,2,false);
SurfDescriptorExtractor
构造函数需要最小 Hessian 阈值、八度音阶的数量、八度音阶层的数量、扩展描述符(描述符的维度是 128 还是 64)以及 SURF 是否为直立模式 (USURF)。
在描述符提取部分,使用与以下代码中相同的 SURF 提取器和 SURF 检测器
//create SURF feature point extracter
Ptr<FeatureDetector> detector(new SurfFeatureDetector(minHessian,4,2,false));
//create SURF descriptor extractor
Ptr<DescriptorExtractor> extractor(new SurfDescriptorExtractor(minHessian,4,2,false));
其他代码与 原始文章 中的 BoF-SIFT 相似。
ORB 特征提取
对于 ORB 特征的提取,使用了 OrbDescriptorExtractor
。 我们使用默认参数值创建检测器对象,如下面的代码所示
OrbDescriptorExtractor detector;
与其他特征不同,在使用 ORB 获取 BoF 词汇表文件时,由于类型不匹配问题,openCV 抱怨 openCV 核心库中的断言失败。 解决方法如下
//convert featuresUnclustered to type CV_32F
Mat featuresUnclusteredF(featuresUnclustered.rows,featuresUnclustered.cols,CV_32F);
featuresUnclustered.convertTo(featuresUnclusteredF,CV_32F);
//cluster the feature vectors
Mat dictionary=bowTrainer.cluster(featuresUnclusteredF);
为了获得 BoF 描述符,我们需要一个描述符匹配器。 在以前的情况下,使用最近邻技术。 这里我们使用 BruteForce-Hamming 描述符匹配器。 ORB 是一个二进制描述符,因此用于匹配的海明距离在效率和性能方面都更好。 我在这一步也遇到了类型问题。 因此,我使用了以下代码
//convert to 8bit unsigned format
Mat dictionary(dictionaryF.rows,dictionaryF.cols,CV_8U);
dictionaryF.convertTo(dictionary,CV_8U);
//create a matcher with BruteForce-Hamming distance
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");
ORB 的检测器和提取器创建如下面的代码所示
//create SURF feature point extracter
Ptr<FeatureDetector> detector(new OrbFeatureDetector());
//create SURF descriptor extractor
Ptr<DescriptorExtractor> extractor(new OrbDescriptorExtractor());
关注点
请在使用此代码进行研究时小心,因为我仅为了避免 openCV 核心库中发生的断言失败而对 Mat 对象使用了类型转换。 如果您可以重新检查确切的问题或 openCV 代码的正确期望,那就更好了。