0

我在descriptor_extractor_matcher.cpp示例中使用以下代码来计算img1的描述符(Mat descriptors01),将其写入我的磁盘并加载回来(Mat descriptors1)。(关键点的步骤相同,但代码几乎相同......)

    Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create( argv[2] );

...

Mat descriptors01;
descriptorExtractor->compute( img1, keypoints1, descriptors01 ); // compute descriptors

FileStorage storage("test.yml", FileStorage::WRITE);             //save it to disc
storage << "blub" << descriptors01;
storage.release();

Mat descriptors1;
FileStorage storage1("test.yml", FileStorage::READ);            // load it again
storage1["blub"] >> descriptors1;
storage1.release();

计算和使用图像 2 的关键点和描述符,无需保存和加载。

我仅使用图像 1 的加载数据(关键点和描述符)进行匹配,因此对于描述符:描述符 1。

现在是这样的:如果我比较案例
A) 使用上面的代码进行计算、存储和加载;
B)仅使用加载的数据(不计算并再次存储)

对于匹配,我得到不同的结果,正如您在关键点以及匹配描述符的图片中看到的那样。我本来期望没有差异......我在这里错过了什么?我必须比较 2 个图像,并且不能将图像与一组存储的关键点及其描述符进行比较吗?

当然,顺便说一下,我对 [detectorType] [descriptorType] [matcherType] [matcherFilterType] [image1] [image2] [ransacReprojThreshold] 使用相同的值;)

非常感谢!

更新

似乎问题取决于描述符。使用加载的描述符适用于 SIFT 和 SURF,但不适用于 ORB 和其他。图像:案例 A 和 B 具有不同描述符的结果:

在此处输入图像描述

4

1 回答 1

0

尝试单独重复 A 或 B,看看结果是否相同。我怀疑他们不会,我之所以这么说是因为,#1 你感兴趣的对象的纹理很差,这会导致描述符很差。#2 两幅图像之间的视点变化很大,即使对于像 SIFT 这样最好的描述符,也会导致不可重复性问题。

现在,是如何解决这个可重复性问题的部分,#1 在描述符的范数上使用一些阈值,以便只使用非常强的特征进行匹配。#2 使用极线约束和 RANSAC 来过滤掉错误的匹配。我附上两张图片来展示过滤器如何极大地影响对应关系。 在此处输入图像描述 使用 SURF 查找两幅图像之间的对应关系(红-青色图中的两幅图像) 在此处输入图像描述 在使用 RANSAC 使用极线约束过滤图像之后。

随意评论并进一步讨论这个问题。:-)

于 2014-10-30T20:00:10.170 回答