5

在 OpenCV 中使用 BRISK 进行特征检测和描述时遇到性能问题。

基本上,我尝试匹配从这张图片中获得的所有描述符:在此处输入图像描述

针对我从图像数据库中获得的所有描述符,使用基于 flann 的匹配器和 LSH 算法和 BRISK 进行特征检测和描述。

我的图像数据库由 242 张图像组成。在这 242 张图像中,有三张图像对应于上述“复杂”图像查询中分别拍摄的每个对象。

以下是用于 BRISK 检测的参数(默认 opencv 参数):Treshold:30,Octaves:4,Pattern scale:1.0。

在使用最佳匹配技术进行 flann 匹配后(图像查询中的每个描述符都与其在数据库描述符集中的最近邻域相关联),我的算法输出按匹配百分比排序的数据库图像列表。以下是前四个结果:

  1. 数据库中螺栓对应的图像:4 个匹配/15 个检测到的关键点 => 匹配百分比:26.7%。
  2. 与数据库中的瓶子对应的图像有 4 个匹配 / 15 个检测到的关键点 => 匹配百分比:26.7%。
  3. 数据库中螺栓对应的图像有 10 个匹配 / 59 个检测到的关键点 => 匹配百分比:16.9%。
  4. 对应于图像查询中不存在的对象的图像:1 个匹配/16 个检测到的关键点 => 匹配百分比:16.7%。

我使用 ORB 作为特征检测和描述来比较这个结果。以下是使用的参数:特征数:2000,比例因子:1.2,金字塔级别数:8。

这是我得到的结果:

  1. 数据库中螺栓对应的图像:576 个匹配/752 个检测到的关键点 => 匹配百分比:76.6%。
  2. 与数据库中的瓶子对应的图像有 111 个匹配 / 189 个检测到的关键点 => 匹配百分比:58.7%。
  3. 数据库中笔对应的图像有 124 个匹配 / 293 个检测到的关键点 => 匹配百分比:42.3%。
  4. 对应于图像查询中不存在的对象的图像:2 个匹配/66 个检测到的关键点 => 匹配百分比:3%。

如您所见,使用 ORB 的结果要好得多。首先,在数据库中的每张图像上检测到更多的关键点,并且对于好的对象,匹配的百分比明显更好。此外,好对象的匹配百分比与错误对象的匹配百分比之间的差距更为显着。

我想知道为什么 BRISK 检测器检测到的关键点比 ORB 检测器少得多。我进行了不同的测试,以弄清楚如何使用 BRISK 检测器检测更多关键点(降低阈值,降低八度数)。我确实可以检测到更多的关键点,但与 ORB 检测器的区别仍然非常重要。你知道为什么 BRISK 检测器会有这样的行为吗?

我的 OpenCV 版本是 2.4.8,但我根据这些陈述尝试了 2.4.4 和 2.4.9 版本的 BRISK 检测部分:

http://code.opencv.org/issues/2491BRISK 特征检测器在没有改进的情况下检测到零关键点。

我还尝试将 ORB 检测器与 BRISK 描述结合起来。匹配结果优于第一种方法(完全 BRISK),但比第二种方法(完全 ORB)差:

  1. 数据库中螺栓对应的图像:529 个匹配/708 个检测到的关键点 => 匹配百分比:74.7%。
  2. 与数据库中的瓶子对应的图像有 69 个匹配 / 134 个检测到的关键点 => 匹配百分比:51.5%。
  3. 数据库中与笔对应的图像已匹配 93 / 247 个检测到的关键点 => 匹配百分比:37.6%。
  4. 对应于图像查询中不存在的对象的图像:5 个匹配/50 个检测到的关键点 => 匹配百分比:10%。

请注意,在方法 2 和方法 3 中,在每个图像上检测到的关键点数量并不相同。实际上,当我在测试图像(这里是螺栓的图像)上运行此代码时:

// BRISK parameters
int Threshl=30;
int Octaves=4;
float PatternScales=1.0f;

// ORB parameters
int nFeatures=2000;
float scaleFactor=1.2f;
int nLevels=8;


BRISK  BRISKD(Threshl, Octaves, PatternScales);
ORB ORBD(nFeatures, scaleFactor, nLevels);

vector<KeyPoint> kpts;
Mat descriptors;

Mat img = cv::imread("Path to the bolt image", IMREAD_GRAYSCALE );
ORBD.detect(img,kpts); // Number of keypoints detected = 752
BRISKD.compute(img, kpts, descriptors); // Number of descriptors = 708

BRISK 似乎没有计算描述符中所有检测到的关键点(ORB 检测器检测到的 752 个关键点 => BRISK 描述符计算的 708 个描述符)。

然而,即使 ORB 检测到的所有关键点都不是在 BRISK 描述符中计算的。从这些结果看来,BRISK 不是比 ORB 更好地描述一个关键点吗?如果我错了,请纠正我,但我很确定应该是相反的......

如果你们有任何可以帮助我理解我的结果的元素,或者如果你已经在 OpenCV 中遇到了 BRISK 的一些问题,请告诉我。任何帮助将不胜感激 :)。

4

1 回答 1

8

好的,我想出了如何从 BRISK 获得我期望的结果。我在这里尝试了 BRISK 创建者的代码: https ://github.com/calihem/mavhub/tree/master/thirdparty

这是我得到的结果:

  1. 数据库中螺栓对应的图像:149 个匹配 / 288 个检测到的关键点 => 匹配百分比:51.7%
  2. 数据库中与瓶子对应的图像有 27 个匹配 / 57 个检测到的关键点 => 匹配百分比:47.4%
  3. 数据库中笔对应的图像有 38 个匹配 / 101 个检测到的关键点 => 匹配百分比:37.6%
  4. 对应于图像查询中不存在的对象的图像:5 个匹配/76 个检测到的关键点 => 匹配百分比:6.6%

这些结果比我以前的结果要好得多。实际上,对于这个特定的查询图像,它们并不比使用 ORB 获得的更好。但是我尝试了其他查询图像,特别是更复杂的图像,并且 BRISK 优于 ORB。

至少从 2.4.4 版本到当前版本 2.4.9,opencv 中的 BRISK 实现似乎存在问题。我认为这个错误应该很快得到修复,因为它已被报告给 opencv 社区(http://code.opencv.org/issues/2491)。

同时,我建议您使用由 BRISK 创建者编写的代码,效果很好;)。

于 2014-05-19T12:04:37.387 回答