用PyTorch3D API渲染纹理网格来构建三维图像的详细指南

2,081 阅读5分钟

渲染是计算机图形学的一个基本组成部分,它将3D模型转化为2D图片。它是弥合3D场景属性和2D图片像素之间差距的一种自然技术。本文主要介绍用Pytorch 3d库渲染纹理网格来构建三维图像。以下是要介绍的主题。

目录

  1. 关于Pytorch3D
  2. 用Pytorch3D渲染图像
    1. 安装Pytorch3D
    2. 导入必要的库
    3. 加载网格和纹理
    4. 建立一个渲染器
    5. 绘制渲染后的图像
    6. 修改观察角度

三维理解力对于增强人工智能系统在现实世界中的理解和行动能力至关重要。让我们先来谈谈Pytorch3D。

关于Pytorch3D

PyTorch3D是一个高度模块化和高效的工具包,具有独特的特点,使使用PyTorch的3D深度学习更加简单。PyTorch3D为3D数据提供了一系列常用的快速和可微分的3D运算符和损失函数,以及模块化的可微分渲染API,使研究人员能够立即将这些函数纳入目前最先进的深度学习系统。

对Pytorch 3D和库的功能的详细了解可以在这里找到。

用Pytorch3D渲染图像

在这篇文章中,我们将使用Pytroch 3D库加载图像的网格和纹理来创建图像的3D印象。

网格模型是由顶点、边和面组成的,它使用多边形表示,如三角形和四边形来描述一个三维形状。网格,与实体物体不同,没有质量属性。然而,就像三维物体一样,可以创建简单的网格形状,如盒子、圆锥体和金字塔。

图像纹理是图像处理中计算的一组指标,用于量化图像的明显纹理。图像纹理告诉我们图像中颜色或强度的空间组织,或图像的特定部分。

让我们从安装和检查重要的库开始。

安装Pytorch3D

通过使用这个代码安装检查torch和torchvision。最有可能的是,如果在没有特定环境下使用colab笔记本,这些都会出现在bin中:

!pip show torch
!pip show torchvision

进入下一部分,即安装Pytorch3D,它需要从Facebook研究的GitHub仓库中安装,并有特定的依赖性:

import os
import sys
import torch
need_pytorch3d=False
try:
    import pytorch3d
except ModuleNotFoundError:
    need_pytorch3d=True
if need_pytorch3d:
    if torch.__version__.startswith("1.11.") and sys.platform.startswith("linux"):
 
        pyt_version_str=torch.__version__.split("+")[0].replace(".", "")
        version_str="".join([
            f"py3{sys.version_info.minor}_cu",
            torch.version.cuda.replace(".",""),
            f"_pyt{pyt_version_str}"
        ])
        !pip install fvcore iopath
        !pip install --no-index --no-cache-dir pytorch3d -f https://dl.fbaipublicfiles.com/pytorch3d/packaging/wheels/{version_str}/download.html
    else:
 
        !curl -LO https://github.com/NVIDIA/cub/archive/1.10.0.tar.gz
        !tar xzf 1.10.0.tar.gz
        os.environ["CUB_HOME"] = os.getcwd() + "/cub-1.10.0"
        !pip install 'git+https://github.com/facebookresearch/pytorch3d.git@stable'

导入必要的库

import matplotlib.pyplot as plt
 
from pytorch3d.io import load_objs_as_meshes, load_obj
 
from pytorch3d.structures import Meshes
from pytorch3d.vis.plotly_vis import AxisArgs, plot_batch_individually, plot_scene
from pytorch3d.vis.texture_vis import texturesuv_image_matplotlib
from pytorch3d.renderer import (
    look_at_view_transform,
    FoVPerspectiveCameras, 
    PointLights, 
    DirectionalLights, 
    Materials, 
    RasterizationSettings, 
    MeshRenderer, 
    MeshRasterizer,  
    SoftPhongShader,
    TexturesUV,
    TexturesVertex
)

由于使用的是colab笔记本,我们需要从GitHub源码中获取utilise文件。

!wget https://raw.githubusercontent.com/facebookresearch/pytorch3d/main/docs/tutorials/utils/plot_image_grid.py
from plot_image_grid import image_grid

