#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>using namespace std;
using namespace cv;int main(int argc, char** argv)
{//判断运行该程序时,是否满足以下启动命令if(argc != 3){cout << "usage: ./feature_extraction img_1 img_2" << endl;//注意img_1和img_2要指明路径return 1;}//读取图像//argv[0] 是程序名--feature_extractionMat img_1 = imread(argv[1] , CV_LOAD_IMAGE_COLOR);Mat img_2 = imread(argv[2] , CV_LOAD_IMAGE_COLOR);//初始化std::vector<KeyPoint> keypoints_1, keypoints_2;Mat descriptors_1, descriptors_2;//cout << "descriptors_1 = " << descriptors_1 << endl;// 打印结果:descriptors_1 = []//在代码最后有介绍ORB::create()//ORB::create(nfeatures, scaleFactor, nlevels, edgeThreshold, firstLevel, WTA_K, scoreType, patchSize, fastThreshold);//cv::ORB 实现ORB(oriented BRIEF)关键点检测器和描述子提取器类。Ptr<ORB> orb = ORB::create(500, 1.2f, 8, 31, 0, 2, ORB::HARRIS_SCORE, 31, 20);//==========================================// 第一步: 检测Oriented FAST 角点的位置orb->detect(img_1, keypoints_1);orb->detect(img_2, keypoints_2);// 第二步: 根据角点位置计算BRIEF描述子orb->compute(img_1, keypoints_1, descriptors_1);orb->compute(img_2, keypoints_2, descriptors_2);Mat outimg1;           //输出图像outimg1,用矩阵保存图像信息,包括矩阵头和矩阵数据drawKeypoints(         //Draws keypoints.img_1,keypoints_1,outimg1,Scalar::all(-1),          //color Color of keypoints.DrawMatchesFlags::DEFAULT //Output image matrix will be created (Mat::create),);imshow("ORB特征点", outimg1);// 第三步: 对两幅图像中的BRIEF描述子进行匹配,使用 Hamming distance 汉明距离vector<DMatch> matches;           //DMatch---Class for matching keypoint descriptorsBFMatcher matcher (NORM_HAMMING); //BFMatcher---Brute-force descriptor matcher.(暴力匹配)matcher.match(descriptors_1, descriptors_2, matches);// 第四步: 匹配点对筛选(p, q)double min_dist = 10000, max_dist = 0;// 找出所有匹配之间的最小距离和最大距离,即是最相似的和最不相似的两组点之间的距离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);/**********************优化匹配****************************///当描述子之间的距离大于两倍的最小距离时, 认为匹配有误//但有时候最小距离非常小,需要设置一个经验值作为下线std::vector<DMatch> good_matches;for(int i = 0; i < descriptors_1.rows; i++){if(matches[i].distance <= max(2*min_dist, 30.0))//设置经验值30.0作为下线,选取 2*min_dist 和 30.0之间最大的一个{good_matches.push_back(matches[i]);//如果描述子距离满足条件,就把这个matches[i]压入到优化后的队列good_matches[i]中。}}//绘制匹配结果Mat img_match;drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_match);imshow("所有匹配点对", img_match);waitKey(0);//打印优化后的图片Mat img_goodmatch;drawMatches(img_1,keypoints_1,img_2, keypoints_2, good_matches, img_goodmatch);imshow("优化后的匹配点对", img_goodmatch);waitKey(0);//std::cout << "Hello, World!" << std::endl;return 0;
}/** static Ptr<ORB> cv::ORB::create (int     nfeatures = 500,    //The maximum number of features to retain.float   scaleFactor = 1.2f,//金字塔抽取比,大于1。scaleFactor==2表示经典金字塔,每一层的像素都比上一层少4倍,//但如此大的尺度因子会显著降低特征匹配得分。//另一方面,过于接近1的比例因素将意味着要覆盖一定的比例范围,//你将需要更多的金字塔级别,因此速度将受到影响。int     nlevels = 8,        //金字塔等级的数量。//最小级别的线性大小等于input_image_linear_size/pow(scaleFactor, nlevels).//输入图像线性大小/功率(缩放因子,非线性)。int     edgeThreshold = 31,  //这是未检测到特征的边框大小。它应该大致匹配patchSize参数.int     firstLevel = 0,     //It should be 0 in the current implementation.int     WTA_K = 2,          //产生oriented BRIEF描述子的每个元素的点数。int     scoreType = ORB::HARRIS_SCORE,//默认的HARRIS_SCORE意味着HARRIS算法用于对特征进行排序//(分数被写入KeyPoint::score,并用于保留最佳特征);//FAST_SCORE是参数的另一个值,它会产生稍微不太稳定的关键点,//但是计算起来要快一点。int     patchSize = 31,     //oriented BRIEF描述符使用的补丁大小。//在较小的金字塔层上,被特征覆盖的感知图像区域会更大。int     fastThreshold = 20)nfeatures :最多提取的特征点的数量;scaleFactor : 金字塔图像之间的尺度参数,类似于SIFT中的?;nlevels: 高斯金字塔的层数;edgeThreshold :边缘阈值,这个值主要是根据后面的patchSize来定的,靠近边缘edgeThreshold以内的像素是不检测特征点的。firstLevel-:看过SIFT都知道,我们可以指定第一层的索引值,这里默认为0。WET_K : 用于产生BIREF描述子的点对的个数,一般为2个,也可以设置为3个或4个,那么这时候描述子之间的距离计算就不能用汉明距离了,而是应该用一个变种。OpenCV中,如果设置WET_K = 2,则选用点对就只有2个点,匹配的时候距离参数选择NORM_HAMMING,如果WET_K设置为3或4,则BIREF描述子会选择3个或4个点,那么后面匹配的时候应该选择的距离参数为NORM_HAMMING2。scoreType :用于对特征点进行排序的算法,你可以选择HARRIS_SCORE,也可以选择FAST_SCORE,但是它也只是比前者快一点点而已。patchSize :用于计算BIREF描述子的特征点邻域大小。*/

