三维重建-CVPR2021-NeuralRecon: Real-Time Coherent 3D Reconstruction from Monocular Video

三维重建-CVPR2021-NeuralRecon: Real-Time Coherent 3D Reconstruction from Monocular Video

论文链接:NeuralRecon: Real-Time Coherent 3D Reconstruction from Monocular Video
代码链接:/zju3dv/NeuralRecon

在了解NeuralRecon之前,需要先了解相机相关的知识,实际上三维重建,最后计算得出的是每个体素的TSDF(Truncated Signed Distance Function)值。

什么是TSDF?

TSDF(Truncated Signed Distance Function,截断的符号距离函数)是一种常用于三维重建的体素表示方法,广泛应用于像 NeuralRecon 这样的三维重建系统。

SDF(Signed Distance Function,符号距离函数): 符号距离函数是一个空间函数,用来表示场景中每个点到最近物体表面的距离,同时包含符号信息:

  • 正值:如果空间中的某个点位于物体表面之外,SDF 的值为正,表示点离表面的距离。
  • 负值:如果某个点在物体表面内部,SDF 的值为负。
  • 零值:如果某个点正好在物体的表面上,则 SDF 的值为 0。

SDF 是一个连续函数,表示物体表面的所有点距离最近表面的距离,并且是带符号的,能区分点在物体内部还是外部。

TSDF(Truncated Signed Distance Function,截断符号距离函数): 由于直接使用 SDF 来表示整个三维空间可能会产生大量不必要的数据(因为大多数点离物体表面较远,距离较大),因此在实际应用中我们会对距离进行截断,得到 TSDF。

  • TSDF 会将那些离物体表面较远的点的 SDF 值进行截断,超过某个距离阈值的点直接设为常量。
  • 这样做的好处是减少了远离物体表面区域的不必要计算,从而提高计算效率。

在这里插入图片描述

如何计算TSDF值?

在计算 TSDF 时,首先通过模型预测获得图片中的深度 ds(从图片中获取的深度信息),然后根据相机的位姿和内参计算出体素的深度 dv(通过相机拍摄的位姿以及相机的内参计算得来),接着计算体素到真实面的距离 d(x) = ds - dv。若 d(x) > 0,则体素位于真实面前;若 d(x) < 0,则体素位于真实面后。最终,通过进一步处理 d(x) 得到 TSDF 值。

在这里插入图片描述

NeuralRecon

NeuralRecon 是一种基于深度学习的三维重建方法,主要用于从单目视频或多视图图像生成高质量的三维场景。NeuralRecon利用TSDF的计算方法,将三维空间中的体素投影映射到二维图像中,找到体素需要提取图片中的具体位置,采用TSDF方式提取特征,构成所有的体素。

NeuralRecon模型架构图

主要步骤:

  • 输入:彩色图像和相机位姿信息作为输入,提供三维场景的基本信息。
  • 初始低分辨率重建:从低分辨率的体素网格开始,通过图像的多视角信息推断初步体素特征。
  • ConvGRU 更新特征:使用 ConvGRU 递归更新每层体素特征,保留前一层的有用信息。
  • MLP 估计 TSDF:多层感知机(MLP)用于估计每个体素的 TSDF 值,表示体素与表面的距离。
  • 逐层细化:每一层增加体素分辨率,并通过上采样和特征融合逐层细化体素特征。
  • 输出:生成高分辨率的 TSDF,表示最终的 3D 场景结构。

在这里插入图片描述

Fragment Posed Images(分段的带位姿的图像输入)

NeuralRecon 的输入是视频中的图像序列以及相机的位姿信息。具体的输入包括:

彩色图像:单目视频中的每一帧图像。

相机位姿:包括相机的内参和外参(位姿信息),这些信息帮助网络确定每个图像在三维空间中的位置。

这些图像会被分成多个 batch,每个 batch 表示一个 fragment(片段)。在每个片段中,网络从多视角的图像推断深度图并估计局部 TSDF(Truncated Signed Distance Function)。然后,通过将多个局部 TSDF 融合,逐步构建出完整的 3D 场景。

Coarse-To-Fine Reconstruction(从粗到细的三维重建)

NeuralRecon 使用了 coarse-to-fine(粗到细)的三维重建策略,逐步提升 TSDF 的分辨率,生成更细致的 3D 场景。其流程如下:

(1) 初始粗分辨率体素网格

首先,网络从低分辨率的体素网格开始重建。在这一层,每个体素的特征会通过图像序列中的多视角图像推断出来。多张图像的特征向量会被相加求平均,以此确定该体素的初步特征向量。

(2) ConvGRU 更新机制

在每一层的 TSDF 估计中,NeuralRecon 使用了 ConvGRU 机制来递归更新体素特征。ConvGRU 的作用是将前一层的体素特征与当前层的信息进行融合,保留有用的信息,并逐层改进。这一机制确保了不同层次之间的特征一致性和逐步细化的过程。

(3) MLP 和 TSDF 估计

特征通过 3D CNN 处理后,进入多层感知机(MLP)模块来估计 TSDF 值。在这一步,网络推断出每个体素的 TSDF 值,表示体素距离真实表面的距离。

(4) 逐层增加分辨率

第一层完成后,接下来的层次中,网络会逐渐增加体素的分辨率。这意味着体素的数量会增加,从而提取出更多的细节。在每一层,ConvGRU 机制会确保上一层的特征信息在新的分辨率下被细化并保留。为了对齐不同分辨率的体素网格,上一层生成的 TSDF 会通过上采样操作。

def forward(self, features, inputs, outputs):
    '''
    :param features: list: 每个图像的特征列表,例如 list[0] : 图像0的金字塔特征 : [(B, C0, H, W), (B, C1, H/2, W/2), (B, C2, H/2, W/2)]
    :param inputs: 来自数据加载器的元数据
    :param outputs: {} 空字典,用于存储输出
    :return: outputs: dict: {
        'coords': (Tensor), 体素的坐标 (number of voxels, 4) (4 : batch 索引, x, y, z)
        'tsdf': (Tensor), 体素的 TSDF 值 (number of voxels, 1)
    }
    :return: loss_dict: dict: {
        'tsdf_occ_loss_X': (Tensor), 多层次损失
    }
    '''
    bs = features[0][0].shape[0]  # 批次大小
    pre_feat = None  # 前一阶段的特征初始化为 None
    pre_coords = None  # 前一阶段的坐标初始化为 None
    loss_dict = {
   }  # 损失字典初始化为空
    # ----从粗到细的过程----
    for i in range(self.cfg.N_LAYER):  # 遍历网络的每一层
        interval = 2 ** (self.n_scales - i)  # 当前层体素网格的间隔
        scale = self.n_scales - i  # 当前尺度

        if i == 0:
            # ----生成新的坐标----
            coords = generate_grid(self.cfg.N_VOX, interval)[0]  # 生成初始的网格坐标
            up_coords = []
            for b in range(bs):
                up_coords.append(torch.cat([torch.ones(1, coords.shape[-1]).to(coords.device) * b, coords]))
            up_coords = torch.cat(up_coords, dim=1).permute(1, 0).contiguous()  # 将批次索引加入坐标
        else:
            # ----上采样坐标----
            up_feat, up_coords = self.upsample(pre_feat, pre_coords, interval)  # 上采样前一层的特征和坐标

        # ----反向投影(将坐标投影到3D空间)----
        feats = torch.stack(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值