【问题标题】:OpenCV SURF class ErrorOpenCV SURF 类错误
【发布时间】:2014-12-18 07:26:07
【问题描述】:

我发现 OpenCV 的新类 SURFSurfFeatureDetector 的行为不同。它有什么问题?

两张图片的例子:

.......................img_1....... ..................................................... ....................img_2.......................

./a.out ./img_1.png ./img_2.png一样使用它

// STL
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
// C-Standard
#include <cstdio>
#include <ctime>
#include <cstdlib>
// OpenCV
#include <opencv2/opencv.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <opencv2/nonfree/nonfree.hpp>

void print(const std::string & filename, const std::vector<std::vector<cv::DMatch>> & vec) {
    FILE *file = fopen(filename.c_str(), "w");
    fprintf(file, "{\n");
    for(auto & i : vec)
        fprintf(file, "    { {%d,%d,%f}, {,%d,%d,%f} },\n",
                i[0].queryIdx, i[0].trainIdx, i[0].distance,
                i[1].queryIdx, i[1].trainIdx, i[1].distance);
    fprintf(file, "}\n");
    fclose(file);
}

void test1(const std::string & imgf_1, const std::string & imgf_2) {
    cv::Mat img_1;
    cv::Mat img_2;
    std::vector<cv::KeyPoint> keypoints_1, keypoints_2;
    cv::Mat descriptors_1, descriptors_2;
    std::vector<std::vector<cv::DMatch>> matches;

    img_1 = cv::imread(imgf_1);
    img_2 = cv::imread(imgf_2);
    int minhessin = 400;
    cv::SurfFeatureDetector detector(minhessin);
    cv::SurfDescriptorExtractor extractor;
    cv::BFMatcher bfMatcher(cv::NORM_L2);

    keypoints_1.clear(); keypoints_2.clear();
    detector.detect(img_1, keypoints_1);
    extractor.compute(img_1, keypoints_1, descriptors_1);
    detector.detect(img_2, keypoints_2);
    extractor.compute(img_2, keypoints_2, descriptors_2);
    matches.clear();
    bfMatcher.knnMatch(descriptors_1, descriptors_2, matches, 2);

    print("main_bak.log", matches);
}

void test2(const std::string & imgf_1, const std::string & imgf_2) {
    cv::Mat img_1;
    cv::Mat img_2;
    std::vector<cv::KeyPoint> keypoints_1, keypoints_2;
    cv::Mat descriptors_1, descriptors_2;
    std::vector<std::vector<cv::DMatch>> matches;

    img_1 = cv::imread(imgf_1);
    img_2 = cv::imread(imgf_2);
    const double hessianThreshold = 400;
    cv::SURF detector2(hessianThreshold);
    cv::BFMatcher bfMatcher(cv::NORM_L2);

    keypoints_1.clear(); keypoints_2.clear();
    detector2(img_1, cv::Mat(), keypoints_1, descriptors_1);
    detector2(img_2, cv::Mat(), keypoints_2, descriptors_2);
    matches.clear();
    bfMatcher.knnMatch(descriptors_1, descriptors_2, matches, 2);

    print("main.log", matches);
}

int main(int argc, char * argv[])
{
    if(argc < 3) {
        std::cout << "usage: " << argv[0] << " img_1 img_2" << std::endl;
        return 1;
    }
    test1(argv[1], argv[2]);
    test2(argv[1], argv[2]);

    return 0;
}

日志的标题 5 行显示在这里:

main_bak.log

{
    { {0,0,0.000787}, {,0,2,0.126846} },
    { {1,1,0.001695}, {,1,167,0.353709} },
    { {2,2,0.000860}, {,2,0,0.127105} },
    { {3,3,0.002939}, {,3,5,0.333215} },
    { {4,4,0.001360}, {,4,115,0.294008} },

main.log

{
    { {0,0,0.000900}, {,0,2,0.143810} },
    { {1,1,0.024048}, {,1,107,0.621702} },
    { {2,2,0.003646}, {,2,0,0.144049} },
    { {3,3,0.032238}, {,3,5,0.604136} },
    { {4,4,0.001449}, {,4,87,0.591502} },

【问题讨论】:

  • 不是一个真正的编程问题......也许算法参数的处理方式?
  • 我知道这不是编程问题。但是,距离从 '0.001695' 变为 '0.024048' 可能是由于一些问题。
  • 在函数test1中,声明extractor为cv::SurfDescriptorExtractor extractor(minHessian);
  • @sgarizvi 是的,你说得对。谢谢。请回答,以便我将您标记为最佳答案。

标签: c++ opencv computer-vision surf


【解决方案1】:

cv::SurfFeatureDetectorcv::SurfDescriptorExtractor 类是 cv::SURF 类的别名。结果的差异是由于以下原因:

在函数test1detectorextractor 中使用不同的参数初始化对象。 detector 使用 400minHessian 值,而提取器使用 opencv 实现定义的默认值。

在函数test2中,关键点检测和描述符计算是使用hessianThreshold值为400的单个cv::SURF对象完成的。

要在test1 中重现test2 的结果,请使用相同的参数初始化两个对象,如下所示:

int minhessin = 400;
cv::SurfFeatureDetector detector(minhessin);
cv::SurfDescriptorExtractor extractor(minHessian);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-26
    • 2015-03-12
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 2012-04-16
    • 2012-07-15
    • 1970-01-01
    相关资源
    最近更新 更多