SLAM--ORB特征点提取--啰里啰嗦的代码解析相关推荐

  1. SLAM--ceres库--曲线逼近示例--啰里啰嗦的代码解析

    #include <ceres/ceres.h> #include <iostream> #include <chrono> #include <opencv ...

  2. ORB特征点提取与均匀化——ORBSLAM2源码讲解(一)

    文章目录 前言 一.基础知识 二.ORB特征均匀化策略对性能的影响 三.ORB特征金字塔 四.ORB提取扩展图像 五.ORB特征均匀化 总结 前言 本博客结合哔哩大学视频ORBSLAM2[ORBSLA ...

  3. opencv上gpu版surf特征点与orb特征点提取及匹配实例

    opencv上gpu版surf特征点与orb特征点提取及匹配实例 标签: gpu版surfgpu orbsurf和orbgpu surf及orbsurf orb gpu 2016-09-25 23:4 ...

  4. 一步步学习操作系统(1)——参照ucos,在STM32上实现一个简单的多任务(“啰里啰嗦版”)...

    该篇为"啰里啰嗦版",另有相应的"精简版"供参考 "不到长城非好汉:不做OS,枉为程序员" OS之于程序员,如同梵蒂冈之于天主教徒,那永远都 ...

  5. ORB-SLAM中的ORB特征(提取)

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者:小葡萄 https://zhuanlan.zhihu.com/p/61738607 本文仅做学术 ...

  6. 视觉SLAM——ORB特征

    一.OpenCV 的ORB 特征--slambook2/ch7/orb_ cv.cpp #include <iostream> #include <opencv2/core/core ...

  7. 2021啰里啰嗦的个人总结

    一年的时间说长不长说短不短,到年底的时候,年初的很多事情的细节都忘了,幸好自己平时在石墨文档中记日志,可以翻一翻日志看看自己这一年都干了些什么事情. 按照时间顺序,先回顾一下2021年干了些什么: 1 ...

  8. C# 多态性 (啰里啰嗦)

    使用多态性,可以动态地定义调用的方法, 而不是在编译期间定义. 编译器创建一个虚拟方法表 (vtable),其中列出了可以在运行期间调用的方法, 它根据运行期间的类型调用方法. public stat ...

  9. 啰里啰嗦学IOS CoreDate入门

    创建项目 需要把Use Core Date勾上 把Main.storyboard删除. 点击如图文件. 点击下面的Add Entity 点击 + 添加属性和设置类型 选中Entity,修改为Perso ...

最新文章

  1. Kafka生产者发送消息的三种方式
  2. input输入框修改后自动跳到最后一个字符
  3. 鸿蒙空间是什么星辰变,飞升之后做什么《星辰变》神魔妖界收伏奇珍异兽
  4. C#LeetCode刷题之#371-两整数之和(Sum of Two Integers)
  5. javascript数字补零
  6. linux mysql 卸载,安装,测试全过程
  7. 基于DevExpress XtraGrid控件实现的凭证式显示
  8. 加密--HashPasswordForStoringInConfigFile过时问题
  9. java基于springboot校园餐厅订餐管理系统
  10. 【高德LBS开源组件大赛】回眸微博的足迹
  11. vim中文乱码问题解决方式
  12. 刘元普双生贵子(但行好事,莫问前程)
  13. php的常见加密方式,记录接口中常见的简单内容加密方式:恺撒加密的PHP实现
  14. 不懂不要炒股,一定要在调整时买入股票!
  15. [实验吧刷题]密码学部分
  16. 验证本地缓冲区溢出漏洞攻击
  17. 一维空间--离散数学图灵机文章(一)
  18. R语言patchwork包将多个可视化结果组合起来、使用plot_annotation函数以及tag_level参数将组合图用大写字母进行顺序编码、为组合图的标签添加自定义前缀信息
  19. (附源码)springboot码头作业管理系统 毕业设计 341654
  20. Applet【总结】

热门文章

  1. 易经读书笔记12天地否
  2. TracePro | ABg散射设置表面不同吸收率的影响
  3. 【Batch批处理】利用random生成任意区间的随机整数
  4. 网络爬虫小白教程 (HttpClient)
  5. HTML5小游戏笑说米,带动气氛的小游戏:5个活跃气氛搞笑的小游戏(精选)
  6. python列表怎么转成数字,Python中列表元素转为数字的方法分析
  7. C++之动态规划(动态规划入门)
  8. Fedora20将网卡名字改回eth0
  9. 两个字的名字如何变成有空格的3个字符的名字
  10. 美术绘画中简单实用的几个技巧,轻松掌握~