DSO代码梳理(一)

本科毕设就是利用开源DSO代码做的,运行了TUM单目数据集,EuRoC数据集,TUM-RGBD数据集。前段时间看了ORB-SLAM2的track线程,感觉ORB的代码比DSO的代码逻辑更清晰,可读性更强。虽然自己之前做毕设的时候梳理过DSO的代码流程,但是现在已经忘了好多,感觉还是有必要再重新梳理一遍。为了加深自己的理解,打算利用博客记录一下。

对于运行不同的数据集(主要区别是光度校准文件),DSO所需参数会不一样,在这里以运行TUM单目数据集为例。另外有个坑提醒一下:运行DSO时,数据集文件的路径下必须要有一个times.txt文件,里面的内容是图像名称,时间戳,曝光时间(可以没有),如果没有这个文件,那么DSO输出的位姿估计文件里面是空白的。

  • 运行参数
for(int i=1; i
参数(只是一部分,其他感觉不重要) 意义
preset= 是否强制实时执行
mode= 是否进行光度校准
files= 图像文件 ,source
calib= 相机内参 calib
vignette= 渐晕图 vignette
gamma= 响应函数校准 gammaCalib
/////文件读取
ImageFolderReader* reader = new ImageFolderReader(source,calib, gammaCalib, vignette);
ImageFolderReader(std::string path, std::string calibFile, std::string gammaFile, std::string vignetteFile)
	{
		this->path = path;
		this->calibfile = calibFile;
#if HAS_ZIPLIB
		ziparchive=0;
		databuffer=0;
#endif

		isZipped = (path.length()>4 && path.substr(path.length()-4) == ".zip");
		if(isZipped)  //解压图片文件
		{
#if HAS_ZIPLIB
			int ziperror=0;
			ziparchive = zip_open(path.c_str(),  ZIP_RDONLY, &ziperror);
			if(ziperror!=0)
			{
				printf("ERROR %d reading archive %s!\n", ziperror, path.c_str());
				exit(1);
			}
			files.clear();
			int numEntries = zip_get_num_entries(ziparchive, 0); //图片数量
			for(int k=0;kgetOriginalSize()[0];  //内参文件第二行:原始图像大小
		heightOrg = undistort->getOriginalSize()[1];
		width=undistort->getSize()[0];               //内参文件第四行:输出图像大小
		height=undistort->getSize()[1];
		// load timestamps if possible.
		loadTimestamps();   //加载时间戳,需要有times.txt文件
		printf("ImageFolderReader: got %d files in %s!\n", (int)files.size(), path.c_str());

	}
///图像帧处理
 for(int ii=0;ii<(int)idsToPlay.size(); ii++)  
   {
           	if(preload)
                img = preloadedImages[ii];
            else
                img = reader->getImage(i); //图像进行光度校准的入口
                //图像帧处理入口
            if(!skipFrame) fullSystem->addActiveFrame(img, i);  //此处的img进行了G的映射,以及乘了渐晕因子
    }
void FullSystem::addActiveFrame( ImageAndExposure* image, int id )
{

    if(isLost) return;
	boost::unique_lock lock(trackMutex);
	// =========================== add into allFrameHistory =========================
	FrameHessian* fh = new FrameHessian();
	FrameShell* shell = new FrameShell();
	shell->camToWorld = SE3(); 		// no lock required, as fh is not used anywhere yet.
	shell->aff_g2l = AffLight(0,0);
    shell->marginalizedAt = shell->id = allFrameHistory.size();
    shell->timestamp = image->timestamp;
    shell->incoming_id = id;
	fh->shell = shell;
	allFrameHistory.push_back(shell);
	// =========================== make Images / derivatives etc. =========================
	fh->ab_exposure = image->exposure_time;
    fh->makeImages(image->image, &Hcalib);
	if(!initialized)
	{
		// use initializer!
		if(coarseInitializer->frameID<0)	// first frame set. fh is kept by coarseInitializer.
		{
			coarseInitializer->setFirst(&Hcalib, fh);
		}
		else if(coarseInitializer->trackFrame(fh, outputWrapper))	// if SNAPPED
		{
			initializeFromInitializer(fh);
			lock.unlock();
			deliverTrackedFrame(fh, true);
		}
		else
		{
			// if still initializing
			fh->shell->poseValid = false;
			delete fh;
		}
		return;
	}
	else	// do front-end operation.
	{
		// =========================== SWAP tracking reference?. =========================
		if(coarseTracker_forNewKF->refFrameID > coarseTracker->refFrameID)
		{
			boost::unique_lock crlock(coarseTrackerSwapMutex);
			CoarseTracker* tmp = coarseTracker; coarseTracker=coarseTracker_forNewKF; coarseTracker_forNewKF=tmp;
		}
		Vec4 tres = trackNewCoarse(fh);
		if(!std::isfinite((double)tres[0]) || !std::isfinite((double)tres[1]) || !std::isfinite((double)tres[2]) || !std::isfinite((double)tres[3]))
        {
            printf("Initial Tracking failed: LOST!\n");
			isLost=true;
            return;
        }
		bool needToMakeKF = false;
		if(setting_keyframesPerSecond > 0)
		{
			needToMakeKF = allFrameHistory.size()== 1 ||
					(fh->shell->timestamp - allKeyFramesHistory.back()->timestamp) > 0.95f/setting_keyframesPerSecond;
		}
		else
		{
			Vec2 refToFh=AffLight::fromToVecExposure(coarseTracker->lastRef->ab_exposure, fh->ab_exposure,
					coarseTracker->lastRef_aff_g2l, fh->shell->aff_g2l);
			// BRIGHTNESS CHECK
			needToMakeKF = allFrameHistory.size()== 1 ||
					setting_kfGlobalWeight*setting_maxShiftWeightT *  sqrtf((double)tres[1]) / (wG[0]+hG[0]) +
					setting_kfGlobalWeight*setting_maxShiftWeightR *  sqrtf((double)tres[2]) / (wG[0]+hG[0]) +
					setting_kfGlobalWeight*setting_maxShiftWeightRT * sqrtf((double)tres[3]) / (wG[0]+hG[0]) +
					setting_kfGlobalWeight*setting_maxAffineWeight * fabs(logf((float)refToFh[0])) > 1 ||
					2*coarseTracker->firstCoarseRMSE < tres[0];
		}
        for(IOWrap::Output3DWrapper* ow : outputWrapper)
            ow->publishCamPose(fh->shell, &Hcalib);
		lock.unlock();
		deliverTrackedFrame(fh, needToMakeKF);
		return;
	}
}

你可能感兴趣的:(DSO代码梳理(一))