使用FLANN进行特征点匹配

目标

在本教程中我们将涉及以下内容:

  • 使用 FlannBasedMatcher 接口以及函数 FLANN 实现快速高效匹配( 快速最近邻逼近搜索函数库(Fast Approximate Nearest Neighbor Search Library) )

理论

代码

这个教程的源代码如下所示。你还可以从 以下链接下载得到源代码

#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

void readme();

/** @function main */
int main( int argc, char** argv )
{
  if( argc != 3 )
  { readme(); return -1; }

  Mat img_1 = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
  Mat img_2 = imread( argv[2], CV_LOAD_IMAGE_GRAYSCALE );

  if( !img_1.data || !img_2.data )
  { std::cout<< " --(!) Error reading images " << std::endl; return -1; }

  //-- Step 1: Detect the keypoints using SURF Detector
  int minHessian = 400;

  SurfFeatureDetector detector( minHessian );

  std::vector<KeyPoint> keypoints_1, keypoints_2;

  detector.detect( img_1, keypoints_1 );
  detector.detect( img_2, keypoints_2 );

  //-- Step 2: Calculate descriptors (feature vectors)
  SurfDescriptorExtractor extractor;

  Mat descriptors_1, descriptors_2;

  extractor.compute( img_1, keypoints_1, descriptors_1 );
  extractor.compute( img_2, keypoints_2, descriptors_2 );

  //-- Step 3: Matching descriptor vectors using FLANN matcher
  FlannBasedMatcher matcher;
  std::vector< DMatch > matches;
  matcher.match( descriptors_1, descriptors_2, matches );

  double max_dist = 0; double min_dist = 100;

  //-- Quick calculation of max and min distances between keypoints
  for( int i = 0; i < descriptors_1.rows; i++ )
  { double dist = matches[i].distance;
    if( dist < min_dist ) min_dist = dist;
    if( dist > max_dist ) max_dist = dist;
  }

  printf("-- Max dist : %f \n", max_dist );
  printf("-- Min dist : %f \n", min_dist );

  //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist )
  //-- PS.- radiusMatch can also be used here.
  std::vector< DMatch > good_matches;

  for( int i = 0; i < descriptors_1.rows; i++ )
  { if( matches[i].distance < 2*min_dist )
    { good_matches.push_back( matches[i]); }
  }

  //-- Draw only "good" matches
  Mat img_matches;
  drawMatches( img_1, keypoints_1, img_2, keypoints_2,
               good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
               vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

  //-- Show detected matches
  imshow( "Good Matches", img_matches );

  for( int i = 0; i < good_matches.size(); i++ )
  { printf( "-- Good Match [%d] Keypoint 1: %d  -- Keypoint 2: %d  \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); }

  waitKey(0);

  return 0;
 }

 /** @function readme */
 void readme()
 { std::cout << " Usage: ./SURF_FlannMatcher <img1> <img2>" << std::endl; }

解释

结果

  1. 这里是第一张图特征点检测结果:

    ../../../../_images/Featur_FlannMatcher_Result.jpg
  2. 此外我们通过控制台输出FLANN匹配关键点结果:

    ../../../../_images/Feature_FlannMatcher_Keypoints_Result.jpg
from: http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html
FLANN(Fast Library for Approximate Nearest Neighbors)算法是一种用于在高维空间中进行快速最近邻搜索的算法。在计算机视觉中,FLANN算法常用于特征匹配,例如在图像配准、图像拼接和三维重建等领域。 特征匹配是指在两个或多个图像中找到相似的特征点,并将它们匹配起来。在匹配过程中,通常需要计算两个图像中每个特征点相似度,然后找到相似度最高的一对特征点。FLANN算法可以帮助我们快速地找到每个特征点在另一个图像中的最近邻点,从而加速特征匹配的过程。 FLANN算法的核心思想是利用空间划分来降低最近邻搜索的时间复杂度。它将高维空间中的数据点分成多个子空间,并建立一棵KD树(k-dimension tree)来表示这些子空间。在搜索最近邻点时,FLANN算法会利用KD树的结构来避免对所有数据点进行线性搜索,从而提高搜索效率。 使用FLANN算法进行特征匹配的步骤通常包括以下几个步骤: 1. 提取图像中的特征点,并计算它们的特征描述子。 2. 建立KD树,并将特征描述子插入到KD树中。 3. 对于每个特征点,在KD树中搜索它在另一个图像中的最近邻点。 4. 计算每一对匹配点之间的相似度,并找到相似度最高的匹配点对。 FLANN算法的优点是它能够在高维空间中进行快速最近邻搜索,并且在大规模数据集上也能够保持高效率。但是,FLANN算法的缺点是它需要大量的内存来存储KD树,因此在处理大规模数据集时,可能会面临内存不足的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值