移动端实时三维重建KinectFusion-ios(3)——数据准备模块

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

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

        之前的文章介绍了KinectFusion-ios的算法框架,主要由4个处理模块构成,本文主要介绍第1个处理模块——数据准备模块。

一、代码整体调用

        由于这里没有复杂的数学需要解释,直接展示的代码调用,代码在FusionProcessor.mm文件的processFrame方法中

    //pre-process
    [_fuMeshToTexture drawPoints: m_mCubeExtractPointBuffer normals: m_mCubeExtractNormalBuffer intoColorTexture: m_colorTexture andDepthTexture: m_depthTexture withTransform: m_projectionTransform * m_globalToFrameTransform];
    [_fuTextureToDepth compute: m_depthTexture intoDepthMapBuffer: m_preDepthMapPyramid[0] with: m_cameraNDC2Depth];
    [_fuDisparityToDepth compute: inDisparityMapBuffer intoDepthMapBuffer: m_currentDepthMapPyramid[0]];
    for(int level=1;level<PYRAMID_LEVEL;++level)
    {
        [_fuPyramidDepthMap compute: m_currentDepthMapPyramid[level - 1] intoDepthMapBuffer: m_currentDepthMapPyramid[level] withLevel: level];
        [_fuPyramidDepthMap compute: m_preDepthMapPyramid[level - 1] intoDepthMapBuffer: m_preDepthMapPyramid[level] withLevel: level];
    }
    for(int level=0;level<PYRAMID_LEVEL;++level)
    {
        [_fuDepthToVertex compute: m_currentDepthMapPyramid[level] intoVertexMapBuffer: m_currentVertexMapPyramid[level] withLevel: level andIntrinsicUVD2XYZ: m_intrinsicUVD2XYZ[level]];
        [_fuVertexToNormal compute: m_currentVertexMapPyramid[level] intoNormalMapBuffer: m_currentNormalMapPyramid[level] withLevel: level];
        [_fuDepthToVertex compute: m_preDepthMapPyramid[level] intoVertexMapBuffer: m_preVertexMapPyramid[level] withLevel: level andIntrinsicUVD2XYZ: m_intrinsicUVD2XYZ[level]];
        [_fuVertexToNormal compute: m_preVertexMapPyramid[level] intoNormalMapBuffer: m_preNormalMapPyramid[level] withLevel: level];
    }

二、逐行解析

(a)、第2行

        完成当前已经重建的模型在上一帧的相机位姿视角下的渲染,这是一个简单的metal渲染管线。输入是已经重建的顶点数据、法向数据、变换矩阵,输出得到RGB纹理和深度纹理。需要注意的是,我们动态重建的网格模型不预存三角形面片信息,我们默认连续排列的3个顶点构成一个三角形面片进行渲染,例如假设顶点个数为12个,就代表由4个三角形面片构成重建的几何模型。此外,输出的RGB纹理用来动态展示当前重建的结果,在app界面可以直接看到。

(b)、第3行

        将(a)渲染得到的深度纹理,转换成深度图,这是一个简单的metal gpgpu管线。这是因为由metal直接渲染得到的深度图,是渲染管线下的ndc坐标系的深度值,范围是0.0-1.0之间,需要进行转换才能得到真实的深度值,而逐像素的转换由gpgpu核函数并行实现。其中的m_cameraNDC2Depth就是用于ndc转深度值的相机固有参数。

(c)、第4行

        将从数据流获取的新一帧的disparity帧图,转换成深度图,这是一个简单的metal gpgpu管线。之前介绍过,iphone的深度相机获取的数据是以disparity的形式存储的,需要经过如下转换得到深度值:depth = 1.0 / disparity,而逐像素的转换由gpgpu核函数并行实现。

(d)、第5-9行

        对(b)(c)得到的两张深度图(480x640帧尺寸),降采样得到3层的mipmap,即每张480x640深度原图分别降采样得到另外两张240x320和120x160的深度图。这是一个简单的metal gpgpu管线,逐像素的转换由gpgpu核函数并行实现。这样做的原因是为了提升后续icp算法的运行效率。

(e)、第10-16行

        对(d)得到的所有深度图,包括每一张的原尺寸图和降采样图,都对应转换得到一张顶点图和一张法向图。这是一个简单的metal gpgpu管线,逐像素的转换由gpgpu核函数并行实现。其中,12、14行将深度图转化为顶点图,这由相机投影的逆变换计算得到;13、15行将顶点图转化为法向图,这由相邻顶点的梯度近似计算得到。经过这样的操作,得到每一张顶点图的单像素存储的是一个(x, y, z)的顶点三维坐标,每一张法向图的单向素存储的是一个(x, y, z)的顶点法向坐标。

三、总结

      综上(a)-(e)的所有操作构成了KinectFusion-ios的数据准备模块,为后续的各个处理模块提供了必要的数据。其中,(a)操作是一个简单metal渲染管线,(b)-(e)操作是简单的metal gpgpu管线。它们的所有代码被包含在文件夹FuPreProcess中,这里不再详细展开,读者可以自行阅读理解。对metal的用法不理解的话,可以参考:https://blog.csdn.net/sjy234sjy234/article/details/81812029

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值