OpenCV - 将FLANN与ORB描述符一起使用以匹配要素

San*_*Gil 4 c++ opencv orb flann feature-descriptor

我正在使用OpenCV 3.2

我试图使用FLANN以比蛮力更快的方式匹配功能描述符.

// Ratio to the second neighbor to consider a good match.
#define RATIO    0.75

void matchFeatures(const cv::Mat &query, const cv::Mat &target,
                   std::vector<cv::DMatch> &goodMatches) {
    std::vector<std::vector<cv::DMatch>> matches;
    cv::Ptr<cv::FlannBasedMatcher> matcher = cv::FlannBasedMatcher::create();
    // Find 2 best matches for each descriptor to make later the second neighbor test.
    matcher->knnMatch(query, target, matches, 2);
    // Second neighbor ratio test.
    for (unsigned int i = 0; i < matches.size(); ++i) {
        if (matches[i][0].distance < matches[i][1].distance * RATIO)
            goodMatches.push_back(matches[i][0]);
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码使用SURF和SIFT描述符,但不使用ORB.

OpenCV Error: Unsupported format or combination of formats (type=0) in buildIndex
Run Code Online (Sandbox Code Playgroud)

正如在这里所说,FLANN需要描述符为CV_32F类型,因此我们需要转换它们.

if (query.type() != CV_32F) query.convertTo(query, CV_32F);
if (target.type() != CV_32F) target.convertTo(target, CV_32F);
Run Code Online (Sandbox Code Playgroud)

但是,这个假定的修复程序在convertTo函数中返回了另一个错误.

OpenCV Error: Assertion failed (!fixedType() || ((Mat*)obj)->type() == mtype) in create
Run Code Online (Sandbox Code Playgroud)

这个断言在opencv/modules/core/src/matrix.cpp文件第2277行.

发生了什么?


用于复制问题的代码.

#include <opencv2/opencv.hpp>

int main(int argc, char **argv) {
    // Read both images.
    cv::Mat image1 = cv::imread(argv[1], cv::IMREAD_GRAYSCALE);
    if (image1.empty()) {
        std::cerr << "Couldn't read image in " << argv[1] << std::endl;
        return 1;
    }
    cv::Mat image2 = cv::imread(argv[2], cv::IMREAD_GRAYSCALE);
    if (image2.empty()) {
        std::cerr << "Couldn't read image in " << argv[2] << std::endl;
        return 1;
    }
    // Detect the keyPoints and compute its descriptors using ORB Detector.
    std::vector<cv::KeyPoint> keyPoints1, keyPoints2;
    cv::Mat descriptors1, descriptors2;
    cv::Ptr<cv::ORB> detector = cv::ORB::create();
    detector->detectAndCompute(image1, cv::Mat(), keyPoints1, descriptors1);
    detector->detectAndCompute(image2, cv::Mat(), keyPoints2, descriptors2);
    // Match features.
    std::vector<cv::DMatch> matches;
    matchFeatures(descriptors1, descriptors2, matches);
    // Draw matches.
    cv::Mat image_matches;
    cv::drawMatches(image1, keyPoints1, image2, keyPoints2, matches, image_matches);
    cv::imshow("Matches", image_matches);
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*cka 8

你有没有调整FLANN参数?

摘自http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_feature2d/py_matcher/py_matcher.html

使用ORB时,您可以传递以下内容.根据文档推荐使用注释值,但在某些情况下不会提供所需的结果.其他价值很好:

index_params = dict(algorithm = FLANN_INDEX_LSH,table_number = 6,#12 key_size = 12,#20 multi_probe_level = 1)#2

你可以将它转换为C++ api吗?

根据评论,C++的方式是:

cv::FlannBasedMatcher matcher = cv::FlannBasedMatcher(cv::makePtr<cv::flann::LshIndexParams>(12, 20, 2));
Run Code Online (Sandbox Code Playgroud)

  • 真的很有效.调用是`cv :: FlannBasedMatcher matcher = cv :: FlannBasedMatcher(cv :: makePtr <cv :: flann :: LshIndexParams>(12,20,2));` (4认同)
  • 另外,并非所有匹配项都使用ORB和FLANN进行对应(可能与其他描述符一起发生,但目前还不行)。然后,在第二个邻居比率测试中,我添加了一个安全条件“ if(matches [i] .size()&gt; = 2)”。 (2认同)
  • 可能值得一提的是`FLANN_INDEX_LSH = 6`。 (2认同)

Nir*_*mal 6

二进制字符串描述符- ORB、BRIEF、BRISK、FREAK、AKAZE 等。

浮点描述符- SIFT、SURF、GLOH 等。


二进制描述符的特征匹配可以通过比较它们的汉明距离而不是用于浮点描述符的欧几里德距离来有效地完成。

要比较 OpenCV 中的二进制描述符,请使用FLANN + LSH 索引Brute Force + Hamming distance

http://answers.opencv.org/question/59996/flann-error-in-opencv-3/

默认情况下,FlannBasedMatcher 用作具有 L2 规范的 KDTreeIndex。这就是为什么它可以很好地与 SIFT/SURF 描述符配合使用并为 ORB 描述符抛出异常的原因。

二元特征和局部敏感哈希(LSH)

二进制和浮点描述符之间的性能比较