2021SC@SDUSC

(十二)lvi-sam源代码阅读10 —— visual_loop阅读3 + ORB学习

visual_loop

DUtils文件夹

DException

定义异常信息

Timestamp

//成员变量/// Secondsunsigned long m_secs;   // seconds/// Microsecondsunsigned long m_usecs;    // microseconds//主要方法setTime //设置时间戳的时间getTime //获取时间戳中的之间

Random

生成符合高斯分布的随机数

/*** Returns a random number in the range [0..1]* @return random T number in [0..1]*/
template <class T>
static T RandomValue(){return (T)rand()/(T)RAND_MAX;
}/*** Returns a random number in the range [min..max]* @param min* @param max* @return random T number in [min..max]*/
template <class T>
static T RandomValue(T min, T max){return Random::RandomValue<T>() * (max - min) + min;
}/** * Returns a random number from a gaussian distribution* @param mean* @param sigma standard deviation*/
template <class T>
//给定数学期望和标准差
static T RandomGaussianValue(T mean, T sigma)
{// Box-Muller transformationT x1, x2, w, y1;do {//2.就是2.0 是doublex1 = (T)2. * RandomValue<T>() - (T)1.;x2 = (T)2. * RandomValue<T>() - (T)1.;w = x1 * x1 + x2 * x2;} while ( w >= (T)1. || w == (T)0. );w = sqrt( ((T)-2.0 * log( w ) ) / w );y1 = x1 * w;return( mean + y1 * sigma );
}

生成符合高斯分布或者其他任意分布的随机数 https://www.cnblogs.com/mightycode/p/8370616.html

DVision文件夹

DVision.h

DVision本身是一个开源的库,在python和c++中都有相应的依赖和库,具有计算机视觉功能的类的集合。

本项目应该是嵌入了该开源库的部分内容。

在文件内部定义了一个命名空间DVision,但是里面并没有内容(应该是将原本的库中命名空间中的内容删除了)

BRIEF

BRIEF是ORB特征点中的描述子。为了对BRIEF有更多的了解,我首先学习了《SLAM14讲》中第七讲的特征点的部分,这一部分也主要是以ORB为例进行讲解的。

该文件的作用是对于给定的图像和图像中的关键点,求出每个点的BRIEF描述子。

