BundleFusion code

44 篇文章 5 订阅

https://blog.csdn.net/weixin_38636815/article/details/107838359

背景:前面用了几篇文章来记录和总结了,我在研究bundlefusion过程中遇到的一些问题以及解决方法,本来想实现给bundlefusion输入先验轨迹,然后让其根据给定的轨迹进行重建,这样即便在环境比较恶劣的情况下,也可以使用给定的位姿完成重建任务,但是这段时间对bundlefusion有了新的认识,意识到这件事没有我想象的那么简单。bundlefusion的研究工作就要告一段落了,所以最后我对bundlefusion做一个大的总结,把网络上一些经典的文章,整合起来。

一、 首先是先明白bundlefusion的工作原理,当然要阅读他的论文,英文的论文也不是很难读,当然也可以看我师兄的总结文章:https://blog.csdn.net/fuxingyin/article/details/52921958,有了这篇文章,如果想了解的更具体,那么就认真阅读一遍,bundlefusion的论文,主要关注一下bf的优化机制。

二、 另外一个重点当然是读代码了,说实话代码我读的不是很通透,主要是参考这篇文章,https://zhuanlan.zhihu.com/p/86718461 了解了代码的脉络,在这里,我将在这篇文章的基础上添加一些细节,这样不仅让我自己对bf的代码有更加深刻的理解,同时也希望能给志同道合的小伙伴更加高效的学习bf的方法。

三、制作.sens数据集可以参考我前一段时间写的博客:https://blog.csdn.net/weixin_38636815/article/details/107694846

四、BundleFusion代码讲解

1. bundlefusion中的主要参数

bundlefusion工程中有很多参数,众多的参数被分到两个文件中,zParametersBundlingDefault.txt和zParametersDefault.txt。

在zParametersBundlingDefault.txt中重要参数如下:

 

  • s_numLocalNonLinIterations = 2; //局部非线性优化迭代次数
  • s_numLocalLinIterations = 100; //局部线性优化迭代次数
  • s_numGlobalNonLinIterations = 3; //全局非线性优化迭代次数
  • s_numGlobalLinIterations = 150; //全局线性优化迭代次数

在上面的这四个参数中,s_numLocalLinIterations 起到了关键的作用,下面是我在ICL_NUIM数据集上测试的几组参数的模型效果,也可以看出s_numLocalLinIterations 起到了重要的作用。

s_numLocalNonLinIterations = 1;
s_numLocalLinIterations = 1;
s_numGlobalNonLinIterations = 1;
s_numGlobalLinIterations = 1;

s_numLocalNonLinIterations = 1;
s_numLocalLinIterations = 50;
s_numGlobalNonLinIterations = 1;
s_numGlobalLinIterations = 1;

 

s_numLocalNonLinIterations = 1;
s_numLocalLinIterations = 1;
s_numGlobalNonLinIterations = 1;
s_numGlobalLinIterations = 100; 

  • s_downsampledWidth = 80;
  • s_downsampledHeight = 60;

上面两个参数主要是用于Correspondence Filtering中的dense verification中,如果设置的不恰当,会导致在跟踪过程中,容易跟踪失败,导致重建的稠密模型确实。我测试自己的数据集时,使用的是kinectv2深度相机获取的960x540的图像,发现在测试一次采集的数据时,有很长一段距离跟踪失败,导致最终重建的模型确实一大块,我抱着试试看的态度,调试参数,在修改了这两个参数后,之前跟丢的部分竟然跟踪上了。所以要根据你实际使用的图像的分辨率来调节这两个参数。

在zParametersDefault.txt文件中

  • s_maxNumKeysPerImage = 1024; //每一帧图像上检测的最多的sift特征点的个数。
  • s_widthSIFT = 640;
  • s_heightSIFT = 480;
  • s_windowWidth = 640;        //render window width
  • s_windowHeight = 480;
  • s_integrationWidth = 320;    //input depth gets re-sampled to this width (decrease to improve perf.)
  • s_integrationHeight = 240;    //input depth gets re-sampled to this height (decrease to improve perf.)
  • s_rayCastWidth = 320;        //should be same as integration except if rendering video
  • s_rayCastHeight = 240;

