我们要知道三维空间中的点在图像中的位置,就需要提取特征与特征匹配了。

1.检测特征点

2.计算描述子

3.特征匹配

1.检测特征点

  我们用到的检测特征点的方法是FAST算法,最大的特点就是快!

  算法原理:遍历图像,找到所有的角点。我们就拿一个角点举例,例如只拿到一个角点p,设其像素灰度值为I,取这个角点以三为半径的圆上的所有像素点,能取到16个,然后设定一个阈值t,如果连续n个像素点的灰度值都大于I+t或者都小于I-t。我们则认为其为特征点。接着计算方向:特征点与重心的角度。

2.计算描述子

  描述子我们可以理解为在每一个特征点旁边有一个向量,或者说也可以理解为数组,记录着特征点周围的信息。这里用的事BRIEF描述子。BRIEF描述子是一个二进制描述子,就是在特征点周围随机取128对点对或者是256对点对p和q,若p大于q,则记为1,否则记为0。这就组成了一个128个数的[0,1,1,0.....]序列。

3.特征匹配

  此时我们得到了所有的特征点和描述子。此时进行暴力匹配,对图1中的每一个特征点分别和图像2中的特征点的描述子比较,我们用Hamming距离来度量两个描述子的相似程度,如果Hamming距离小于两倍的最小距离则认为匹配正确,否则认为匹配错误。

代码如下:

#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 != )
{
cout<<"usage: feature_extraction img1 img2"<<endl;
return ;
}
//-- 读取图像
Mat img_1 = imread ( argv[], CV_LOAD_IMAGE_COLOR );
Mat img_2 = imread ( argv[], CV_LOAD_IMAGE_COLOR ); //-- 初始化
std::vector<KeyPoint> keypoints_1, keypoints_2;
Mat descriptors_1, descriptors_2;
Ptr<FeatureDetector> detector = ORB::create();
Ptr<DescriptorExtractor> descriptor = ORB::create();
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create ( "BruteForce-Hamming" ); //-- 第一步:检测 Oriented FAST 角点位置
detector->detect ( img_1,keypoints_1 );
detector->detect ( img_2,keypoints_2 ); //-- 第二步:根据角点位置计算 BRIEF 描述子
descriptor->compute ( img_1, keypoints_1, descriptors_1 );
descriptor->compute ( img_2, keypoints_2, descriptors_2 ); Mat outimg1;
drawKeypoints( img_1, keypoints_1, outimg1, Scalar::all(-), DrawMatchesFlags::DEFAULT );
imshow("ORB特征点",outimg1); //-- 第三步:对两幅图像中的BRIEF描述子进行匹配,使用 Hamming 距离
vector<DMatch> matches;//matches存储特征点信息
matcher->match ( descriptors_1, descriptors_2, matches ); //-- 第四步:匹配点对筛选
double min_dist=, max_dist=; //找出所有匹配之间的最小距离和最大距离, 即是最相似的和最不相似的两组点之间的距离
for ( int i = ; 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 ); //当描述子之间的距离大于两倍的最小距离时,即认为匹配有误.但有时候最小距离会非常小,设置一个经验值30作为下限.
std::vector< DMatch > good_matches;
for ( int i = ; i < descriptors_1.rows; i++ )
{
if ( matches[i].distance <= max ( *min_dist, 30.0 ) )
{
good_matches.push_back ( matches[i] );
}
} //-- 第五步:绘制匹配结果
Mat img_match;
Mat img_goodmatch;
drawMatches ( img_1, keypoints_1, img_2, keypoints_2, matches, img_match );
drawMatches ( img_1, keypoints_1, img_2, keypoints_2, good_matches, img_goodmatch );
imshow ( "所有匹配点对", img_match );
imshow ( "优化后匹配点对", img_goodmatch );
waitKey(); return ;
}

若有错误,欢迎指正!谢谢!

