void ORBextractor::ComputePyramid(cv::Mat image)
{
for (int level = 0; level < nlevels; ++level)
{
float scale = mvInvScaleFactor[level];
//尺寸为该层的缩放因子
Size sz(cvRound((float)image.cols*scale), cvRound((float)image.rows*scale));
//应该是计算截取缩放后的尺寸对于Size 类赋值
Size wholeSize(sz.width + EDGE_THRESHOLD*2, sz.height + EDGE_THRESHOLD*2);
Mat temp(wholeSize, image.type()), masktemp;
//根据计算的出来的尺寸构造缓冲图片
mvImagePyramid[level] = temp(Rect(EDGE_THRESHOLD, EDGE_THRESHOLD, sz.width, sz.height));
/*对于存放图片矩阵进行初始化,该图片为左上角坐标(EDGE_THRESHOLD, EDGE_THRESHOLD),宽高为width, height的图片
// Compute the resized image*/
if( level != 0 )
{
resize(mvImagePyramid[level-1], mvImagePyramid[level], sz, 0, 0, INTER_LINEAR);
//这里的意思是将mvImagePyramid[level-1]存放的图片,调整为sz后赋值进入mvImagePyramid[level]
copyMakeBorder(mvImagePyramid[level], temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
BORDER_REFLECT_101+BORDER_ISOLATED);
//将mvImagePyramid原图像拷贝到temp中间并对它填充每个空间指定的像素 EDGE_THRESHOLD
//对于边界填充的类型参考博客https://blog.csdn.net/maweifei/article/details/72773062
}//方便卷积做边界补充
else
{
copyMakeBorder(image, temp, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD, EDGE_THRESHOLD,
BORDER_REFLECT_101);//将image中的图片通过调整为特定的格式进入temp
}
}
}
} //namespace ORB_SLAM
对于该函数的最终流程我进行大致如下描述:首先我们计算每层金字塔的尺寸大小size,然后在第一次循环中利用temp存放image调整后的原图(注意在前面temp与mvImagePyramid[0]建立了浅拷贝的关系,当temp被修改后对应的mvImagePyramid[0]也会相应改变,读者对于这里表示不理解可以在截取此段代码并在该代码中添加输出图像来判断)
我们以第二次循环为例,size类 sz计算每层的图片大小,通过在temp中利用rect截取相同的大小赋值给mvImagePyramid【1】,然后再将调整后的
mvImagePyramid【0】中的图片调整后输入mvImagePyramid【1】,mvImagePyramid【1】特定调整后转入temp,(注意temp与mvImagePyramid[1]建立浅拷贝的关系当temp改变,mvImagePyramid[1]也会改变)经过循环后,mvImagePyramid每层中都存放了对应的金字塔图像
这就是我对,构造金字塔函数的浅显理解,小白一枚,大佬亲喷。
协作者:@