DSO代码梳理(一)

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

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

  • 运行参数
for(int i=1; i<argc;i++)
	parseArgument(argv[i]);   //利用此函数读取参数
void parseArgument(char* arg)     //参数设置
{
	if(1==sscanf(arg,"files=%s",buf))
	{
		source = buf;
		printf("loading data from %s!\n", source.c_str());
		return;
	}
		if(1==sscanf(arg,"calib=%s",buf))
	{
		calib = buf;
		printf("loading calibration from %s!\n", calib.c_str());
		return;
	}

	if(1==sscanf(arg,"vignette=%s",buf))
	{
		vignette = buf;
		printf("loading vignette from %s!\n", vignette.c_str());
		return;
	}
	if(1==sscanf(arg,"gamma=%s",buf))
	{
		gammaCalib = buf;
		printf("loading gammaCalib from %s!\n", gammaCalib.c_str());
		return;
	}
}
参数(只是一部分,其他感觉不重要)意义
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;k<numEntries;k++)
			{
				const char* name = zip_get_name(ziparchive, k,  ZIP_FL_ENC_STRICT);
				std::string nstr = std::string(name);
				if(nstr == "." || nstr == "..") continue;
				files.push_back(name);
			}
			printf("got %d entries and %d files!\n", numEntries, (int)files.size());
			std::sort(files.begin(), files.end());
#else
			printf("ERROR: cannot read .zip archive, as compile without ziplib!\n");
			exit(1);
#endif
		}
		else
			getdir (path, files);//如果没压缩,直接读取
		undistort = Undistort::getUndistorterForFile(calibFile, gammaFile, vignetteFile);  //读取去畸变文件,包括内参,伽玛,渐晕。
		widthOrg = undistort->getOriginalSize()[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<boost::mutex> 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<boost::mutex> 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;
	}
}

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值