上面这些跟输入的图像的分辨率有关的参数也一定要根据自己使用的数据来响应的修改。

2. 不怕大家见笑,我刚开始读orb-slam2代码的时候,过了好久才想到,我还一直没有去看程序的主函数呢?哈哈,现在想想这真是作为程序员的耻辱。以后无论读什么代码我都必须先找到main函数,然后去先捋清楚代码的主干脉络,并且使用xmind软件将代码的思维导图画出来,这样整个工程的主干就很清楚了。

 

  • main() FriedLiver:程序入口
    • g_RGBDSensor = getRGBDSensor();//根据你设置的s_sensorIdx来判断你输入的数据的形式,是深度相机还是.sens文件。
    • g_RGBDSensor->createFirstConnected(); //这个函数主要是读取输入的.sens文件中的数据,彩色图,深度图,pose,还有info.txt
    • std::thread bundlingThread(bundlingThreadFunc); //开启多线程,进行跟踪和优化。
      •  std::thread(bundlingOptimizationThreadFunc);
        • bundlingOptimization();
          • g_bundler->process()
            • optimizeLocal()
            •  processGlobal()
            • optimizeGlobal()
    • startDepthSensing(g_bundler, getRGBDSensor(), g_imageManager); //重建
  • startDepthSensing
    • OnD3D11FrameRender
      • bool bGotDepth = g_CudaImageManager->process(); // Read Input
      • reintegrate(); //更新模型,包括:deintegrate和integrate
      • integrate(depthCameraData, transformation); //Reconstruction of current frame
      • Render
      • StopScanningAndExit(); //这个函数中实现将计算的位姿保存的.sens中的pose数据,并且生成.ply模型
  • OnlineBundler
    • OnlineBundler()
      • m_bHasProcessedInputFrame=false
      • m_bExitBundlingThread=false
      • m_lastFrameProcessed = -1
    • getCurrentFrame()
    • processInput()
      •  Bundler::detectFeatures()
      •  Bundler::storeCachedFrame()
      •  Bundler::matchAndFilter()
    • process()//BundleFusion Optimization
      • optimizeLocal()
      •  processGlobal()
      • optimizeGlobal()
  • Bundler
    • detectFeatures() //检测图像sift特征点
    • storeCachedFrame() //缓存数据
    • matchAndFilter() //匹配和过滤当前帧和之前所有帧的sift特征点,计算3D点。
    • optimize() //稀疏点优化
  • CUDASolverBundling 求解器

 

BundleFusion代码对于我来说还是太庞大了,在短时间内很难吃透很多细节,这一阶段的bundlefusion的研究就暂时告一段落了,如果以后有机会,重新开始研究他。

实时全局一致的3D重建,使用动态表面重新整合技术实时,高品质,大尺寸场景的3D扫描是混合现实和机器人应用的关键。然而,可扩展性带来了姿态估计漂移的挑战,在累积模型中引入了显着的错误。方法通常需要几个小时的离线处理来全局纠正模型错误。最近的在线方法证明了令人信服的结果,但遭受以下缺点:(1)需要几分钟的时间才能执行在线修正,影响了真正的实时使用; (2)脆弱的帧到帧(或帧到模型)姿态估计导致许多跟踪失败;或(3)仅支持非结构化的基于点的表示,这限制了扫描质量和适用性。我们通过一个新颖的,实时的端对端重建框架来系统地解决这些问题。其核心是强大的姿态估计策略,通过考虑具有高效分层方法的RGB-D输入的完整历史,针对全局摄像机姿态优化每帧。我们消除了对时间跟踪的严重依赖,并且不断地将其定位到全局优化的帧。我们提出了一个可并行化的优化框架,它采用基于稀疏特征和密集几何和光度匹配的对应关系。我们的方法估计全局最优化(即,束调整的姿势)实时,支持从总跟踪故障(即重新定位)恢复的鲁棒跟踪,并实时重新估计3D模型以确保全局一致性;都在一个框架内。我们优于最先进的在线系统,质量与离线方法相同,但速度和扫描速度前所未有。我们的框架导致尽可能简单的扫描,使用方便和高质量的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值