前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ OpenCV4.5版本SIFT特征检测及匹配

C++ OpenCV4.5版本SIFT特征检测及匹配

作者头像
Vaccae
发布2021-05-27 10:04:55
3.7K0
发布2021-05-27 10:04:55
举报
文章被收录于专栏:微卡智享

学更好的别人,

做更好的自己。

——《微卡智享》

本文长度为2739,预计阅读6分钟

前言

关于SIFT的特征点检测在《C++ OpenCV特征提取之SIFT特征检测》有介绍过,在OpenCV4.5版本中SIFT做是算法优化,也移到主仓库中了,并且有朋友也留言问了4.5版本下的DEMO。

所以这篇就做一下OpenCV4.5版本的SIFT特征点检测及匹配。

实现效果

两张原图

匹配的效果

代码实现

微卡智享

#

实现流程

1

定义检测的特征点个数,用SIFT进行特征检测

2

对检测完的两个图做特征向量的提取

3

使用BFMatch进行匹配,筛选出好的结果

4

画出匹配的特征点

01

SIFT特征检测

以前版本中使用SIFT需要引入xfeatures2d.hpp,而现在就不用了。

旧版本

新版本

02

特征向量的提取

接下来就是计算特征点描述符,特征向量的提取

特征向量提取

03

使用BFMatch匹配

提取完特征向量后,对两个特征向量进行匹配,然后通过匹配的结果计算出向量的最大和最小距离。

特征匹配及计算最大最小距离

04

筛选好的匹配结果

最后就是根据最大最小的距离,从匹配的点中筛选出好的结果,再展示出来。

筛选结果绘制图像

完整代码

代码语言:javascript
复制
#include<iostream>
#include<opencv2/opencv.hpp>
#include"CvUtils.h"

using namespace std;
using namespace cv;

int main(int argc, char** argv) {

  Mat src = imread("E:/DCIM/hrd/h1.jpg");
  CvUtils::MatResize(src);
  CvUtils::SetShowWindow(src, "src", 10, 20);
  imshow("src", src);

  Mat src2 = imread("E:/DCIM/hrd/h3.jpg");
  CvUtils::MatResize(src2);
  CvUtils::SetShowWindow(src2, "src2", 300, 20);
  imshow("src2", src2);

  //定义Sift的基本参数
  int numFeatures = 500;
  //创建detector存放到KeyPoints中
  Ptr<SIFT> detector = SIFT::create(numFeatures);
  vector<KeyPoint> keypoints, keypoints2;
  detector->detect(src, keypoints);
  detector->detect(src2, keypoints2);
  //打印Keypoints
  cout << "Keypoints:" << keypoints.size() << endl;
  cout << "Keypoints2:" << keypoints2.size() << endl;

  Mat drawsrc, drawsrc2;
  drawKeypoints(src, keypoints, drawsrc);
  CvUtils::SetShowWindow(drawsrc, "drawsrc", 10, 20);
  imshow("drawsrc", drawsrc);
  drawKeypoints(src2, keypoints2, drawsrc2);
  CvUtils::SetShowWindow(drawsrc2, "drawsrc2", 300, 20);
  imshow("drawsrc2", drawsrc2);

  //计算特征点描述符,特征向量提取
  Mat dstSIFT, dstSIFT2;
  Ptr<SiftDescriptorExtractor> descriptor = SiftDescriptorExtractor::create();
  descriptor->compute(src, keypoints, dstSIFT);
  descriptor->compute(src2, keypoints2, dstSIFT2);
  cout << dstSIFT.cols << endl;
  cout << dstSIFT2.rows << endl;

  //进行BFMatch暴力匹配
  BFMatcher matcher(NORM_L2);
  //定义匹配结果变量
  vector<DMatch> matches;
  //实现描述符之间的匹配
  matcher.match(dstSIFT, dstSIFT2, matches);

  //定义向量距离的最大值与最小值
  double max_dist = 0;
  double min_dist = 1000;
  for (int i = 1; i < dstSIFT.rows; ++i)
  {
    //通过循环更新距离,距离越小越匹配
    double dist = matches[i].distance;
    if (dist > max_dist)
      max_dist = dist;
    if (dist < min_dist)
      min_dist = dist;
  }
  cout << "min_dist=" << min_dist << endl;
  cout << "max_dist=" << max_dist << endl;
  //匹配结果筛选    
  vector<DMatch> goodMatches;
  for (int i = 0; i < matches.size(); ++i)
  {
    double dist = matches[i].distance;
    if (dist < 2 * min_dist)
      goodMatches.push_back(matches[i]);
  }
  cout << "goodMatches:" << goodMatches.size() << endl;

  Mat result;
  //匹配特征点天蓝色,单一特征点颜色随机
  drawMatches(src, keypoints, src2, keypoints2, goodMatches, result, 
    Scalar(255, 255, 0), Scalar::all(-1));
  CvUtils::SetShowWindow(result, "Result", 100, 20);
  imshow("Result", result);


  waitKey(0);
  return 0;
}

源码地址

https://github.com/Vaccae/OpenCVDemoCpp.git

这个Demo我也整合到OpenCV练习Demo中了,GitHub上不去的朋友,可以击下方的原文链接跳转到码云的地址,关注【微卡智享】公众号,回复【源码】可以下载我的所有开源项目。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微卡智享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 源码地址
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档