加载网格和纹理

本文所使用的网格和纹理文件存在于Facebook research的GitHub资源库中。所以可以直接从仓库中下载这些文件,也可以手动下载并上传到colab笔记本中。

!mkdir -p data/cow_mesh
!wget -P data/cow_mesh https://dl.fbaipublicfiles.com/pytorch3d/data/cow_mesh/cow.obj
!wget -P data/cow_mesh https://dl.fbaipublicfiles.com/pytorch3d/data/cow_mesh/cow.mtl
!wget -P data/cow_mesh https://dl.fbaipublicfiles.com/pytorch3d/data/cow_mesh/cow_texture.png

一旦下载了网格和纹理文件,就需要进行读取:

f torch.cuda.is_available():
    device = torch.device("cuda:0")
    torch.cuda.set_device(device)
else:
    device = torch.device("cpu")
 
DATA_DIR = "./data"
obj_filename = os.path.join(DATA_DIR, "cow_mesh/cow.obj")
 
mesh = load_objs_as_meshes([obj_filename], device=device)

绘制网格和纹理文件

plt.figure(figsize=(7,7))
texturesuv_image_matplotlib(mesh.textures, subsample=None)
plt.axis("off");

分析印度杂志

建立一个渲染器

R, T = look_at_view_transform(2.7, 0, 180) 
cameras = FoVPerspectiveCameras(device=device, R=R, T=T)
 
raster_settings = RasterizationSettings(
    image_size=512, 
    blur_radius=0.0, 
    faces_per_pixel=1, 
)
 
 
lights = PointLights(device=device, location=[[0.0, 0.0, -3.0]])
 
renderer = MeshRenderer(
    rasterizer=MeshRasterizer(
        cameras=cameras, 
        raster_settings=raster_settings
    ),
    shader=SoftPhongShader(
        device=device, 
        cameras=cameras,
        lights=lights
    )
)

就像上面的纹理图片一样,有一些3D模型的碎片,在这些碎片的帮助下,将创建一个牛的3D模型。

最初,需要设置一个摄像头。牛的正面朝向-Z方向,世界坐标为+Y上,+X左,+Z中。所以我们将摄像机在方位角方向旋转180度,以面对牛的前面。

  • 在一个方位角圆上,方位角是指从北方顺时针测量的方向。一个方位角圆有360度。90度代表东,180度代表南,270度代表西,360度和0度代表北。

设置栅格化和阴影选项。由于我们只是制作用于显示的图片,我们将每像素的面数设置为1,模糊半径为0.0。我们还将bin size和每bin的最大面数设置为none,以采用更快的从粗到细的栅格化方法。

将栅格化器和着色器结合起来,形成Phong渲染器。纹理Phong着色器将对每个顶点的纹理UV坐标进行插值,获取纹理图像样本,并应用Phong照明模型。

绘制渲染后的图像

rendered_image = renderer(mesh)
plt.figure(figsize=(10, 10))
plt.imshow(rendered_image[0, ..., :3].cpu().numpy())
plt.axis("off");

分析印度杂志

这是最终的3D渲染图像,它是由网格和纹理文件组成的。它的观察角度和位置也可以改变,照明的影响也可以被调制。

修改观察角度

R, T = look_at_view_transform(dist=2.7, elev=10, azim=-150)
cameras = FoVPerspectiveCameras(device=device, R=R, T=T)
 
lights.location = torch.tensor([[2.0, 2.0, -2.0]], device=device)
 
materials = Materials(
    device=device,
    specular_color=[[0.0, 1.0, 0.0]],
    shininess=10.0
)
 
images = renderer(mesh, lights=lights, materials=materials, cameras=cameras)
plt.figure(figsize=(10, 10))
plt.imshow(images[0, ..., :3].cpu().numpy())
plt.axis("off");

印度分析杂志

结论

PyTorch3D为三维数据提供了一个常用的快速和可微分的三维算子和损失函数的集合。它还提供了一个模块化的可微分渲染API。通过这篇文章,我们已经了解了Pytorch 3D在渲染3D图像及其网格和纹理方面的应用。

参考资料