首页 文章

从功能关键点手动在OpenCV中进行成对匹配

提问于
浏览
8

这是我的问题 . 我在多个图像上手动提取了SURF的关键点特征 . 但我也已经知道哪一对要匹配 . 问题是,我正在尝试创建我的匹配对,但我不明白如何 . 我试着通过查看代码,但这是一个烂摊子 .

现在,我知道features.descriptors(一个矩阵)的大小与关键点的数量相同(另一个维度为1) . 在代码中,为了检测匹配对,它只使用描述符,因此它比较行(或列,我不确定)或两个描述符矩阵,并确定是否有任何共同点 .

但就我而言,我已经知道图像1中的关键点i与图像2中的关键点j之间存在匹配 . 如何将其描述为MatchesInfo值 . 特别是std :: vector <cv :: DMatch>类型的元素匹配 .

编辑:所以,为此,我不需要使用任何匹配器或类似的东西 . 我知道哪些对在一起!

1 回答

  • 6

    如果我理解你的问题是正确的,我假设您希望 std::vector<cv::DMatch> 中的关键点匹配,以便使用OpenCV cv::drawMatches 绘制它们或使用某些类似的OpenCV函数 . 由于我最近也在匹配"by hand",这里是我的代码,用于绘制最初包含在 std::vector<std::pair <int, int> > aMatches 中的任意匹配,并在窗口中显示它们:

    const cv::Mat& pic1 = img_1_var;
    const cv::Mat& pic2 = img_2_var;
    const std::vector <cv::KeyPoint> &feats1 = img_1_feats;
    const std::vector <cv::KeyPoint> &feats2 = img_2_feats;
        // you of course can work directly with original objects
        // but for drawing you only need const references to
        // images & their corresponding extracted feats
    
    std::vector <std::pair <int, int> > aMatches;
        // fill aMatches manually - one entry is a pair consisting of
        //      (index_in_img_1_feats, index_in_img_2_feats)
    
    
    // the next code draws the matches:
    std::vector <cv::DMatch> matches;
    matches.reserve((int)aMatches.size());
    
    for (int i=0; i < (int)aMatches.size(); ++i)
        matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second,
                          std::numeric_limits<float>::max()));
    
    cv::Mat output;
    
    cv::drawMatches(pic1, feats1, pic2, feats2, matches, output);
    
    cv::namedWindow("Match", 0);
    cv::setWindowProperty("Match", CV_WINDOW_FULLSCREEN, 1);
    cv::imshow("Match", output);    
    cv::waitKey();
    cv::destroyWindow("Match");
    

    或者,如果您需要有关匹配的更全面信息,而不是绘图,那么您可能还需要将匹配之间的距离设置为适当的值 . 例如 . 如果要使用L2距离计算距离,则应替换以下行:

    for (int i=0; i < (int)aMatches.size(); ++i)
        matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second,
                          std::numeric_limits<float>::max()));
    

    用此(请注意,为此还需要引用特征描述符向量):

    cv::L2<float> cmp;
    
    const std::vector <std::vector <float> > &desc1 = img_1_feats_descriptors;
    const std::vector <std::vector <float> > &desc2 = img_2_feats_descriptors;
    
    for (int i=0; i < (int)aMatches.size(); ++i){
        float *firstFeat = &desc1[aMatches[i].first];
        float *secondFeat = &desc2[aMatches[i].second];
        float distance = cmp(firstFeat, secondFeat, firstFeat->size());
        matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second,
                          distance));
    }
    

    请注意,在最后一个片段中, descX[i]featsX[i] 的描述符,内部向量的每个元素都是描述符向量的一个组成部分 . 另请注意,所有描述符向量应具有相同的维度 .

相关问题