OpenCV SURF类错误

时间:2014-12-18 07:26:07

标签: c++ opencv computer-vision surf

我发现OpenCV的新课程SURFSurfFeatureDetector的行为不同。怎么了?

有两张照片的例子:

.................................. img_1 ........ .................................................. ........... img_2 .................................. 。

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} },

1 个答案:

答案 0 :(得分:2)

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

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

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

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

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