移动端实时三维重建KinectFusion-ios(5)——TSDF、Marching Cube

        博主的源码地址:https://github.com/sjy234sjy234/KinectFusion-ios

        原论文:"KinectFusion: Real-time dense surface mapping and tracking."

        之前的文章介绍了KinectFusion-ios的算法框架,主要由4个处理模块构成,并介绍了数据准备模块和ICP模块。本文主要介绍第3、4个处理模块——TSDF、Marching Cube。

一、TSDF

         扩展阅读:https://blog.csdn.net/qq_31785865/article/details/78524429

         这里不展开介绍TSDF的原理,读者直接看扩展阅读的链接,或者搜索SDF和TSDF相关的论文阅读理解即可。TSDF用来存储和合成更新当前所有的深度数据,博主实现的KinectFusion-ios中取的TSDF的一些参数定义如下,见FusionDefinition.h文件

#define TSDF_RESOLUTION 128
#define TSDF_MAXWEIGHT 512
// perlength, truncate and nearest are dynamic
#define TSDF_PERLENGTH 1.8
#define TSDF_TRUNCATE 10.0
#define TSDF_NEAREST 300.0

        其中,采用128x128x128的体素个数,是考虑到移动端的算力有限。TSDF算法的实现其实非常简单,源码包含在FuTsdfFusioner文件夹下。其中只包含一个类FuTsdfFusioner,实际上实现的是一个128x128x128尺寸的metal gpgpu核函数,逐体素的进行存储参数的更新。因此,TSDF的外部调用只有如下一行,代码在FusionProcessor.mm文件的processFrame方法中

//tsdf fusion updater
[_fuTsdfFusioner compute:m_currentDepthMapPyramid[0] intoTsdfVertexBuffer:m_tsdfVertexBuffer withIntrinsicXYZ2UVD:m_intrinsicXYZ2UVD[0] andTsdfParameter:m_tsdfParameter andTransform:m_globalToFrameTransform];

二、Marching Cube

        扩展阅读:https://blog.csdn.net/noahzuo/article/details/78544609

        这里不展开介绍Marching Cube的原理,读者直接看扩展阅读的链接,或者搜索相关的论文阅读理解即可。Marching Cube用来提取TSDF体素中隐含存储的三维网格模型,实际上是提取TSDF中的0等值曲面。Marching Cube算法的实现源码包含在FuMarchingCube文件夹下,包含两个类:FuMCubeTraverse和FuMCubeExtract,分别对应Marching Cube算法的两步操作:遍历操作、提取操作。

        首先,遍历操作,通过遍历TSDF网格,定位并记录下与0等值曲面相交的体素点;然后,提取操作,对于前面记录下来的体素点,利用预存的网格索引及线性插值方法,提取出三角形面片网格,得到重建的三维几何模型。

        代码在FusionProcessor.mm文件的processFrame方法中的外部调用如下

        //marching cube
        int activeVoxelNumber = [_fuMCubeTraverse compute:m_tsdfVertexBuffer intoActiveVoxelInfo:m_mCubeActiveVoxelInfoBuffer withMCubeParameter:m_mCubeParameter];
        if(activeVoxelNumber==0)
        {
            NSLog(@"alert: no active voxel");
            m_mCubeExtractPointBuffer = nil;
            m_mCubeExtractNormalBuffer = nil;
            return NO;
        }
        else if(activeVoxelNumber>=m_mCubeParameter.maxActiveNumber)
        {
            NSLog(@"alert: too mush active voxels");
            m_mCubeExtractPointBuffer = nil;
            m_mCubeExtractNormalBuffer = nil;
            return NO;
        }
        else
        {
            void *baseAddress=m_mCubeActiveVoxelInfoBuffer.contents;
            ActiveVoxelInfo *activeVoxelInfo=(ActiveVoxelInfo*)baseAddress;
            for(int i=1;i<activeVoxelNumber;++i)
            {
                activeVoxelInfo[i].vertexNumber=activeVoxelInfo[i-1].vertexNumber+activeVoxelInfo[i].vertexNumber;
            }
            uint totalVertexNumber=activeVoxelInfo[activeVoxelNumber-1].vertexNumber;
            m_mCubeExtractPointBuffer = [_metalContext.device newBufferWithLength: 3 * totalVertexNumber * sizeof(float) options:MTLResourceOptionCPUCacheModeDefault];
            m_mCubeExtractNormalBuffer = [_metalContext.device newBufferWithLength: 3 * totalVertexNumber * sizeof(float) options:MTLResourceOptionCPUCacheModeDefault];
            [_fuMCubeExtract compute: m_mCubeActiveVoxelInfoBuffer andTsdfVertexBuffer: m_tsdfVertexBuffer withActiveVoxelNumber: activeVoxelNumber andTsdfParameter: m_tsdfParameter andMCubeParameter: m_mCubeParameter andOutMCubeExtractPointBufferT: m_mCubeExtractPointBuffer andOutMCubeExtractNormalBuffer: m_mCubeExtractNormalBuffer];
        }

        第2行,执行遍历操作,并返回与0等值面相交的体素点的个数activeVoxelNumber。

        第3-16行,activeVoxelNumber无效,则Marching Cube失败,重建失败。

        第17-29行,activeVoxelNumber有效,执行提取操作。其中第19-27执行预分配内存空间,28行执行提取,完成Marching Cube算法,提取出来当前重建得到的三维几何网格模型。

三、总结

        至此,KinectFusion-ios的实现就介绍完了。

        目前,ios metal的使用者较少,因此网上可以参考的资料也较少。通过一轮KinectFusion-ios的源码介绍,就可以对ios metal的使用方法,特别是ios metal的gpgpu有了比较深入的理解。此外,如果是android端的gpgpu,可以使用renderscript进行实现。但是android端的处理器类型较多,gpgpu的生态不是很好。例如华为的手机自主研发的处理器,对renderscript的支持就不是很好,华为手机如果有更好的gpgpu语言选择,求留言告知。此外,苹果手机虽然从来不以性能为卖点,但是楼主亲身开发过ios和android相关的性能计算应用以后。发现苹果手机的性能,特别是gpu,确实是吊打android端的,谁开发谁知道~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值