在 OpenCV 中使用 SURF 特征进行多个匹配的基本步骤与之前描述的单个匹配类似,但需要进行一些额外的处理以合并多个关键点的匹配结果。以下是实现多个匹配的一个简单示例:

步骤概述

  1. 读取图像:读取源图像和模板图像。
  2. 使用 SURF 检测特征点和描述符
  3. 使用 BFMatcher 匹配多个描述符
  4. 筛选和显示多个匹配

示例代码

#include <opencv2/opencv.hpp>  
#include <opencv2/xfeatures2d.hpp>  
#include <iostream>  

int main() {  
    // 读取源图像和模板图像  
    cv::Mat img_source = cv::imread("source.jpg");  
    cv::Mat img_template = cv::imread("template.jpg");  
    if (img_source.empty() || img_template.empty()) {  
        std::cerr << "Could not open or find the images!" << std::endl;  
        return -1;  
    }  

    // 转换为灰度图  
    cv::Mat gray_source, gray_template;  
    cv::cvtColor(img_source, gray_source, cv::COLOR_BGR2GRAY);  
    cv::cvtColor(img_template, gray_template, cv::COLOR_BGR2GRAY);  

    // 创建 SURF 检测器  
    auto surf = cv::xfeatures2d::SURF::create();  

    // 检测并计算关键点和描述符  
    std::vector<cv::KeyPoint> keypoints_source, keypoints_template;  
    cv::Mat descriptors_source, descriptors_template;  
    surf->detectAndCompute(gray_source, cv::noArray(), keypoints_source, descriptors_source);  
    surf->detectAndCompute(gray_template, cv::noArray(), keypoints_template, descriptors_template);  

    // 使用 BFMatcher 进行匹配  
    cv::BFMatcher matcher(cv::NORM_L2);  
    std::vector<std::vector<cv::DMatch>> knn_matches;  
    matcher.knnMatch(descriptors_template, descriptors_source, knn_matches, 2);  

    // 筛选好的匹配  
    const float ratio_thresh = 0.75f;  
    std::vector<cv::DMatch> good_matches;  
    for (size_t i = 0; i < knn_matches.size(); i++) {  
        if (knn_matches[i][0].distance < ratio_thresh * knn_matches[i][1].distance) {  
            good_matches.push_back(knn_matches[i][0]);  
        }  
    }  

    // 显示匹配结果  
    cv::Mat img_matches;  
    cv::drawMatches(img_template, keypoints_template, img_source, keypoints_source, good_matches, img_matches);  
    cv::imshow("Good Matches", img_matches);  
    cv::waitKey(0);  

    return 0;  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.

代码解释

  1. 图像读取:读取源图像和模板图像,确保成功读取。
  2. 转为灰度:将彩色图像转换为灰度图。
  3. 特征检测与描述:使用 SURF::create() 创建 SURF 对象,检测关键点并计算描述符。
  4. KNN 匹配:使用 knnMatch 进行 K 最近邻匹配,得到每个描述符的前两个匹配结果。
  5. 比率测试:使用比率测试来筛选好的匹配点,确保匹配的可靠性。
  6. 结果显示:绘制匹配的关键点并显示结果