本文首发自微信公众号「PyTorch 开发者社区」 随着计算机视觉领域相关技术的发展,针对 2D 图像的处理效率和精度得到了显著地提升。 但是现实环境中,物体多以 3D 立体结构的形式存在,如何准确地提升 AI 系统对复杂现实环境的感知和理解能力,正确处理 3D 图像,正在成为日趋关键的技术难点。 2019 年 Facebook AI 发布 Mesh R-CNN 模型进行 3D 目标检测与形状预测 2020 年 1 月 23 日,Facebook AI 发布了 PyTorch3D v0.1.0 版本。PyTorch3D 是 PyTorch 中经过优化的、高效、可重用组件库,它具有 3 大突出特点:高效、模块化和可微分,旨在简化在 PyTorch 中进行 3D 深度学习的难度。 PyTorch3D 中提供了 3D 算子和渲染两大组件。 在 3D 算子中,Fit Mesh 可以利用 3D 损失函数,把初始的通用形状变形为目标形状,并借助一些规则让目标形状变得更为流畅。而 3D 算子中的光束平差法(Bundle Adjustment),则提供了 cameras、transforms、so3 共计 3 个 API,根据给定相机的视角,形成对照相机视角的映射,从而推断场景的 3D 结构。 渲染则包括纹理网格渲染器(Render Textured Meshes)、DensePose 网格渲染器(Render DensePose Meshed)、彩色点云渲染器(Render Colored Pointclouds)等,借助这些渲染器,可以进一步优化形成的场景 3D 结构。 图为 PyTorch3D logo,由 PyTorch3D 的隐式立体渲染器生成的 隐式形状渲染(Implicit Shape Rendering) 隐式形状渲染是指基于输入场景的新视角,生成 3D 场景的真实渲染,其核心思想是利用神经网络与可微分渲染,重建 3D 场景表面的隐式形态,这使得仅依靠 2D 视图就可以学习 3D 场景中的几何形状。 进行隐式形状渲染需要几个关键组件,包括数据卷的抽象类(abstraction for volume data)以及可微分的隐式形状渲染器。 为了让行业从业者更容易地针对隐式形状渲染进行尝试,PyTorch3D 已经为用户提供了一系列常用的 3D 算子(3D operators)和损失函数,以及一个模块化、可微分的渲染 API。在指出核心可重用组件的同时,也提供了这些组件经验证的、标准化实现方法。 在 PyTorch3D v0.4.0 中,包括 5 个支持隐式形状渲染的新特性: 1、新增数据卷结构(Volumes data structure),支持 3D 卷的批处理和坐标框架之间的转换; 2、新增多个光线纹理实现方法: GridRaysampler MonteCarloRaysampler NDCGridRaysampler 3、新增多个 Raymarcher 实现方法: AbsorptionOnlyRaymarcher EmissionAbsorptionRaymarcher 4、新增隐式渲染器(ImplicitRenderer)和体积渲染器(VolumeRenderer)API,构成 Raysampler 和 Raymarcher 5、新增多个效用函数,如点云到体积的可微分转换。 利用 PyTorch3D 生成的甜甜圈 3D 图像 要使用这些新组件,可以借助一个模块化、文档完备的 NeRF 重新实现。 而改良版的 NeRF 重新实现,性能得到了极大提升,在保证输出图像质量的同时,比正式版本运行得更快。 使用 PyTorch3D 的 NeRF 重新实现功能,生成了形状和光影复杂的 3D 图像示例 教程(Fit Textured Volume)我们基于 PyTorch3D GitHub 官方教程 Fit Textured Volume,进行了汉化和整理,演示如何在 PyTorch3D 中,利用可微分立体渲染,依据给定场景的一组视图,预测场景的立体结构。 用 Raymarching 构建场景 3D 立体结构 本教程将介绍:
备注:限于篇幅有限,本文仅展示部分代码,完整代码请移步: https:///console/openbayes/containers/oAYzp70wwPk/overview 0. 安装和导入模块 确保已安装 torch 和 torchvision 。 如果没有安装 pytorch3d ,请使用以下代码安装。 1. 生成场景及 mask 的图像 以下代码将生成本次训练数据。它会通过 fit_textured_mesh.ipynb 教程,从多个角度渲染奶牛图像,并返回以下内容: 一系列由奶牛网格渲染器生成的图像及其剪影的张量;与所有摄像机镜头一一对应的渲染器。 备注:在 generate_cow_renders 函数中实现网格渲染的工作原理请参考: target_cameras, target_images, target_silhouettes = generate_cow_renders(num_views=40)print(f'Generated {len(target_images)} images/silhouettes/cameras.') 2. 初始化体积渲染器 初始化体积渲染器会从目标图像的每个像素发出一条射线,并沿射线采样一组间隔均匀的点。与每个射线点相对应的密度值和色值,可通过查询场景的体积模型中的相应位置获得。 raysampler 负责从图像像素中发射射线,并沿着射线对点进行取样。此处使用的是 NDCGridRaysampler ,它符合标准的 PyTorch3D 坐标网格规范。 raymarcher 获得射线采样的密度和颜色,并将所有射线渲染成光线源像素的颜色和不透明度值。此处使用的是
3. 初始化体积模型 接下来实例化场景的体积模型。这会使得 3D 空间量化为体积像素,其中每个体素都用体素 RGB 颜色的 3D 向量,和描述体素不透明度的密度标量(范围在[0-1]之间,数字越大不透明越高)来表示。 为了保证密度和颜色的取值范围在 [0-1] 之间,我们会在对数空间中表示体积颜色和密度。模型运行 forward 函数时, log-space 值会通过 sigmoid 函数传递,从而使得 log-space 值处于正确的取值范围。 此外, VolumeModel 还包含渲染器对象。这个对象在整个优化过程中保持不变。 本部分代码还定义了 huber 损失函数,它可以计算出渲染色和 mask 之间的差异。 4. 体积拟合 这一步,我们用可微分渲染来进行体积拟合。 为了拟合体积,我们从 target_camera 的视角进行渲染,并将渲染结果与观察到的 target_images 和 target_silhouettes 进行对比。 这种对比是通过评估的 5. 将优化后的场景体积进行可视化 最后,旋转场景体积的 y 轴,从多个视点进行渲染,将优化后的体积进行可视化。 def generate_rotating_volume(volume_model, n_frames = 50): logRs = torch.zeros(n_frames, 3, device=device) logRs[:, 1] = torch.linspace(0.0, 2.0 * 3.14, n_frames, device=device) Rs = so3_exponential_map(logRs) Ts = torch.zeros(n_frames, 3, device=device) Ts[:, 2] = 2.7 frames = [] print('Generating rotating volume ...') for R, T in zip(tqdm(Rs), Ts): camera = FoVPerspectiveCameras( R=R[None], T=T[None], znear = target_cameras.znear[0], zfar = target_cameras.zfar[0], aspect_ratio = target_cameras.aspect_ratio[0], fov = target_cameras.fov[0], device=device, ) frames.append(volume_model(camera)[..., :3].clamp(0.0, 1.0)) return torch.cat(frames) with torch.no_grad(): rotating_volume_frames = generate_rotating_volume(volume_model, n_frames=7*4)image_grid(rotating_volume_frames.clamp(0., 1.).cpu().numpy(), rows=4, cols=7, rgb=True, fill=True)plt.show() 6. 结论 本教程中演示了如何优化场景的 3D 立体构造,使已知视点的体积渲染与每个视点的观测图像相匹配。 教程中的渲染是使用 NDCGridRaysampler 和 为 2D 图像构建有纹理的立体形状 完整教程请查看:
|
|
来自: taotao_2016 > 《几何》