特征提取与匹配

目标
  • 提取特征和描述子
  • 匹配特征
  • 展示匹配结果
SIFT
#include "openMVG/features/feature.hpp"
#include "openMVG/features/sift/SIFT_Anatomy_Image_Describer.hpp"
#include "openMVG/features/svg_features.hpp"
#include "openMVG/image/image_io.hpp"
#include "openMVG/image/image_concat.hpp"
#include "openMVG/matching/regions_matcher.hpp"
#include "openMVG/matching/svg_matches.hpp"
//
#include "third_party/stlplus3/filesystemSimplified/file_system.hpp"

#include <cstdlib>
#include <string>
#include <iostream>

using namespace openMVG;
using namespace openMVG::image;
using namespace openMVG::matching;
using namespace std;

int main() {

  Image<RGBColor> image;
  string jpg_filenameL = stlplus::folder_up(string("/home/lsy/openMVG/src/openMVG_Samples/features_siftPutativeMatches"))
    + "/imageData/StanfordMobileVisualSearch/Ace_0.png";
  string jpg_filenameR = stlplus::folder_up(string("/home/lsy/openMVG/src/openMVG_Samples/features_siftPutativeMatches"))
    + "/imageData/StanfordMobileVisualSearch/Ace_1.png";

  Image<unsigned char> imageL, imageR;
  ReadImage(jpg_filenameL.c_str(), &imageL);
  ReadImage(jpg_filenameR.c_str(), &imageR);

  //--
  // Detect regions thanks to an image_describer
  //--
  using namespace openMVG::features;
  std::unique_ptr<Image_describer> image_describer(new SIFT_Anatomy_Image_describer);
  std::map<IndexT, std::unique_ptr<features::Regions>> regions_perImage;
  image_describer->Describe(imageL, regions_perImage[0]);
  image_describer->Describe(imageR, regions_perImage[1]);

  const PointFeatures
    featsL = regions_perImage.at(0)->GetRegionsPositions(),
    featsR = regions_perImage.at(1)->GetRegionsPositions();
    //virtual PointFeatures GetRegionsPositions() const = 0;不好,返回不是引用

  // Show both images side by side
  {
    Image<unsigned char> concat;
    ConcatV(imageL, imageR, concat);
    string out_filename = "00_images.jpg";
    WriteImage(out_filename.c_str(), concat);
  }

  //std::unique_ptr<features::Regions>
  const SIFT_Regions* regionsL = dynamic_cast<SIFT_Regions*>(regions_perImage.at(0).get());
  const SIFT_Regions* regionsR = dynamic_cast<SIFT_Regions*>(regions_perImage.at(1).get());

  //- Draw features on the two image (side by side)
  {
    Features2SVG
    (
      jpg_filenameL,
      {imageL.Width(), imageL.Height()},
      regionsL->Features(),
      jpg_filenameR,
      {imageR.Width(), imageR.Height()},
      regionsR->Features(),
      "01_features.svg"
    );
  }

  //-- Perform matching -> find Nearest neighbor, filtered with Distance ratio
  std::vector<IndMatch> vec_PutativeMatches;
  {
    // Find corresponding points
    matching::DistanceRatioMatch(
      0.8, matching::BRUTE_FORCE_L2,
      *regions_perImage.at(0).get(),
      *regions_perImage.at(1).get(),
      vec_PutativeMatches);

    // Draw correspondences after Nearest Neighbor ratio filter
    const bool bVertical = true;
    Matches2SVG
    (
      jpg_filenameL,
      {imageL.Width(), imageL.Height()},
      regionsL->GetRegionsPositions(),
      jpg_filenameR,
      {imageR.Width(), imageR.Height()},
      regionsR->GetRegionsPositions(),
      vec_PutativeMatches,
      "02_Matches.svg",
      bVertical
    );
  }

  // Display some statistics
  std::cout << featsL.size() << " Features on image A" << std::endl
   << featsR.size() << " Features on image B" << std::endl
   << vec_PutativeMatches.size() << " matches after matching with Distance Ratio filter" << std::endl;

  return EXIT_SUCCESS;
}
特征点提取

可以选择三种方法:

std::unique_ptr<Image_describer> image_describer = AKAZE_Image_describer::create
    (AKAZE_Image_describer::Params(AKAZE::Params(), AKAZE_MSURF));
std::unique_ptr<Image_describer> image_describer = AKAZE_Image_describer::create
    (AKAZE_Image_describer::Params(AKAZE::Params(), AKAZE_MLDB));
std::unique_ptr<Image_describer> image_describer(new SIFT_Anatomy_Image_describer(SIFT_Anatomy_Image_describer::Params()));
//regions_fctory.hpp
/// Define the classic SIFT Keypoint
using SIFT_Regions = Scalar_Regions<SIOPointFeature, unsigned char, 128>;

/// Define the AKAZE Keypoint (with a float descriptor)
using AKAZE_Float_Regions = Scalar_Regions<SIOPointFeature, float, 64>;
/// Define the AKAZE Keypoint (with a LIOP descriptor)
using AKAZE_Liop_Regions = Scalar_Regions<SIOPointFeature, unsigned char, 144>;
/// Define the AKAZE Keypoint (with a binary descriptor saved in an uchar array)
using AKAZE_Binary_Regions = Binary_Regions<SIOPointFeature, 64>;
//matcher_type.hpp
enum EMatcherType : unsigned char
{
  BRUTE_FORCE_L2,
  ANN_L2,
  CASCADE_HASHING_L2,
  BRUTE_FORCE_HAMMING
};
匹配结果保存成图像
//features_image_matching
  // Draw correspondences after Nearest Neighbor ratio filter
  {
    const bool bVertical = true;
    Matches2SVG
    (
      jpg_filenameL,
      {imageL.Width(), imageL.Height()},
      regions_perImage.at(0)->GetRegionsPositions(),
      jpg_filenameR,
      {imageR.Width(), imageR.Height()},
      regions_perImage.at(1)->GetRegionsPositions(),
      vec_PutativeMatches,
      "02_Matches.svg",
      bVertical
    );
  }
c++技巧
string jpg_filenameL = stlplus::folder_up(string("/home/lsy/openMVG/src/openMVG_Samples/features_siftPutativeMatches"))
    + "/imageData/StanfordMobileVisualSearch/Ace_0.png";
//folder_up : 输入"1/2/3", 输出"1/2"
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值