ORB-SLAM2代码详读-------特征点检测

版权声明:此文章为原创,可任意转载,但是需声明出处 https://blog.csdn.net/qq_41981025/article/details/83792443

目录

1 特征点检测的基本步骤

1.1 输入图像

1.2 图像金字塔

1.3 计算每层FAST关键点

1.4 计算FAST关键点的描述子

1.5 计算特征点的尺度坐标


1 特征点检测的基本步骤

  输入图像----图像金字塔----计算每层FAST关键点----计算FAST关键点描述子

 先列出这个类里面关键的函数和变量

//创建图像金字塔,这里每层只是降采样
 void ComputePyramid(cv::Mat image);
//计算每一层的关键点
 void ComputeKeyPointsOctTree(std::vector<std::vector<cv::KeyPoint> >& allKeypoints);
//控制关键点个数
std::vector<cv::KeyPoint> DistributeOctTree(const std::vector<cv::KeyPoint>& vToDistributeKeys, const int &minX,const int &maxX, const int &minY, const int &maxY, const int &nFeatures, const int &level);
//计算描述子多需要的点的位置
std::vector<cv::Point> pattern;
//需要提取的总的特征点个数
int nfeatures;
//尺度因子
double scaleFactor;
//金字塔层数
int nlevels;
//初始FAST阈值
int iniThFAST;
//最小FAST阈值
int minThFAST;
//每层关键点个数
std::vector<int> mnFeaturesPerLevel;

  下面来看看每个步骤对应的代码

   代码有些地方也没有完全搞明白,欢迎交流!

扫描二维码关注公众号,回复: 5035008 查看本文章

1.1 输入图像

   特征点检测的入口是ORBextractor类,其中最主要的是

void operator()( cv::InputArray image, cv::InputArray mask,
      std::vector<cv::KeyPoint>& keypoints,
      cv::OutputArray descriptors);

 参数包括输入图像image、输入模板mask(好像没有用到)、存储关键点的向量keypoints、存储描述子的数组descriptors

1.2 图像金字塔

 这里使用的是简化版的图像金字塔,每一层大小被改变,都是上一层*尺度因子,函数是

void ORBextractor::ComputePyramid(cv::Mat image)

  输入参数image,主要目的是计算每层图像,并且处理边界

  主要的语句如下:

//每层缩放系数
float scale = mvInvScaleFactor[level];
//计算图像大小
Size sz(cvRound((float)image.cols*scale), cvRound((float)image.rows*scale)); 
//将图像进行缩放(双线性插值)
resize(mvImagePyramid[level-1], mvImagePyramid[level], sz, 0, 0, cv::INTER_LINEAR); 
//处理边界 
copyMakeBorder(mvImagePyramid[level], temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,BORDER_REFLECT_101+BORDER_ISOLATED);     

1.3 计算每层FAST关键点

void ORBextractor::ComputeKeyPointsOctTree(vector<vector<KeyPoint> >& allKeypoints)

  输入参数allKeypoints,用来存储每层关键点

  步骤:

           将每层图像分成多个30*30的小格子(cell)

           在每个小格子里面找FAST关键点(如果第一次没找到,就减小阈值再找,里面包括非极大值抑制)

           根据事先给定的每层图像中特征点的多少(根据尺度,按等比数列的方式给出)来进行局部关键点剔除

//给定总特征点个数,根据等比数列求出最下面图像特征点个数
float nDesiredFeaturesPerScale = nfeatures*(1 - factor)/(1 - (float)pow((double)factor, (double)nlevels))
//记录每层特征点个数
mnFeaturesPerLevel[level] = cvRound(nDesiredFeaturesPerScale); //四舍五入
//计算上面一层特征点个数
nDesiredFeaturesPerScale *= factor;

         进行局部关键点剔除的函数是(这个函数最多将图像分成长/宽*16块,在每块中选取一个响应值最大的保留)//todo  是不是有点少  //参数:每层找到的关键点、有效区域、每层允许的最多关键点个数、金字塔层数

vector<cv::KeyPoint> ORBextractor::DistributeOctTree(const vector<cv::KeyPoint>& vToDistributeKeys, const int &minX,const int &maxX, const int &minY, const int &maxY, const int &N, const int &level)

         最后计算每个关键点-质心向量的夹角(里面计算灰度质心的公式有点变形)

static void computeOrientation(const Mat& image, vector<KeyPoint>& keypoints, const vector<int>& umax) 

1.4 计算FAST关键点的描述子

  首先对每层图像进行高斯滤波,然后计算256维描述子,计算描述子函数如下:

  //输入参数:关键点位置 kpt、操作图像 img、要比较的位置pattern、描述子输出地址

static void computeOrbDescriptor(const KeyPoint& kpt,const Mat& img, const Point* pattern,uchar* desc)

计算步骤是:

                     先进行坐标变换(原来的基底乘以过渡矩阵,这里的过渡矩阵是旋转矩阵,旋转角为质心与关键点连线与原来X轴的夹角)

                     然后按照原来定义的比较点位置进行比较,输出描述向量

1.5 计算特征点的尺度坐标

未完待续......

猜你喜欢

转载自blog.csdn.net/qq_41981025/article/details/83792443
今日推荐