关于特征检测和匹配的具体原理会在后续的文章中具体讲解,本文主要介绍Opencv实现的简单过程:
第一步:定义特征检测器(SIFT,SURF,ORB等)。

第二步:对图像中特征点进行检测,并将特征点存储在Keypoints中。

第三步:提取特征点的描述信息。

第四步:定义特征匹配器(特征匹配的方法主要有两种分别为暴力匹配BFmatch和FlannBased)。

第五步:过滤掉较差的匹配点位(一般根据临近两点的距离进行过滤)

主要是根据DMatch中的distance进行过滤,对于distance可以抽象理解为匹配的分值,distance越小说明检测点的相似度越高,效果越好。

第六步:对匹配的特征点显示。

代码1(未滤波,只限制筛选点数为20)

#include <iostream>
#include <opencv2/opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include <opencv2/xfeatures2d.hpp>using namespace cv;  //包含cv命名空间
using namespace std;
using namespace xfeatures2d;int main() {system("color 2E");//载入图片Mat src1 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\3.jpg",1);Mat src2 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\4.jpg", 1);//显示原图imshow("原图1",src1);imshow("原图2", src2);//定义变量vector<KeyPoint> keypoints1, keypoints2;//定义检测的特征点存储容器Mat descriptors1,descriptors2;//定义特征点描述信息为Mat类型Mat result_img;//匹配结果图片//创建sift特征检测器实例//将SIFT可以换位SURF、ORBPtr<SIFT>detector = SIFT::create();//提取特征点detector->detect(src1,keypoints1,noArray());detector->detect(src2, keypoints2, Mat());//获取特征点的描述信息=>特征向量detector->compute(src1,keypoints1,descriptors1);detector->compute(src2, keypoints2, descriptors2);//定义匹配器的实例化=>方法为暴力匹配法Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::BRUTEFORCE);//create中的参数可以填string FlannBased等匹配方法//第二种实例化方法//BFMatcher matcher;//进行暴力匹配vector<DMatch> matches;//第一个参数为queryDescription为目标,第二个参数为trainDescription模板matcher->match(descriptors1,descriptors2,matches);//限制特征点匹配数量=》只匹配前20个较好的特征点int num = 20;nth_element(matches.begin(), matches.begin()+num,matches.end());//vector去除20以后的元素matches.erase(matches.begin()+num,matches.end());//输出关键点和匹配结果//其中右侧图为trainDescription模板,左侧图为queryDescription目标//左图中的点与右图中进行匹配对应drawMatches(src1,keypoints1,src2,keypoints2, matches,result_img);drawKeypoints(src1,keypoints1,src1);drawKeypoints(src2,keypoints2,src2);imshow("匹配结果",result_img);imshow("特征点1",src1);imshow("特征点2",src2);waitKey(0);system("pause");return 0;
}

运行结果为:

代码2(通过距离进行滤波)

