ORBSLAM特征提取流程
特征提取函数流程
这部分工作是主要是在ORBSLAM中的工作,这是ORBSLAM2在选取特征点中所采取的一种策略。在今年的暑假也就是202007将这个部分提取出来整合成为一个模块。现在九月份来做一个总结工作。
这里不会详细去讲述具体的数据结构以及各种解决这个办法的trick,着重于整个流程的简介。关于trick应该会在之后的一些文章中去解释说明一下。
## 入口
整个特征提取的入口首先是在Tracking.cc中构造Frame的部分
1 | if(mState==NOT_INITIALIZED || mState==NO_IMAGES_YET) |
进入到Frame的构造函数,在一系列规定ORB提取的参数之后其进行Frame类内的一个函数ExtractORB来做单幅图像的一个特征点提取工作。
1 | // ORB extraction |
进入函数之后,可以发现Frame类中一个ORBextractor的成员变量实例,并使用重载operator()来做实现特征点提取的工作。
1 | void Frame::ExtractORB(int flag, const cv::Mat &im) |
所以真正的函数的入口就是在ORBextractor.cc文件中的函数括号的重载
1 | /** |
对于这个函数,其主要的功能就是计算图像中的特征点位置以及各个特征点所具有的特征点描述
Step1: 构建图像金字塔
首先需要对原始图像进行尺度上的变换,构建不同尺度的金字塔,所使用的主要方式就是使用OpenCV自带的函数resize。
这里需要注意的就是,构建金字塔的所有参数就是之前在Frame类中所赋予的,在ORBextractor的构造函数中将这些参数传递给ORBex这个类中。
1 | // Pre-compute the scale pyramid |
Step2: 计算图像特征点
这里所提取得到的特征点是均匀化之后的,所使用的是一个二维vector来进行存储
这里二维的vector,第一维存储的是金字塔的层数,第二维存储的是那一层金字塔图像里提取的所有特征点
1 | vector < vector<KeyPoint> > allKeypoints; |
Step3: 构造存储描述子的容器Mat
到遍历金字塔每一层图像之前的操作就是在做给描述子初始化的工作,也就是对每一个描述子给定一个初始的大小与空间上的分配。
1 | // 如果本图像金字塔中没有任何的特征点 |
这里重新新建了一个变量,复制矩阵。
Step4: 遍历每层图像,做高斯模糊
对金字塔每层的图像做一个高斯模糊,来防止图像噪声。
在提取特征点的时候用的是清晰的原图像,计算描述子的时候,用的是高斯模糊之后的图像
1 | GaussianBlur(workingMat, // 源图像 |
Step5: 计算高斯模糊之后的描述子
1 | computeDescriptors(workingMat, //高斯模糊之后的图层图像 |
Step6: 将非0层的特征点坐标恢复到第0层下
也就是将金字塔高层的特征点映射回原图像中
1 | if (level != 0) |