ORB-SLAM2-学习记录1-ORB特征提取

ORB-SLAM2-学习记录1-ORB特征提取

代码注释参考
代码讲解参考
主要针对ORB-SLAM2中视觉里程计部分学习记录

函数运行顺序:

 1. ORBextractor 
 2. operator()
 3. ComputePyramid
 4. ComputeKeyPointsOctTree
 5. DistributeOctTree
 6. DivideNode
 7. computeOrientation
 8. computeDescriptors

处理单张图像效果,只做特征提取部分:
在这里插入图片描述

程序调用:

    ORB_SLAM2::ORBextractor* mpORBextractor;
    mpORBextractor = new ORB_SLAM2::ORBextractor(nFeatures,scaleFactor,nLevels,iniThFAST,minThFAST);
    std::vector<cv::KeyPoint> mvKeys;
    cv::Mat mDescriptors;
    (*mpORBextractor)(mImGray,cv::Mat(),mvKeys,mDescriptors);
1.ORBextractor

特征点提取器的构造函数
难点:

        LOG_INFO("This is for orientation");
        //This is for orientation
        //下面的内容是和特征点的旋转计算有关的
        // pre-compute the end of a row in a circular patch
        //预先计算圆形patch中行的结束位置
        //+1中的1表示那个圆的中间行
        umax.resize(HALF_PATCH_SIZE + 1);

        //cvFloor返回不大于参数的最大整数值,cvCeil返回不小于参数的最小整数值,cvRound则是四舍五入
        int v,		//循环辅助变量
        v0,		//辅助变量
        vmax = cvFloor(HALF_PATCH_SIZE * sqrt(2.f) / 2 + 1);	//计算圆的最大行号,+1应该是把中间行也给考虑进去了
        //NOTICE 注意这里的最大行号指的是计算的时候的最大行号,此行的和圆的角点在45°圆心角的一边上,之所以这样选择
        //是因为圆周上的对称特性

        //这里的二分之根2就是对应那个45°圆心角

        int vmin = cvCeil(HALF_PATCH_SIZE * sqrt(2.f) / 2);
        //半径的平方
        const double hp2 = HALF_PATCH_SIZE*HALF_PATCH_SIZE;

		//*通过对称计算umax,0<=v<=vmax*//
        //利用圆的方程计算每行像素的u坐标边界(max)
        for (v = 0; v <= vmax; ++v)
            umax[v] = cvRound(sqrt(hp2 - v * v));		//结果都是大于0的结果,表示x坐标在这一行的边界

        // Make sure we are symmetric
        //这里其实是使用了对称的方式计算上四分之一的圆周上的umax,目的也是为了保持严格的对称(如果按照常规的想法做,由于cvRound就会很容易出现不对称的情况,
        //同时这些随机采样的特征点集也不能够满足旋转之后的采样不变性了)
		
		//*通过对称计算umax,vmin<=v<=HALF_PATCH_SIZE*//
        for (v = HALF_PATCH_SIZE, v0 = 0; v >= vmin; --v)
        {
            while (umax[v0] == umax[v0 + 1])
                ++v0;
            umax[v] = v0;
            ++v0;
        }
2.operator()

用仿函数(重载括号运算符)方法来计算图像特征点,这个函数是该部分的流程化函数,负责整个特征提取计算流程的调用

3.ComputePyramid

构建图像金字塔
将图像进行“补边”,EDGE_THRESHOLD区域外的图像不进行FAST角点检测

//把源图像拷贝到目的图像的中央,四面填充指定的像素。图片如果已经拷贝到中间,只填充边界
//这样做是为了能够正确提取边界的FAST角点
//EDGE_THRESHOLD指的这个边界的宽度,由于这个边界之外的像素不是原图像素而是算法生成出来的,所以不能够在EDGE_THRESHOLD之外提取特征点
copyMakeBorder(mvImagePyramid[level],//源图像
				temp,//目标图像(此时其实就已经有大了一圈的尺寸了)
                EDGE_THRESHOLD, EDGE_THRESHOLD, 			//top & bottom 需要扩展的border大小
                EDGE_THRESHOLD, EDGE_THRESHOLD,			//left & right 需要扩展的border大小
                BORDER_REFLECT_101+BORDER_ISOLATED);     //扩充方式,opencv给出的解释:

                if(level == 1)
                {
                    cv::imshow("Result.jpg", temp);
                }

扩充像素后图像
在这里插入图片描述

else
{
     //对于第0层未缩放图像,直接将图像深拷贝到temp的中间,并且对其周围进行边界扩展。此时temp就是对原图扩展后的图像
     copyMakeBorder(image,//这里是原图像
                    temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
                    BORDER_REFLECT_101);
     cv::imshow("Result.jpg", temp);//只是对原图拓展
}

第0层图像,拓展后
第0层图像

4.ComputeKeyPointsOctTree

以八叉树分配特征点的方式,计算图像金字塔中的特征点,分布均匀

4.ComputeKeyPointsOld

使用传统的方法提取并平均分配图像的特征点,虽然分布不均匀,但是颜色变化明显的地方较多
效果
在这里插入图片描述

5.DistributeOctTree

对于某一图层,分配其特征点,通过八叉树的方式

6.DivideNode

在八叉树分配特征点的过程中,实现一个节点分裂为4个节点的操作

7.computeOrientation

这个函数用于计算特征点的方向,这里是返回角度作为方向

8.computeDescriptors

计算某层金字塔图像上特征点的描述子

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值