#include <iostream>
#include <opencv2/opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include <opencv2/xfeatures2d.hpp>using namespace cv;  //包含cv命名空间
using namespace std;
using namespace xfeatures2d;int main() {system("color 2E");//载入图片Mat src1 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\3.jpg",1);Mat src2 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\4.jpg", 1);//显示原图imshow("原图1",src1);imshow("原图2", src2);//定义变量vector<KeyPoint> keypoints1, keypoints2;//定义检测的特征点存储容器Mat descriptors1,descriptors2;//定义特征点描述信息为Mat类型Mat result_img;//匹配结果图片//创建sift特征检测器实例//将SIFT可以换位SURF、ORBPtr<SIFT>detector = SIFT::create();//提取特征点detector->detect(src1,keypoints1,noArray());detector->detect(src2, keypoints2, Mat());//获取特征点的描述信息=>特征向量detector->compute(src1,keypoints1,descriptors1);detector->compute(src2, keypoints2, descriptors2);//定义匹配器的实例化=>方法为暴力匹配法Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::BRUTEFORCE);//create中的参数可以填string FlannBased等匹配方法//第二种实例化方法//BFMatcher matcher;//进行暴力匹配vector<DMatch> matches;//第一个参数为queryDescription为目标,第二个参数为trainDescription模板matcher->match(descriptors1,descriptors2,matches);//限制特征点匹配数量=》只匹配前20个较好的特征点int num = 20;nth_element(matches.begin(), matches.begin()+num,matches.end());//vector去除20以后的元素matches.erase(matches.begin()+num,matches.end());double Max_distance = matches[1].distance;double Min_distance = matches[1].distance;vector<DMatch> goodfeatrues;//根据特征点的距离去筛选for (int i = 0; i < matches.size(); i++){double dist = matches[i].distance;if (dist>Max_distance){Max_distance = dist;}if (dist<Min_distance){Min_distance = dist;}}cout << "匹配点的最大距离:" << Max_distance << endl;cout << "匹配点的最小距离:" << Min_distance << endl;//M为距离阈值,M越大点数越多double M = 1.3;for (int  i = 0; i < matches.size(); i++){double dist = matches[i].distance;if (dist<M*Min_distance)      {goodfeatrues.push_back(matches[i]);}}cout << "最终选取特征点的数量为:" << matches.size() << endl;//输出关键点和匹配结果//其中右侧图为trainDescription模板,左侧图为queryDescription目标//左图中的点与右图中进行匹配对应drawMatches(src1,keypoints1,src2,keypoints2, goodfeatrues,result_img);drawKeypoints(src1,keypoints1,src1);drawKeypoints(src2,keypoints2,src2);imshow("匹配结果",result_img);imshow("特征点1",src1);imshow("特征点2",src2);waitKey(0);system("pause");return 0;
}

运行结果为:

代码3(通过knnMatch匹配,可以通过对distance设置阈值进行滤波,效果最好)

#include <iostream>
#include <opencv2/opencv.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include <opencv2/xfeatures2d.hpp>using namespace cv;  //包含cv命名空间
using namespace std;
using namespace xfeatures2d;int main() {system("color 2E");//载入图片Mat src1 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\3.jpg",1);Mat src2 = imread("E:\\乔大花进度\\11-18\\sift特征检测和匹配\\4.jpg", 1);//显示原图imshow("原图1",src1);imshow("原图2", src2);//定义变量vector<KeyPoint> keypoints1, keypoints2;//定义检测的特征点存储容器Mat descriptors1,descriptors2;//定义特征点描述信息为Mat类型Mat result_img;//匹配结果图片//创建sift特征检测器实例//将SIFT可以换位SURF、ORBPtr<SIFT>detector = SIFT::create();//提取特征点detector->detect(src1,keypoints1,noArray());detector->detect(src2, keypoints2, Mat());//获取特征点的描述信息=>特征向量detector->compute(src1,keypoints1,descriptors1);detector->compute(src2, keypoints2, descriptors2);//定义匹配器的实例化=>方法为暴力匹配法Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(DescriptorMatcher::BRUTEFORCE);//create中的参数可以填string FlannBased等匹配方法//第二种实例化方法//BFMatcher matcher;//进行暴力匹配vector<DMatch> matches;vector<Mat>train_desc(1, descriptors2);matcher->add(train_desc);matcher->train();vector<vector<DMatch>> matchpoints;matcher->knnMatch(descriptors1,matchpoints,2);vector<DMatch> goodfeatur;for (int i = 0; i < matchpoints.size(); i++){if (matchpoints[i][0].distance<0.15*matchpoints[i][1].distance){goodfeatur.push_back(matchpoints[i][0]);}}cout << "筛选后的特征点数量为: " << goodfeatur.size() << endl;//输出关键点和匹配结果//其中右侧图为trainDescription模板,左侧图为queryDescription目标//左图中的点与右图中进行匹配对应drawMatches(src1,keypoints1,src2,keypoints2, goodfeatur,result_img);drawKeypoints(src1,keypoints1,src1);drawKeypoints(src2,keypoints2,src2);namedWindow("匹配结果",WINDOW_NORMAL);resizeWindow("匹配结果",500,500);imshow("匹配结果",result_img);waitKey(0);system("pause");return 0;
}

运行结果为:

