我是靠谱客的博主 凶狠石头,最近开发中收集的这篇文章主要介绍ORB-SLAM2(代码详解),特征提取与描述(ORBextractor):图像金字塔的计算,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

ORB-SLAM2,其实有很多大牛已将代码分析的很彻底了,在此写下博客以加深印象,会将自己收集的资料尽量集中在这里

本文主要讲ORBextractor中的ComputePyramid()部分,在获取目标图像后计算图像金字塔(nlevels张不同分辨率的图片),为FAST关键点在各层上的计算提供支持。本文涉及到的一些尺度参数参见ORBextractor()构造函数进行的参数计算部分。

//计算图像金字塔,按一定的尺度比例获取nlevels张分辨率不同的图像
void ORBextractor::ComputePyramid(cv::Mat image)
{
	/**
	//在同一个图像金字塔中,两个参数只是图像相邻层比较时上下或者下上的区别
	std::vector<float> mvScaleFactor;          //是用来存储金字塔中每层图像对应的尺度因子的vector变量
    std::vector<float> mvInvScaleFactor;       //可以理解为逆向尺度
    **/
	for (int level = 0; level < nlevels; ++level)
    {
        float scale = mvInvScaleFactor[level];
        //原图像的尺寸
        Size sz(cvRound((float)image.cols*scale), cvRound((float)image.rows*scale));
        //相当于给原图像加边,在计算关键点时便不需要检测所加边缘,又能保证原图像边缘的关键点也能检测
        Size wholeSize(sz.width + EDGE_THRESHOLD*2, sz.height + EDGE_THRESHOLD*2);
         //temp通过Mat类的一种构造函数获得了尺寸及图像的类型
        Mat temp(wholeSize, image.type()), masktemp;
        //temp通过=与mvImagePyramid[level]相关联
        mvImagePyramid[level] = temp(Rect(EDGE_THRESHOLD, EDGE_THRESHOLD, sz.width, sz.height));
 
        //在temp被改变时,mvImagePyramid[level]将做相同的改变,故最终得到mvImagePyramid[level](含有分辨率不同的图像)
        if( level != 0 )
		{
			//把原图缩放成sz大小,同时改变的还有内容
            resize(mvImagePyramid[level-1], mvImagePyramid[level], sz, 0, 0, INTER_LINEAR);
			//在图像周围以对称的方式加一个宽度为EDGE_THRESHOLD的边,便于后面的计算
			//在后面计算特征点时的时候省去边缘的判断;
			// 可以省去加边操作,然后在后面计算的时候做原图像的边缘判断即可
			copyMakeBorder(mvImagePyramid[level], temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
                           BORDER_REFLECT_101+BORDER_ISOLATED);            
        }
        else//第一张为原图分辨率,无需缩放,进行了加边操作
        {
            copyMakeBorder(image, temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
                           BORDER_REFLECT_101);    
        }
    }
}

Size:尺寸类別,成员有width和height(int类型),只是尺寸信息,其原型及用法如下:

//简略的原型
Size  size_name(int width, int height);
//第一种初始化
Size  size_name1(150, 100);
//第一种初始化  
Size size_name2;
size_name2.width = 150;
size_name2.height = 100;

cvRound():返回跟参数最接近的整数值,相当于四舍五入。
Rect 矩形类用法,参考https://blog.csdn.net/sinat_38102206/article/details/80996897

resize函数来改变图像的大小,函数原型如下:

void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR );

各参数含义:
src : 输入,原图像,即待改变大小的图像;
dst : 输出,改变大小之后的图像,这个图像和原图像具有相同的内容,只是大小和原图像不一样而已;
dsize: 输出图像的大小。如果这个参数不为0,那么就代表将原图像缩放到这个Size(width,height)指定的大小;如果这个参数
为0,那么原图像缩放之后的大小就要通过下面的公式来计算:
dsize = Size(round(fxsrc.cols), round(fysrc.rows))
其中,fx和fy就是下面要说的两个参数,是图像width方向和height方向的缩放比例。
fx : width方向的缩放比例,如果它是0,那么它就会按照(double)dsize.width/src.cols来计算;
fy : height方向的缩放比例,如果它是0,那么它就会按照(double)dsize.height/src.rows来计算;
interpolation:这个是指定插值的方式(具体可查,这里不再赘述)

copyMakeBorder()用来拓展边界,函数原型如下:

void copyMakeBorder( InputArray src,  OutputArray dst,int top,  int bottom,  int left,  int right,  int borderType,
                     const Scalar& value = Scalar())

各参数含义:
src:输入的数组。
dst:输出的拓展边界后的数组。
top:在src上边界向上拓展的行数。
bottom:在src下边界向下拓展的行数。
left:在src的左边界向左拓展的列数。
right:在src的右边界向右拓展的列数。
borderType:上一节中的边界拓展策略中的一个。
value:当你的边界策略使用的是BORDER_CONSTANT的时候,此处是指边界处填写的常数值。(具体可查,这里不再赘述)

结束语:文中如有理解的不到位之处,望告知,谢谢

最后

以上就是凶狠石头为你收集整理的ORB-SLAM2(代码详解),特征提取与描述(ORBextractor):图像金字塔的计算的全部内容,希望文章能够帮你解决ORB-SLAM2(代码详解),特征提取与描述(ORBextractor):图像金字塔的计算所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部