//成员变量
/// Descriptor length in bits
int m_bit_length;/// Patch size
int m_patch_size;/// Type of pairs
Type m_type;/// Coordinates of test points relative to the center of the patch
std::vector<int> m_x1, m_x2;
std::vector<int> m_y1, m_y2;//关键函数//生成选择的随机点的位置,存储在m_的vector中
void BRIEF::generateTestPoints()//返回给定图像中给定关键点的简要描述符
void BRIEF::compute(const cv::Mat &image,  //图像const std::vector<cv::KeyPoint> &points,   //vector<bitset> &descriptors,  //描述子bool treat_image) const
{const float sigma = 2.f;const cv::Size ksize(9, 9);cv::Mat im;if(treat_image){cv::Mat aux;if(image.depth() == 3){cv::cvtColor(image, aux, CV_RGB2GRAY);}else{aux = image;}cv::GaussianBlur(aux, im, ksize, sigma, sigma);}else{im = image;}assert(im.type() == CV_8UC1);assert(im.isContinuous());// use im nowconst int W = im.cols;const int H = im.rows;descriptors.resize(points.size());//C++的 bitset 在 bitset 头文件中,它是一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1bit空间。std::vector<bitset>::iterator dit; // 存储每个特征子std::vector<cv::KeyPoint>::const_iterator kit;int x1, y1, x2, y2;dit = descriptors.begin();for(kit = points.begin(); kit != points.end(); ++kit, ++dit){dit->resize(m_bit_length);dit->reset();for(unsigned int i = 0; i < m_x1.size(); ++i){x1 = (int)(kit->pt.x + m_x1[i]);y1 = (int)(kit->pt.y + m_y1[i]);x2 = (int)(kit->pt.x + m_x2[i]);y2 = (int)(kit->pt.y + m_y2[i]);if(x1 >= 0 && x1 < W && y1 >= 0 && y1 < H && x2 >= 0 && x2 < W && y2 >= 0 && y2 < H){//判断这两个被选中的像素点的大小if( im.ptr<unsigned char>(y1)[x1] < im.ptr<unsigned char>(y2)[x2] ){//将dit的第i位设置成1dit->set(i);}        } // if (x,y)_1 and (x,y)_2 are in the image} // for each (x,y)} // for each keypoint
}

bitset https://www.cnblogs.com/magisk/p/8809922.html

前置学习

特征点法

基于特征点的前端,长久以来都是视觉里程计的主流方法。

1.1 特征点

视觉里程计的核心问题是如何根据图像估计相机运动。比较方便的做法是:从图像中选择比较有代表性的点,这些点在相机视角发生变化后会保持不变。在经典SLAM问题中,我们称这些点为路标。而在视觉SLAM问题中,路标则是指图像特征

特征(featrue):是图像信息的另一种数字表达形式。

仅凭像素的灰度值特征,不能判定哪些地方是同一个点(灰度值受光照、形变、物体材质的影响严重)。

特征点:图像里一些特别的地方。

一种直观的提取特征点的方式就是在不同图像间辨认角点,确定他们的对应关系。在这种做法中,角点就是所谓的特征

角点的提取算法:Harris角点、FAST角点、GFTT角点…

但是单纯的角点不能满足很多需求(eg:从远处看上去是角点的地方,当相机距离靠近后就可能不再显示为角点了)。为此,出现了很多更加稳定的局部图像特征,如SIFT、SURF、ORB等等。

这些人工设计的特征点能够拥有如下性质:

  • 可重复性(Repeatability):相同的特征点可以在不同的图像中找到
  • 可区别性(Distinctiveness):不同的特征有不同的表述
  • 高效性(Efficiency):同一图像中,特征点的数量应远小于像素的数量
  • 本地性(Locality):特征仅与一小片图像区域相关

特征点:由关键点(Key-Point)和描述子(descriptor)

  • 关键点:是指该特征点在图像里的位置,有些特征点还具有朝向、大小等信息。
  • 描述子:通常是一个向量,按照某种人为设计的方式,描述该关键点周围像素的信息。描述子按照“外观相似的特征应该具有相似的描述子”的原则来设计。因此,只要两个特征点的描述子在向量空间上的距离相近,我们可以认为他们是同样的特征点。

ORB(Oriented FAST and Rotated BRIEF)特征,是目前比较有代表性的实时图像特征。改进了FAST检测子中不具有方向性的问题,采用速度极快的二进制描述子BRIEF(Binary Robust Independenct Elementary Feature)。ORB在保持了特征子具有旋转、尺度不变性的同时,在速度方面提升明显,对于实时性要求很高的SLAM来说是个很好的选择。

1.2 ORB特征

ORB特征由关键点和描述子两部分组成。它的关键点称为“Oriented FAST”,是一种改进的FAST角点;它的描述子称为BRIEF。提取ORB特征分为如下两个步骤:

  1. FAST角点提取:找出图像中的角点。相较于原版的FAST,ORB中计算了特征点的主方向,为后续BRIEF描述子增加了旋转不变特性
  2. BRIEF描述子:对前一步提取出特征点的周围图像区进行描述。ORB和BRIEF进行了一些改进,主要是指在BRIEF中使用了先前计算的方向信息。

FAST关键点

FAST是一种角点,主要检测局部像素灰度变化明显的地方。思想:如果一个像素与邻域的像素差别较大(过亮或者过暗),那么他更可能是角点。

检测过程:

  1. 在图像中选择像素p,假设亮度为Ip。
  2. 设置一个阈值T(不如,Ip的20%)。
  3. 以像素p为中心,选择半径为3的圆上的16个像素点
  4. 假如选取的圆上有连续的N个点的亮度大于Ip+T或者小于Ip-T,那么像素p可以被认为是特征点(N通常取12,即FAST-12)
  5. 循环上述4步,对每一个像素执行相同操作
  • 在FAST-12算法中,为了更加高效,可以添加一项预测试操作,从而快速地排除绝大多数不是角点的像素:对于每个像素,直接检查邻域圆上1 5 9 13个像素的亮度,只有这4个点中有至少3个符合条件,当前像素才可能是一个角点
  • 原始的FAST角点容易出现角点扎堆的现象,所以在第一遍检测完成后,还需要用非极大值抑制,在一定区域内仅仅保留响应极大值的角点,避免角点集中的问题。

FAST角点的优缺点:仅仅比较像素间亮度的差异,所以速度很快;但是重复性不强,分布不均匀;且FAST角点不具备方向信息;由于固定取半径为3的圆,所以存在尺度问题。

针对于FAST角点不具有方向性和尺度的缺点,ORB添加了尺度和旋转的描述。

尺度不变性:由构建图像金字塔,并在金字塔的每一层上检测角点来实现

  • 金字塔底座是原始图像,每往上一层,就对图像进行一个固定倍率的缩放,这样就有了不同分辨率的图像。较小的图像可以看作是远处看过来的场景。在特征匹配算法中,我们可以匹配不同层上的图像,从而实现了尺度不变性。
  • eg:如果相机后退,那么我们应该能够在上一个图像金字塔的上层和下一个图像金字塔的下层中找到匹配

旋转:由灰度质心法实现

  • 计算特征点附近的图像灰度质心。

  • 质心是指以图像灰度值作为权重的中心

  • 步骤:

将这种改进后的FAST称为Oriented FAST。

BRIEF描述子

在提取了Oriented FAST角点后,我们对其中的每一个点计算其描述子。ORB使用改进后的BRIEF特征描述。

BRIEF是一种二进制描述子,其描述向量由0/1组成,这里的0和1编码了关键点附近两个随机像素(比如p和q)的大小关系:如果p比q大,则取1;反之就取0。如果我们随机去了128组这样的p和q,最后就能得到128维由0和1组成的向量。

BRIEF使用了随机选点的比较,速度非常快,而且由于使用二进制进行表达,存储起来也十分方便,适用于实时的图像匹配。

原始的BRIEF描述子不具有旋转不变性,因此在图像发生旋转以后容易丢失。而ORB在FAST特征点提取阶段计算了关键点的方向,所以可以利用方向信息,计算旋转之后的steer BRIEF特征使ORB的描述子具有较好的旋转不变性。

1.3 特征匹配

特征匹配解决了SLAM问题中的数据关联问题。

由于图像特征的局部特性,误匹配的情况广泛存在,而且长期以来一直没有得到有效解决,目前已经成为视觉SLAM中制约性能提成的一大瓶颈。部分原因是因为场景中经常存在大量的重复纹理,使得特征描述非常相似。在这种情况下,仅利用局部特征解决误匹配是非常困难的。

最简单的匹配方法是暴力匹配

对于二进制描述子,可以使用汉明距离作为度量----两个二进制串之间的汉明距离,指的是不同位数的个数

FLANN(快速近似最近邻)算法适用于匹配点数量极多的情况。

非极大值抑制

NMS(non maximum suppression),中文名非极大值抑制,在很多计算机视觉任务中都有广泛应用,如:边缘检测、目标检测等。

NMS顾名思义就是抑制不是极大值的元素,可以理解为局部最大搜索。这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的大小。这里讨论用于目标检测中提取分数最高的窗口。例如在行人检测中,滑动窗口经提取特征,经分类器分类识别后,每个窗口都会得到一个分数。但是滑动窗口会导致很多窗口与其他窗口存在包含或者大部分交叉的情况。这时就需要用到NMS来选取那些邻域里分数最高(是行人的概率最大),并且抑制那些分数低的窗口

NMS在计算机视觉领域有着非常重要的应用,如视频目标跟踪、数据挖掘、3D重建、目标识别以及纹理分析等。

以下图为例,由于滑动窗口,同一个人可能有好几个框(每一个框都带有一个分类器得分)

而我们的目标是一个人只保留一个最优的框:

于是我们就要用到非极大值抑制,来抑制那些冗余的框: 抑制的过程是一个迭代-遍历-消除的过程。

**(1)**将所有框的得分排序,选中最高分及其对应的框:

**(2)**遍历其余的框,如果和当前最高分框的重叠面积(IOU)大于一定阈值,我们就将框删除。

**(3)**从未处理的框中继续选一个得分最高的,重复上述过程。

NSM – 非极大值抑制 https://blog.csdn.net/shuzfan/article/details/52711706

https://www.cnblogs.com/makefile/p/nms.html

FLANN算法

opencv中可以直接调用FLANN库。

FLANN是快速最近邻搜索包(Fast_Library_for_Approximate_Nearest_Neighbors)的简称。它是一个对大数据集和高维特征进行最近邻搜索的算法的集合,而且这些算法都已经被优化过了。在面对大数据集是它的效果要好于BFMatcher。

https://blog.csdn.net/jinxueliu31/article/details/37768995

https://blog.csdn.net/Bluenapa/article/details/88371512

http://www.whudj.cn/?p=920

ROS-3DSLAM(十二)lvi-sam源代码阅读10 —— visual_loop阅读3 + ORB学习相关推荐

  1. C语言编程>第十二周 ③ 已知学生的记录由学号和学习成绩构成,M名学生的数据已存入a结构体数组中。请编写函数fun,该函数的功能是:找出成绩最高的学生记录,通过形参返回主函数。

    已知学生的记录由学号和学习成绩构成,M名学生的数据已存入a结构体数组中.请编写函数fun,该函数的功能是:找出成绩最高的学生记录,通过形参返回主函数(规定只有一个最高分).已给出函数的首部,请完成该函 ...

  2. C++ primer读书记录包括第一部分和第二部分 第二十二次更新2021.9.10

    需要对程序进行恰当的缩进保持程序的可读性 第一章 开始 cout<<c1<<endl;可以视为(cout<<c1)<<endl; cin>> ...

  3. 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

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

  4. 中国大学生服务外包创新创业大赛近五届(八至十二)赛题汇总

    届次 赛题编号 命题企业 题目类别 专业方向 赛题 备注 十二 A01 今目标 应用类 企业服务 小微企业跨组织人才管理系统 1.企业服务--企业服务外包,如法务.财务.人力资源.知识产权.咨询策划. ...

  5. The Inventor Mentor-第十二章 传感器

    第十二章 传感器 本章目标 在阅读完本章节后,我们将有能力做下列事情: l         描述在场景中使用的不同类型的传感器,以及每种传感器的用法. l         理解传感器在延迟队列和定时队 ...

  6. 静态树表查找算法及C语言实现,数据结构算法C语言实现(三十二)--- 9.1静态查找表...

    一.简述 静态查找表又分为顺序表.有序表.静态树表和索引表.以下只是算法的简单实现及测试,不涉及性能分析. 二.头文件 /** author:zhaoyu date:2016-7-12 */ #inc ...

  7. ROS探索总结(十二)——坐标系统

    ROS探索总结(十二)--坐标系统 ubuntu 14.04  indigo版本 转摘自:http://www.guyuehome.com/265 一.tf简介 1.安装turtle包 1 rosde ...

  8. ROS入门笔记(十二):动作编程 (C++)

    ROS入门笔记(十二):动作编程 (C++) 文章目录 01 导读 02 功能包的创建 03 在功能包中创建action(动作) 3.1 自定义action 3.2 在package.xml中添加功能 ...

  9. “云时代架构”经典文章阅读感想十二

    云时代架构"经典文章阅读感想十二 (牛逼的架构师是怎么炼成的?) 前几周阅读的三四十岁的大龄程序员,应该如何保持自己的职场竞争力?中提到如何在35岁左右可以实现掌握有核心竞争力.其中之一便是 ...

  10. ROS探索总结(十)(十一)(十二)——语音控制 机器视觉 坐标系统

    ROS探索总结(十)--语音控制 如今语音识别在PC机和智能手机上炒的火热,ROS走在技术的最前沿当然也不会错过这么帅的技术.ROS中使用了CMU Sphinx和Festival开源项目中的代码,发布 ...

最新文章

  1. CNCC 2019 | 计算领域年度盛会—中国计算机大会10月将在苏州举行
  2. Week4-作业1:阅读与博客
  3. NYOJ 409 郁闷的C小加(三)
  4. 克鲁斯卡尔(Kruskal)算法求最小生成树
  5. JavaScript中的Date对象在Safari与IOS中的“大坑”
  6. 鼠标提上去弹出提示层(定位)
  7. color-loss pytorch实现
  8. 世界上最贵的车是直通车吗?
  9. 修改 Windows Host 文件工具
  10. 【J2EE规范】什么是JNDI
  11. 廖雪峰Java9正则表达式-2正则表达式进阶-3分组匹配
  12. TLSF: Memory allocator real time embedded systems
  13. 读博太孤独?一个人的苦行!
  14. 干草堆——acwing算法题第二天
  15. dm8127 A8 yuv420sp 送入到videoM3编码--已经解决
  16. [RelativeNAS] Relative Neural Architecture Search via Slow-Fast Learning
  17. 硅谷最牛程序员,总是不经意间碾压众人
  18. linux查看php端口,Linux如何查看端口状态
  19. Tomcat-- 掌握汤姆猫,看这一篇文章就够了
  20. 计算机软件跨考教育学优点,我是英语专业学生,想考研。但专业优势不突出,想跨考教育学。不了解考研方向就业方向及前景,建议?谢啦...

热门文章

  1. ICCV 2017:训练GAN的16个技巧,2400+星(PPT)
  2. 数据库可靠性/可用性、稳定性RTO/RPO
  3. 数据科学数据清理和可视化,适合使用python的初学者
  4. git 入门笔记-基础命令
  5. 计算机等级考试(包括二级),包括几个级别?
  6. 独立显卡驱动安装不成功解决办法
  7. python flask服务器假死_IE浏览器访问Flask自带服务器假死问题解决方法 - digwtx
  8. 【金猿案例展】某新型股份制商业银行——客服智能质检系统建设
  9. 2021年春季 PAT乙级(复盘)
  10. win10下修改C盘用户文件夹名