Opencv(C++)学习系列---特征点检测和匹配相关推荐

  1. 【OpenCV学习】(十)特征点检测与匹配

    [OpenCV学习](十)特征点检测与匹配 背景 提取图像的特征点是图像领域中的关键任务,不管在传统还是在深度学习的领域中,特征代表着图像的信息,对于分类.检测任务都是至关重要的: 特征点应用的一些场 ...

  2. opencv学习笔记三十六:AKAZE特征点检测与匹配

    KAZE是日语音译过来的 , KAZE与SIFT.SURF最大的区别在于构造尺度空间,KAZE是利用非线性方式构造,得到的关键点也就更准确(尺度不变性 ): Hessian矩阵特征点检测 ,方向指定, ...

  3. 【OpenCV入门教程之十七】OpenCV重映射 SURF特征点检测合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/30974513 作者:毛星云(浅墨) ...

  4. 调用摄像头使用face_recognition 或 opencv中haar人脸特征实时检测识别人脸、给人脸打马赛克/给人脸贴图

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) OpenCV:python调用摄像头同时使用OpenCV中自带 ...

  5. 十.OpenCv 特征点检测和匹配

    特征点检测和匹配 1. 特征检测的基本概念 特征检测是计算机视觉和图像处理中的一个概念.它指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征.特征检测的结果是把图像上的点分为不同的子集 ...

  6. 系统性综述:特征点检测与匹配

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨梦寐mayshine@知乎(已授权) 来源丨https://zhuanlan.zhihu.com ...

  7. Patch2Pix(CVPR 2021)特征点检测与匹配论文精读笔记

    前言 论文地址 论文补充材料 / 附录 代码地址   翻译并记录阅读每段的感受和写作逻辑.大概了解特征点检测和目标检测的大致方法的话,不用递归式读论文也能基本理解本文的方法. 参考文献 检测: [5] ...

  8. 图像特征点检测与匹配评价准则——量化

    欢迎转载,转载请注明出处,谢谢! 目前图像匹配中,局部特征匹配占据了绝大部分,常用的局部特征匹配方法有Harris.SIFT.SURF.ORB等等,不同的特征点检测和匹配方法尤其独特的优势和不足:  ...

  9. 图像特征点检测与匹配评价——量化指标

    原文:http://blog.csdn.net/cgwang_1580/article/details/68944319 目前图像匹配中,局部特征匹配占据了绝大部分,常用的局部特征匹配方法有Harri ...

最新文章

  1. Java动态调用方法
  2. executor线程池框架_如何使用Java 5 Executor框架创建线程池
  3. Python -- 三元表达式(三目运算符)
  4. dreamweaver 正则表达式为属性值加上双引号_PHP正则表达式核心技术完全详解 第2节...
  5. (2)PCIE简介(学无止境)
  6. PHP(PHP:Hypertext Preprocessor)
  7. SpringMVC一路总结(一)
  8. c++获取ctrl+v内容_WPS表格——CTRL快捷键的用法
  9. 目标跟踪之ADMM求解简介
  10. fm -rf 删除 恢复
  11. 无线网改了密码后连不上服务器了,修改wifi密码后连不上网了怎么办?
  12. 确定sw1开关信号输入端口_MEMS光学器件— MEMS OXC(光交叉互连开关)
  13. 0基础女生学网络安全合适吗
  14. JVM内存模型和垃圾回收机制
  15. 【Nessus安装、使用】
  16. mawen启动项目css样式失效问题解决方法 EL表达式无效
  17. Detection in Crowded Scenes: One Proposal, Multiple Predictions(拥挤场景下的检测:一个提议,多个预测)
  18. 牛客练习赛51 C、勾股定理 只一边求另外两边 结论
  19. ArcGIS 中的标准分类方法(相等、分位、自然断裂、标准差)
  20. opencv python gpu加速_在Windows上使用OpenCV和Python进行硬件加速解码(MSMT/IntelMFX/FFMPEG/any-backend)...

热门文章

  1. python把字符串按照指定长度分割_python如何将字符串等长分割
  2. 名帖53 隋代 小楷《董美人墓志》
  3. Unity-ARKit入门
  4. goldengate mysql_Goldengate异构 mysql——oracl
  5. 火爆全网的DragGAN作者,潘新钢团队招全奖博士/博后
  6. linux 桌面时钟
  7. 程序员秒懂的6个梗,其实做程序员和买橘子是一样的
  8. Node.js实现简单爬虫 讲解
  9. Hive支持Update和Delete语句
  10. 简易小游戏(类似打飞机)的简单实现cocos2d-x-2.1.5