数据流角度看DSO(四)

前面几帧的处理都是为初始化做准备,到第八帧才满足进行初始化的条件。
第八帧
前面直到else if(coarseInitializer->trackFrame(fh, outputWrapper))的处理均与第2帧一样,在当前帧的时候,对第一帧进行跟踪之后会返回ture,表示可以进行初始化操作。
初始化操作:

initializeFromInitializer(fh);

initializeFromInitializer(fh)函数解析:
1.添加第一帧:

	FrameHessian* firstFrame = coarseInitializer->firstFrame;
	firstFrame->idx = frameHessians.size();
	frameHessians.push_back(firstFrame);
	firstFrame->frameID = allKeyFramesHistory.size();
	allKeyFramesHistory.push_back(firstFrame->shell);

在这里新定义vector:frameHessiansallKeyFramesHistory,并把第一帧加入进去,(这两个容器应该是只存储关键帧的相关信息,此时里面仅有第一帧)
2.第一帧加入优化:

	ef->insertFrame(firstFrame, &Hcalib);
	setPrecalcValues();

利用ef->insertFrame(firstFrame, &Hcalib),将第一帧加入到优化后端energyFunction,加入过程为:创建当前帧的EFFrame对象eff,并将其加入到vector:frames,同时将表示energyFunction中图像帧数量的nFrames加1(用来确定优化变量的维数,每个图像帧是8维),并且建立当前帧和eff 的关联:fh->efFrame = eff;,然后执行setAdjointsF();makeIDX();
利用setAdjointsF(Hcalib);建立两帧之间的相对状态对主导帧和目标帧的状态的求导。(因为优化的变量是各帧的绝对状态而不是相对状态,在后面的滑窗优化中会使用到)建立方法为:定义两个数组,分别用来存储主导帧和目标帧,adHost = new Mat88[nFrames*nFrames]; adTarget = new Mat88[nFrames*nFrames];然后会传递给数组adHostFadTargetF,这里是会建立尽可能多的主导帧和目标帧的关联,即遍历所有帧,将所有帧作为当前帧的目标帧。
利用makeIDX();将点加入到vector:allPoints,然后建立residual的主导帧id和目标帧id,但是此时未在第一帧中加入点。建立过程为:遍历EFFrame,遍历EFPoint,加入到vector:allPoints,遍历EFResidual,建立hostIDX和targetIDX。
setPrecalcValues();会建立所有帧的目标帧,并且进行主导帧和目标帧之间相对状态的预计算,实现的函数见下,计算的量有:leftToLeftPRE_RTllPRE_tTllPRE_KRKiTllPRE_RKiTllPRE_KtTllPRE_aff_modePRE_b0_mode

fh->targetPrecalc[i].set(fh, frameHessians[i], &Hcalib);

然后利用:ef->setDeltaF(&Hcalib);建立相关量的微小扰动,包括:adHTdeltaF[idx]f->deltaf->delta_prior
3.初始第一帧的各种点,包括:pointHessianspointHessiansMarginalizedpointHessiansOut

	firstFrame->pointHessians.reserve(wG[0]*hG[0]*0.2f);
	firstFrame->pointHessiansMarginalized.reserve(wG[0]*hG[0]*0.2f);
	firstFrame->pointHessiansOut.reserve(wG[0]*hG[0]*0.2f);

4.利用前面帧对第一帧的跟踪更新的逆深度,计算尺度因子rescaleFactor(相对的),并且根据相关参数设置第一帧保持的点的数目:keepPercentage

	float sumID=1e-5, numID=1e-5;
	for(int i=0;i<coarseInitializer->numPoints[0];i++)
	{
		sumID += coarseInitializer->points[0][i].iR;
		numID++;
	}
	float rescaleFactor = 1 / (sumID / numID);

5.将第一帧的未成熟点生成PointHessian,并且设置PointHessian的相关参数,存储到第一帧的容器pointHessians中,然后利用insertPoint()加入到后端优化中。注意:前面分析对第一帧选点时说到是在每层图像金字塔都会进行选点,但是此时生成PointHessian仅利用第0层(即原始图像层)选取的点。
在应用构造函数创建类ImmaturePoint的对象pt时,会计算点的权重:weights[idx]

		Pnt* point = coarseInitializer->points[0]+i;
		ImmaturePoint* pt = new ImmaturePoint(point->u+0.5f,point->v+0.5f,firstFrame,point->my_type, &Hcalib);
		if(!std::isfinite(pt->energyTH)) { delete pt; continue; }
		pt->idepth_max=pt->idepth_min=1;
		PointHessian* ph = new PointHessian(pt, &Hcalib);
		delete pt;
		if(!std::isfinite(ph->energyTH)) {delete ph; continue;}
		ph->setIdepthScaled(point->iR*rescaleFactor);
		ph->setIdepthZero(ph->idepth);
		ph->hasDepthPrior=true;
		ph->setPointStatus(PointHessian::ACTIVE);
		firstFrame->pointHessians.push_back(ph);
		ef->insertPoint(ph);

insertPoint()中会生成PointHessian类型的点phEFPoint类型的efpefp,包含点ph以及其主导帧host。按照push_back的先后顺序对idxInPoints进行编号, nPoints表示后端优化中点的数量。

	EFPoint* efp = new EFPoint(ph, ph->host->efFrame);
	efp->idxInPoints = ph->host->efFrame->points.size();
	ph->host->efFrame->points.push_back(efp);
	nPoints++;
	ph->efPoint = efp;

6.通过前面所有帧对第一帧的track以及optimization得到第一帧到第八帧的位姿:firstToNew,并对平移部分利用尺度因子进行处理。

SE3 firstToNew = coarseInitializer->thisToNext;
	firstToNew.translation() /= rescaleFactor;

7.设置第一帧和第八帧的相关参数。

firstFrame->shell->camToWorld = SE3();
firstFrame->shell->aff_g2l = AffLight(0,0);
firstFrame->setEvalPT_scaled(firstFrame->shell->camToWorld.inverse(),firstFrame->shell->aff_g2l);
firstFrame->shell->trackingRef=0;
firstFrame->shell->camToTrackingRef = SE3();

newFrame->shell->camToWorld = firstToNew.inverse();
newFrame->shell->aff_g2l = AffLight(0,0);
newFrame->setEvalPT_scaled(newFrame->shell->camToWorld.inverse(),newFrame->shell->aff_g2l);
newFrame->shell->trackingRef = firstFrame->shell;
newFrame->shell->camToTrackingRef = firstToNew.inverse();

8.初始化成功:initialized=true;至此初始化已经成功了,接下的操作是将第八帧作为关键帧进行处理。

利用deliverTrackedFrame(fh, true)对当前图像帧处理,实现关键帧和非关键帧的区分(当前为true,将当前帧作为关键帧进行处理)

	if(needKF) makeKeyFrame(fh);

(感觉再接着写下去,博客会过长,接下一篇博客吧!)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值