📜  cv::Dmatch 使用 (1)

📅  最后修改于: 2023-12-03 15:30:13.748000             🧑  作者: Mango

cv::DMatch

cv::DMatch 是一个OpenCV中用于描述特征匹配的简单结构体。它包含了与每个匹配相关的三个属性:queryIdx, trainIdx和distance。

  • queryIdx:查询图像中特征的索引。
  • trainIdx:训练图像中特征的索引。
  • distance:两个特征描述子之间的距离或相似度。

cv::DMatch 允许将特定的查询和训练图像中的特征进行匹配。这在计算机视觉领域中常用于目标检测、图像配准、三维重建等等。

基本用法

可以通过简单的代码来演示使用 cv::DMatch 进行特征匹配。以下是一个使用 cv::DMatch 的匹配示例:

#include <opencv2/opencv.hpp>
#include <vector>

int main()
{
    cv::Mat img1 = cv::imread("image1.png");
    cv::Mat img2 = cv::imread("image2.png");

    cv::Ptr<cv::FeatureDetector> detector;
    cv::Ptr<cv::DescriptorExtractor> extractor;

    detector = cv::ORB::create();
    extractor = cv::ORB::create();

    std::vector<cv::KeyPoint> keypoints1, keypoints2;
    detector->detect(img1, keypoints1);
    detector->detect(img2, keypoints2);

    cv::Mat descriptors1, descriptors2;
    extractor->compute(img1, keypoints1, descriptors1);
    extractor->compute(img2, keypoints2, descriptors2);

    cv::BFMatcher matcher(cv::NORM_HAMMING);

    std::vector<cv::DMatch> matches;
    matcher.match(descriptors1, descriptors2, matches);

    cv::waitKey(0);

    return 0;
}

在此示例中,我们使用ORB算法来检测关键点和计算特征描述符。然后使用 cv::BFMatcher 匹配这些描述符。匹配后,将生成一组 cv::DMatch 对象,每个对象都表示两个特征之间的匹配。

匹配策略

OpenCV提供了多种匹配策略,包括暴力匹配、K邻近匹配和FLANN匹配等。在此我们介绍几种常用的匹配算法:

暴力匹配

暴力匹配是最简单的匹配策略之一。它计算每个查询描述符和每个训练描述符之间的距离,然后根据距离进行匹配。以下是使用暴力匹配算法的示例:

cv::BFMatcher matcher(cv::NORM_L2);
matcher.match(descriptors1, descriptors2, matches);

在此示例中,使用了 cv::BFMatchercv::NORM_L2 作为查询描述符和训练描述符之间距离的计算方式。

K邻近匹配

与暴力匹配不同,K邻近匹配允许匹配不止一个查询特征描述符。对于每个查询描述符,它将返回前K个训练描述符,这些描述符与查询描述符最相似(距离最短)。以下是使用K邻近匹配算法的示例:

cv::BFMatcher matcher(cv::NORM_L2);
std::vector<std::vector<cv::DMatch>> knn_matches;
matcher.knnMatch(descriptors1, descriptors2, knn_matches, 2);

在此示例中, knn_matches 是一个大小为 descriptors1.size() 的向量,每个元素都是一个大小为2的 std::vector<cv::DMatch>

FLANN匹配

FLANN(Fast Library for Approximate Nearest Neighbors)是一种高效的快速最近邻搜索算法,它可以在大型数据集上处理高维数据。以下是使用FLANN匹配算法的示例:

cv::FlannBasedMatcher matcher;
matcher.match(descriptors1, descriptors2, matches);

在此示例中,我们使用了 cv::FlannBasedMatcher 实现了匹配。FLANN可以处理多个查询和训练特征描述符的情况,因此不像暴力匹配那样一一进行计算,而是使用一种更高效的算法。