当我在OpenCV中使用BRISK进行特征检测和描述时,我遇到了性能问题。
基本上我尝试匹配从这张图片中得到的所有描述符:
针对我从图像数据库中获取的所有描述符,使用基于flann的匹配器和LSH算法以及用于特征检测和描述的BRISK。
我的图像数据库由242张图像组成。在这242张图像中,有三个图像对应于在上述"复合体中分别拍摄的每个物体。图像查询。
以下是用于BRISK检测的参数(默认的opencv参数): 阈值:30,八度值:4,模式比例:1.0。
使用最佳匹配技术进行flann匹配后(图像查询中的每个描述符与数据库描述符集中最近的邻域相关联),我的算法输出按匹配百分比排序的数据库图像列表。以下是四个第一个结果:
我使用ORB作为特征检测和描述来比较这些结果。以下是使用的参数:特征数量:2000,比例因子:1.2,金字塔等级数量:8。
以下是我得到的结果:
正如您所看到的,ORB的结果要好得多。首先,在数据库中的每个图像上检测到更多的关键点,并且匹配的百分比对于好的对象明显更好。此外,良好对象的匹配百分比与错误对象的匹配百分比之间的差距更为显着。
我想知道为什么BRISK探测器检测到的关键点比ORB探测器少得多。我已经做了不同的测试来弄清楚如何用BRISK探测器探测更多的关键点(降低阈值,减少八度数)。我确实可以检测到更多的关键点,但与ORB检测器的差异仍然非常重要。你知道为什么BRISK探测器有这样的行为吗?
我的OpenCV版本是2.4.8但我根据这些陈述尝试了2.4.4和2.4.9版本的BRISK检测部分:
http://code.opencv.org/issues/2491和BRISK feature detector detects zero keypoints没有任何改进。
我还尝试将ORB检测器与BRISK描述相结合。匹配结果优于第一种方法(完全BRISK),但比第二种方法(完整ORB)更差:
请注意,在方法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的一些问题,请告诉我。任何帮助将不胜感激:)。
答案 0 :(得分:8)
好的,我想出了如何从BRISK获得我期望的结果。 我在这里尝试了BRISK创建者的代码: https://github.com/calihem/mavhub/tree/master/thirdparty
以下是我得到的结果:
这些结果比我之前的结果要好得多。实际上,它们并不比使用ORB获得的特定查询图像更好。但是我尝试了其他查询图像,特别是更复杂的图像和BRISK优于ORB。
至少从2.4.4版本到当前版本2.4.9,opencv中的BRISK实现似乎存在问题。我认为这个bug应该很快修复,因为它已经报告给opencv社区(http://code.opencv.org/issues/2491)。
与此同时,我建议您使用BRISK创建者编写的代码,该代码效果很好;)。