2012-03-21 78 views
0

我在使用OpenCV中的SIFT描述符实现时有点困惑。使用SIFT描述符的OpenCV(C++)增加了检测到的功能数量?

我想测试各种特征检测器+描述符的计算方法,所以我用的cv::FeatureDetectorcv::DescriptorExtractor接口,这让我简单地不同的检测方法和描述符之间改变的组合。

当调用cv::DescriptorExtractor::compute(...)(变体的单个图像),该文件说,有可能给该算法下降如果无法计算其描述关键点的数量,我了解为什么这样做。

但是,发生在我身上的是描述符计算后的关键点实际数量增加了。显然是这样的,我并没有试图阻止它的发生,我只是希望能够解释为什么(只是一种直观的描述会很酷,尽管我更赞赏那些)。

我在实际的OpenCV上没有任何代码(只是设置了一些本地的非OpenCV标志)的包装层上有层,所以这里是OpenCV代码在底部被调用:

cv::Ptr<cv::FeatureDetector> dect = cv::FeatureDetector::create("MSER"); 
cv::Mat input = cv::imread("someImg.ppm", 0); 
std::vector<cv::KeyPoint> keypoints; 
dect->detect(input, keypoints); 

cv::Ptr<cv::DescriptorExtractor>deEx=cv::DescriptorCalculator::create("SIFT"); 

std::cout << "before computing, feats size " << keypoints.size() << std::endl; 
// code to print out 10 features 

cv::Mat desc; 
deEx->compute(input, keypoints, desc); 

std::cout << "after computing, feats size " << keypoints.size() << std::endl; 
// code to print out 10 features 

我之前打印出来的前10个关键点和描述符的计算后,所以这里有一些具体的数字为例:

before computing, feats size 379 
feat[0]: 10.7584 39.9262 176.526 0 12.5396 
feat[1]: 48.2209 207.904 275.091 0 11.1319 
feat[2]: 160.894 313.781 170.278 0 9.63786 
feat[3]: 166.061 239.115 158.33 0 19.5027 
feat[4]: 150.043 233.088 171.887 0 11.9569 
feat[5]: 262.323 322.173 188.103 0 8.65429 
feat[6]: 189.501 183.462 177.396 0 12.3069 
feat[7]: 218.135 253.027 171.763 0 123.069 
feat[8]: 234.508 353.236 173.281 0 11.8375 
feat[9]: 234.404 394.079 176.23 0 8.99652 
after computing, feats size 463 
feat[0]: 10.7584 39.9262 13.1313 0 12.5396 
feat[1]: 48.2209 207.904 69.0472 0 11.1319 
feat[2]: 48.2209 207.904 107.438 0 11.1319 
feat[3]: 160.894 313.781 9.57937 0 9.63786 
feat[4]: 166.061 239.115 166.144 0 19.5027 
feat[5]: 150.043 233.088 78.8696 0 11.9569 
feat[6]: 262.323 322.173 167.259 0 8.65429 
feat[7]: 189.501 183.462 -1.49394 0 12.3069 
feat[8]: 218.135 253.027 -117.067 3 123.069 
feat[9]: 218.135 253.027 7.44055 3 123.069 

我从这个例子可以看出,原始的​​和feat[7]已经跨越了每两个新的关键点,但我看不出有任何合乎逻辑的解释为compute方法,这样做:(

我这里给出的是使用MSER检测关键点的打印输出,然后尝试计算SIFT描述,但同样增加大小也与STARSURFSIFT发生(即DoG)关键点检测。我没有尝试将描述符更改为其他内容,但如果有人认为它与问题相关,我会尝试并在我的问题中对其进行编辑。

+0

你可以添加你使用的部分代码吗?了解参数将很有用。 – Alex 2012-03-21 11:32:29

+0

呃......我实际上是在围绕OpenCV代码的封装进行封装,但是我会尝试挖掘实际的5行代码,它们将完成所有工作并编辑它。 – penelope 2012-03-21 14:45:34

回答

2

看起来像是由于OpenCV使用Rob Hess的SIFT实现,它有时会以多于一个主导方向复制关键点。

环顾OpenCV报告的错误做了诡计,问题报告为here

这不是一个错误,行为没有在新版本中得到纠正,而是只是记录在案。由于我有义务使用我现在正在使用的OpenCV版本(v2.1),因此在我看来newer documentation还没有发生其他行为,因为old one中描述的行为对我而言意义重大。

5

首先,您可以在documentationcv::DescriptorExtractor::compute中看到std::vector<cv::Keypoints>参数,其中non const。这意味着这个矢量可以通过cv::DescriptorExtractor::compute进行修改。 实际上,KeyPointsFilter::runByImageBorderKeyPointsFilter::runByKeypointSize(两个non-const函数)将应用于该向量,并将删除无法计算描述符的关键点。不会重新提取关键点。 您应该张贴您用于进一步诊断的几行代码。

-

好了,我终于找到发生问题:cv::SiftDescriptorExtractor::compute方法调用SIFT::operator()这(重新)计算的功能定位,并与几个主要的方向重复的点。 解决方案可能会将descriptorParams.recalculateAngles更改为false。

+0

我知道为什么':: compute'函数允许改变'std :: vector '和'non const'的含义。他们在文档中给出的原因是(和我引用)“关键点,描述符无法计算的关键点被删除。”移除是可以的。但是当我的关键点完成这个过程时,其中有*更多*,而不是*更少*,这是我无法理解的。我发布了一些真实代码,以更好地理解打印输出的内容。 – penelope 2012-03-21 15:00:31

+0

我想清楚了解它是否完全了解您的问题。没有代码,很难诊断。我尝试了你编辑的代码,并且改变了其他类型的DesciptorExtractor。看来只有Sift描述符才会出现问题。 – Eric 2012-03-21 16:33:31

+0

是的,我已经给出了自己的答案,链接到新旧文档以及报告问题的页面。我之所以没有发布代码,是因为我更感兴趣的是为什么发生这种情况(以何种方式提取SIFT描述符增加了关键点的数量)比在代码中发生的确切点更为重要。 – penelope 2012-03-22 08:02:55

0

这是不是一个错误,而是由设计:

SIFT在同一位置不同方向返回多个兴趣点,如果没有明确单一的主方向。通常,估计最多三个(取决于实际图像补丁)方向。