网站首页资讯科技

深度学习新使用:在PyTorch顶用单个2D图画创立3D模型

2019-01-11 05:04:28小编:仁怀安卓网点击数:

近年来,深度学习在处理图画分类、方针辨认、语义切割等 2D 图画使命方面的体现都很超卓。不仅如此,深度学习在 3D 图画问题中的运用也取得了很大的发展。本文试着将深度学习扩展到单个 2D 图画的 3D 重建使命中,这是 3D 计算机图形学范畴中最重要也是最有含义的应战之一。

使命

单个图画仅仅 3D 方针在 2D 平面的投影,所以一些高维空间的数据必定会在低维表征中丢掉。因而,单视角 2D 图画中并没有满足的数据来构建其 3D 组件。

要依据单个 2D 图画创立 3D 感知,首要需求关于 3D 形状自身的先验常识

在 2D 深度学习中,卷积自编码器是一种学习输入图画紧缩表征的有用办法。将该架构拓宽到学习紧凑形状常识是将深度学习运用于 3D 数据的最有远景办法。

CNN 编码深度形状先验常识

3D 数据表征

3D 数据的不同表征

与计算机格局中只要一种通用表征(像素)的 2D 图画不同,3D 数据能够以许多数字方式来表明。它们各有优缺陷,所以数据表征的挑选直接影响了运用它们的办法。

栅格化方式(体素网格):能够直接运用 CNN

每个蓝色的盒子表明单个别素,大部分体素都是空的。

体素是体积像素(volumetric pixel)的简称,它直接将空间网格像素拓宽为体积网格体素。每一个别素的局部性一同界说了该体积数据绝无仅有的结构,因而 ConvNet 的局部性假设在立体方式中依然建立。

体素表征密度低

但这种表征既稀少又糟蹋。有用体素的密度会跟着分辨率的添加而下降。

  • 优势: 从 2D 表征到 3D 表征,能够直接运用 CNN

  • 下风:简单糟蹋,要在细节和资源(计算力、内存)之间好好权衡。

几许方式:不能直接运用 CNN

椅子的点云表征

多边形网格:是三维空间中界说方针外表的极点、边和面的调集。它能够在适当紧凑的表征中捕获粒度细节。

点云:3D 坐标(x,y,z)中点的调集,这些点一同形成了与 3D 方针形状相似的云。点的调集越大,取得的细节就越多。同一组次序不同的点表明相同的 3D 方针。

  • 优势:表征紧凑,要点重视 3D 方针的外表细节。

  • 缺陷:不能直接运用 CNN。

# point_cloud1 and point_cloud2 represent the same 3D structure
# even though they are represented differently in memory
point_cloud1 = [(x1, y1, z1), (x2, y2, z2),..., (xn, yn, zn)]
point_cloud2 = [(x2, y2, z2), (x1, y1, z1),..., (xn, yn, zn)]

办法

本文的完成结合了点云紧凑表征的优势,可是用了传统的 2D ConvNet 来学习先验形状常识。

2D 结构生成器

咱们将构建规范的 2D CNN 结构生成器来学习方针的先验形状常识。咱们没有用体素办法,由于它功率比较低下,并且不能直接用 CNN 学习点云。因而咱们将学习从单个图画到点云的多个 2D 投影的映射,将一个视角的 2D 投影界说为:2D projection == 3D coordinates (x,y,z) + binary mask (m)

  • 输入:单个 RGB 图画

  • 输出:预先设定视角的 2D 投影

#--------- Pytorch pseudo-code for Structure Generator ---------#
class Structure_Generator(nn.Module):
    # contains two module in sequence, an encoder and a decoder
    def __init__(self):
        self.encoder = Encoder()
        self.decoder = Decoder()
    def forward(self, RGB_image):
        # Encoder takes in one RGB image and 
        # output an encoded deep shape-embedding
        shape_embedding = self.encoder(RGB_image)

        # Decoder takes the encoded values and output  
        # multiples 2D projection (XYZ + mask)
        XYZ, maskLogit = self.decoder(shape_embedding)

       return XYZ, maskLogit

点云交融

将猜测得到的 2D 投影交融到原生 3D 点云数据中。这是有或许完成的,由于这些猜测值的视角是固定的,并且是已知的。

  • 输入:预先设定视角的 2D 投影

  • 输出:点云。

伪烘托

咱们以为,假如用猜测的 2D 投影交融得到的点云有用,那么假如咱们重新视角烘托出不同 2D 投影的话,它应该与实在 3D 模型的投影相似。

  • 输入:点云

  • 输出:新视角的深度图画

练习动态

由 2D 卷积结构生成器、交融模块以及伪烘托模块组成的完好架构。

将这三个模块组合在一同,咱们得到了一个端到端模型,它能够只用 2D 卷积结构生成器,依据单个 2D 图画学习生成紧凑的点云表征。

这个模型的奇妙之处在于使交融模块和伪烘托模块能够朴实地进行可微分的几许推理:

  • 几许代数意味着没有可学习的参数,这使得模型更小、更易于练习。

  • 可微分意味着咱们能够反向传达梯度,从而用 2D 投影的丢失来学习生成 3D 点云。

# --------- Pytorch pseudo-code for training loop ----------#
# Create 2D Conv Structure generator
model = Structure_Generator()
# only need to learn the 2D structure optimizer
optimizer = optim.SGD(model.parameters())
# 2D projections from predetermined viewpoints
XYZ, maskLogit = model(RGB_images)
# fused point cloud
#fuseTrans is predetermined viewpoints info
XYZid, ML = fuse3D(XYZ, maskLogit, fuseTrans)
# Render new depth images at novel viewpoints
# renderTrans is novel viewpoints info
newDepth, newMaskLogit, collision = render2D(XYZid, ML, renderTrans)
# Compute loss between novel view and ground truth
loss_depth = L1Loss()(newDepth, GTDepth)
loss_mask = BCEWithLogitLoss()(newMaskLogit, GTMask)
loss_total = loss_depth + loss_mask
# Back-propagation to update Structure Generator
loss_total.backward()
optimizer.step()

定论

比较来自实在 3D 模型的新深度图画和经过学到的点云模型烘托得到的深度图画。

终究成果:从单个 RGB 图画→3D 点云

有了具体的点云表征,就能够用 MeshLab 将单个 RGB 图画转换为其它表征,比如与 3D 打印机兼容的体素或多边形网格。

参阅

  • Pytorch 代码:https://github.com/lkhphuc/pytorch-3d-point-cloud-generation

  • Tensorflow 代码:https://github.com/chenhsuanlin/3D-point-cloud-generation

  • 论文:https://arxiv.org/abs/1706.07036

  • 原始项目网站:https://chenhsuanlin.bitbucket.io/3D-point-cloud-generation/

参阅链接:https://medium.com/vitalify-asia/create-3d-model-from-a-single-2d-image-in-pytorch-917aca00bb07