OpenCV FREAK:快速视网膜关键点描述符

17
我正在开发一个涉及到 Freak 描述符的应用程序,该描述符刚刚在 OpenCV2.4.2 版本中发布。 documentation 中只有两个函数:
- 类构造函数 - 令人困惑的方法 selectPairs() 我想使用自己的检测器,然后调用 FREAK 描述符来传递检测到的关键点,但我不太清楚该类如何工作。
问题:
我是否严格需要使用 selectPairs()?仅通过调用 FREAK.compute() 就足够了吗?我真的不明白 selectPairs 的用途。
2个回答

18

我刚才翻了一下文章,看到在第4.2段中作者建立了一种方法来选择要评估其描述符中的接收场对,因为考虑所有可能的对太过繁琐。selectPairs() 函数可以让您重新计算这个接收场对的集合。

接着阅读文档,他们指出原始文章中的确切段落。此外,文档中的一些注释告诉您已经有一个离线学习好的可以直接用于FREAK描述符的接收场对集合。所以至少一开始,您可以使用预先计算好的接收场对,并将您从方法中得到的关键点列表作为参数传递给FREAK.compute函数。

如果您的结果令人不满意,可以尝试原论文中使用的关键点选择方法(第2.1段),最终学习您自己的接收场对集合。


是的,我猜这就是那样的东西。我不知道的是,如果你有一个选择配对的算法,为什么需要使用关键点探测器。在论文中并不清楚。我正在开发一款与freak相结合的pyrFAST算法,看看会发生什么。 - Jav_Rock
1
我的理解是,给定一个关键点位置(例如使用pyrFAST),描述符是在该关键点周围的小邻域中计算出对点对(!=关键点)之间差异的符号。如果您熟悉BRIEF,则这非常类似。但是FREAK有一种方法,它采样邻域中受人类视觉系统启发的位置。 - remi
好的,我现在更明白了。是的,我知道BRIEF(它会在随机位置采样)和BRISK(它会在圆形区域内采样)。FREAK也会在圆形区域内采样,但是它们是冗余的,并且像视网膜一样粗到细。我没有注意到的是这是在关键点的邻域中完成的,这很重要。谢谢! - Jav_Rock
大家好,他们是如何计算出这些奇怪的图案的呢?我不知道他们用什么方程来计算每个圆的半径,平滑度的sigma等。有人知道如何创建这些图案吗(数学上每个层级的半径方程,sigma等)? - user570593
1
据我所知,该方程式未被书写,但是是参考论文中图形的直接翻译。在训练过程中,作者使用的检测器是AGAST,它类似于一个尺度敏感的FAST(如pyrFast)。更确切地说,AGAST是BRISK论文中使用的检测器,您可以在BRISK论文作者的网站上找到代码。 - sansuiso

16
#include "iostream"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "cv.h"
#include "highgui.h"
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/flann/flann.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <vector>


using namespace cv;
using namespace std;

int main()
{
    Mat image1,image2;
    image1 = imread("C:\\lena.jpg",0);
    image2 = imread("C:\\lena1.bmp",0);

    vector<KeyPoint> keypointsA,keypointsB;
    Mat descriptorsA,descriptorsB;

    std::vector<DMatch> matches;

    OrbFeatureDetector detector(400);

    FREAK extractor;

    BruteForceMatcher<Hamming> matcher;

    detector.detect(image1,keypointsA);
    detector.detect(image2,keypointsB);

    extractor.compute(image1,keypointsA,descriptorsA);
    extractor.compute(image2,keypointsB,descriptorsB);

    matcher.match(descriptorsA, descriptorsB, matches);

    int nofmatches = 30;
    nth_element(matches.begin(),matches.begin()+nofmatches,matches.end());
    matches.erase(matches.begin()+nofmatches+1,matches.end());

    Mat imgMatch;
    drawMatches(image1, keypointsA, image2, keypointsB, matches, imgMatch);

    imshow("matches", imgMatch);
    waitKey(0);

    return 0;
}

这是一个简单的应用程序,用于在两张图片中匹配点。我使用了ORB算法来检测关键点,并使用FREAK算法对这些关键点进行描述。然后使用暴力匹配算法来检测两张图片中对应的点。我选择了最佳匹配的前30个点。希望这能对你有所帮助...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接