SLAM算法中提取特征总结的更多相关文章

  1. 使用DeepWalk从图中提取特征

    目录 数据的图示 不同类型的基于图的特征 节点属性 局部结构特征 节点嵌入 DeepWalk简介 在Python中实施DeepWalk以查找相似的Wikipedia页面 数据的图示 当你想到" ...

  2. SIFT算法中DoG特征点的修正

    SIFT算法中,在DoG空间找到极值点后,需要对极值点进行修正,本文主要详细的讲解一下为什么需要修正,以及如何对极值点进行修正. 下图演示了二维函数离散空间得到的极值点与连续空间的极值点之间的差别 利 ...

  3. 三维重建:SLAM算法的考题总结

    参考英文维基:https://en.wikipedia.org/wiki/Slam 参考文档:视觉slam研究分析的一点认识 1. 请简单描述您对机器人的SLAM的概念理解? 答: 机器人需要在自身位 ...

  4. 机器学习中的特征缩放(feature scaling)

    参考:https://blog.csdn.net/iterate7/article/details/78881562 在运用一些机器学习算法的时候不可避免地要对数据进行特征缩放(feature sca ...

  5. SLAM: Orb_SLAM中的ORB特征

    原文链接:什么是ORB 关于Orb特征的获取:参考 最新版的OpenCV中新增加的ORB特征的使用 ORB是是ORiented Brief 的简称,对Brief的特定性质进行了改进. ORB的描述在下 ...

  6. SEPC:使用3D卷积从FPN中提取尺度不变特征,涨点神器 | CVPR 2020

    论文提出PConv为对特征金字塔进行3D卷积,配合特定的iBN进行正则化,能够有效地融合尺度间的内在关系,另外,论文提出SEPC,使用可变形卷积来适应实际特征间对应的不规律性,保持尺度均衡.PConv ...

  7. TextRank:关键词提取算法中的PageRank

    很久以前,我用过TFIDF做过行业关键词提取.TFIDF仅仅从词的统计信息出发,而没有充分考虑词之间的语义信息.现在本文将介绍一种考虑了相邻词的语义关系.基于图排序的关键词提取算法TextRank [ ...

  8. 对比几种在ROS中常用的几种SLAM算法

    在此因为要总结写一个文档,所以查阅资料,将总结的内容记录下来,欢迎大家指正! 文章将介绍使用的基于机器人操作系统(ROS)框架工作的SLAM算法. 在ROS中提供的五种基于2D激光的SLAM算法分别是 ...

  9. 转:SLAM算法解析:抓住视觉SLAM难点,了解技术发展大趋势

    SLAM(Simultaneous Localization and Mapping)是业界公认视觉领域空间定位技术的前沿方向,中文译名为“同步定位与地图构建”,它主要用于解决机器人在未知环境运动时的 ...

随机推荐

  1. Windows内核驱动中操作文件

    本页主题:如何在windows内核驱动中对文件操作,实现对文件的拷贝.粘贴.删除.查询信息等,这是很常用也是很简单的方法. 部分内容参考:http://www.cppblog.com/aurain/a ...

  2. stm32输入的功能引脚功能介绍

    Ⅰ.写在前面在开发STM32的时候,都需要对IO的模式进行配置(GPIO_InitStructure. GPIO_Mode = xxx).但是,你们都知道各种模式的具体意义吗? 有的人问:IO口输出可 ...

  3. 记录-springcloud -mybatis

    搭建springcloud与mybatis 从数据库读取数据返回到浏览器 1:我的工程目录 entity  和mapper 中的代码 controller和service的代码 启动类的文件:记得加包 ...

  4. 微信支付遇到的坑---缺少参数total_fee

    今天在做微信砍价成功后支付,出现了这个报错 看到报错后,去找total_fee这个参数,调试了半天,total_fee是确定有值的 微信支付的步骤 ① 预支付 商户号,商户秘钥,appid,appse ...

  5. chip8模拟器的python3实现-1-CHIP8简介

    打算编写一个NES模拟器,先从简单的chip8模拟器入手 1.CHIP-8简介 CHIP-8是一个解释型语言,由Joseph Weisbecker开发.最初CHIP-8在上个世纪70年代被使用在COS ...

  6. UNIX 系统下退出 git commit 编辑器

    如果是 Emacs 编辑器,输入 Ctrl X + Ctrl S(保存),再输入Ctrl X + Ctrl C(退出) 如果是VIM编辑器,输入 ESC + :wq UNIX 系统默认打开的是 Ema ...

  7. 用同一台PC的两个网口实现Iperf的server端和client端

    用同一台PC的两个网口实现Iperf的server端和client端 2015年10月20日 20:35:11 阅读数:2943 有时候需要发包,仅仅需要一定速率的流量,并不需要关心收到报文的大小,一 ...

  8. 使用iconfont图标

    iconfont.cn基本使用 登录iconfont.cn网站,直接使用github账号即可登录 输入关键字搜索需要的图标,然后在需要的图标上点击'添加入库' 点击网站右上角的购物车图标,查看当前已入 ...

  9. dotNet程序员的Java爬坑之旅(一)

    仔细想了下还是转java吧,因为后期不管是留在北京也好还是回老家也好,java的工作都会好找一点.现在的工作主要还是写.net,目标是下一次离职的时候可以找到一份全职的java工作,我一直都觉得实践才 ...

  10. python基础之Day18

    一.序列化概念 什么是序列化? 内存中的数据结构转成中间格式(json(所有编程语言通用)和pickle)存储到硬盘或基于网络状态 反序列化: 硬盘网络传来的数据格式转换成内存的数据结构 为什么 1. ...