【论文阅读】GRAF: Generative Radiance Fieldsfor 3D-Aware Image Synthesis

GRAF

NeRF与GAN 碰撞出的火花——从 CVPR 2021 最佳论文:GIRAFFE 读起(一) - 知乎 (zhihu.com)

NeRF与GAN的交融(四)——GRAF论文阅读 - 知乎 (zhihu.com)

GRAF论文解读_remenber先生的博客-CSDN博客

【3维GAN】GRAF 用NeRF+GAN做三维生成 NIPS2020 论文阅读_哔哩哔哩_bilibili

背景知识

GAN

生成对抗网络(Generative Adversarial Network,GAN)是一种深度学习架构,由生成器(Generator)和判别器(Discriminator)组成。

GAN的核心理念是通过对抗训练的方式来生成逼真的数据。这个架构由两个主要部分组成:

  1. 生成器(Generator)

    • 生成器试图从随机噪声或潜在空间中学习到数据的分布情况,并生成与真实数据相似的假数据样本。

    • 它将潜在空间中的随机向量映射到数据空间,其目标是生成能够欺骗判别器的逼真样本。

  2. 判别器(Discriminator)

    • 判别器是一个二元分类器,尝试区分生成器生成的假数据和真实数据。

    • 它的目标是正确地将来自生成器的假样本和真实数据区分开来。

GAN的训练过程可以描述为一个博弈过程:生成器和判别器相互竞争、相互提升。在训练过程中,生成器和判别器相互对抗,不断优化自己的能力。生成器努力生成更逼真的样本以欺骗判别器,而判别器则试图更准确地区分真实和假数据。

Conditional GAN

条件生成对抗网络(Conditional Generative Adversarial Network,Conditional GAN或cGAN)是生成对抗网络(GAN)的一种扩展形式,它在生成器和判别器之间引入了条件信息。这种条件信息可以是任何形式的辅助信息,比如类别标签、图像、文本等,以指导生成器生成特定类型的图像或数据。

cGAN的结构与标准GAN的区别在于:

  • 生成器(Generator):接收随机噪声向量和条件信息,以生成与条件信息相关的假数据。

  • 判别器(Discriminator):除了区分真实数据和生成的假数据外,还需要判断生成的假数据是否与给定的条件信息匹配。

cGAN的引入使得生成模型更具控制性和可预测性,能够按需生成特定条件下的数据,这在许多实际应用中具有很高的价值。

patch GAN

Patch GAN 是一种生成对抗网络(GAN)的变体,用于图像生成和图像编辑任务。相比于传统的全图(全局)判别器,Patch GAN 使用了基于图像局部区域的判别器

在传统的 GAN 结构中,判别器被用于对整个图像进行真假分类。然而,Patch GAN 将判别器设计为对图像的局部区域(patches,即图像的小块)进行判断,而不是整个图像。这意味着判别器不再输出一个单一的真假标签,而是为图像中的每个小块(patch)生成一个真假预测,然后求平均值作为输出

通过这种方式,Patch GAN 提供了更加细粒度的判别信息,使生成器能够更精细地学习图像的局部细节和结构。此外,Patch GAN 在图像生成和编辑任务中更容易捕捉图像中的局部一致性和纹理细节,有助于生成更逼真、更细致的图像。

Latent

latent space,就是输入噪声的一个特征空间,也可以理解为一种有效的信息表示。

latent code,就是一种降维或者说是压缩,旨在用更少的信息去表达数据的本质。

disentangle

将数据或表示中的不同因素或属性分离开来,使它们更加独立和可操作。

NeRF

神经辐射场(Neural Radiance Fields,简称NeRF)是一种用于三维场景重建和渲染的神经网络模型。它是一种基于深度学习的方法,能够从二维图像数据中学习到场景的三维表示,并且可以用于生成逼真的三维渲染图像。

NeRF 旨在通过从不同角度观察的二维图像数据中学习到三维场景的密集表示。它使用了神经网络来建模场景中每个点的辐射强度和颜色,并通过学习到的辐射场(radiance field)来实现高质量的渲染。具体来说,NeRF 将每个三维空间中的点作为输入,并输出该点的颜色和辐射强度。

NeRF 的核心思想是通过训练神经网络来学习从场景中观察到的多个视角的二维图像数据到三维场景的映射关系。通过这种方式,NeRF 能够实现对场景的高精度重建和渲染,即使在存在遮挡和复杂光照条件下也能产生逼真的图像。

Volume Rendering

NeRF的体渲染过程通常包括以下步骤:

  1. 光线追踪:从相机位置出发,沿着每个像素的光线方向追踪,这些光线穿过了场景中的不同点。

  2. 采样场景中的点:对于每条光线,NeRF在其路径上进行采样,获取光线与场景中点的交点。这些点根据相机视角和场景的几何属性被采样出来。

  3. 颜色和密度估计:对于每个采样点,根据NeRF中MLP预测的颜色和密度信息,得到相应的颜色和密度值。

  4. 体素的累积:根据采样到的点和其预测的颜色、密度信息,进行体素的累积,计算沿着观察路径的光线累积颜色和密度。这个过程可以考虑光线穿过不同密度的体素并累积颜色值,从而产生最终像素的颜色。

  5. 生成图像:最后,基于光线的累积和采样点的颜色值,NeRF体渲染生成出具有高逼真度的图像,展示了三维场景的细节和外观。

因此,体渲染是NeRF中将预测的颜色和密度信息转换为最终逼真图像的关键步骤。它通过光线追踪和颜色密度的计算,实现了对场景的高质量渲染,展示了准确的三维场景。

Unposed images

"Unposed images" 指的是未经过特定姿势或布置的图像。即训练模型使用未经特定姿势或布置的图像。

主要内容

Motivation

尽管2D生成的对抗网络已经实现了高分辨率图像的合成,但它们在很大程度上缺乏对3D世界和图像形成过程的理解。因此,它们不能提供对相机视点或对象姿势的精确控制。为了解决这个问题,最近的几种方法利用基于中间体素的表示与可区分的渲染结合使用。但是,现有方法要么产生低图像分辨率,要么缺乏摄像头和场景属性,例如,对象标识可能会随着视点而变化。

现有的3D-Aware Image Synthesis方法(如PlatoniGAN的Voxel-based Representation、HoloGAN的abstract 3D feature representation)存在生成物体分辨率低,无法提供显式的相机控制,且无法完全地解耦相机位姿与物体形态的问题。例如:在合成过程中可能会出现物体的形态随着视角的变动而变动的问题,而神经辐射场自带视角一致性,而这是之前的3D生成模型存在的最大问题。

Overview

受到NeRF的启发,GRAF设计了一种NeRF表示的条件变体,展示了如何从一组未设定pose的2D图像中学习出丰富的生成模型。 除了改变视角之外,GRAF 还允许修改生成对象的形状和外观。

与之前的方法相比,GRAF 的优势是以神经辐射场来描述场景。神经辐射场自带视角一致性,而这是之前的3D生成模型存在的最大问题

Method

Generative Radiance Fields

这个模型包括一个生成器(Generator)和一个判别器(Discriminator)。

  • 生成器(Generator):生成器 Gθ 接收多个输入参数,包括相机矩阵 K、相机姿势 ξ、2D采样模式 ν,以及形状/外观编码 zs 和 za。它的任务是预测一个image patch P'。在推理时,生成器将为每个图像像素预测一个颜色值。

  • 判别器(Discriminator):判别器 Dφ 的作用是比较生成器生成的image patch P'与真实图像 I 中提取的图像补丁 P。通过这种对比,判别器可以区分出真实图像和生成图像之间的差异。

K的选取需要让principle point在图像中心位置。 ξ 是一个从均匀分布,使得相机位置位于上半球并且让相机朝向坐标系原点的相机位姿。

GRAF 的主要框架如上,和 GAN 十分类似,在生成图像的 Generator 中用到了 NeRF 的机制。GRAF 的网络包含两部分,Generator(后面称作G)与 Discriminator(后面称作D)。

G 在每次训练时,并不会生成一张完整的图片,而是以随机摄像角度和尺度,生成本该生成的完整的图片上的一系列 K×K 数量的离散的像素点(称作 patch)。D 比较生成的 patch 和从真实图像中采样得到的 patch 。这是考虑到,要生成一张完整的图片,训练成本过大。在 inference 时,G 生成的当然就是一张完整的图片,即一张图片所有的像素点了。

Generator

在生成之前要做的是前面提到的 patch sampling 。要完全确定一个 patch sampling 的点,首先需要的是在一个分布中随机选取 camera pose ξ ,camera matrix K (大概是一个定位场景中心和照片中心的量,反正是用来定位的)。通过 ξ 与 K ,camera与场景参照物的相对位置和角度关系唯一确定。接下来除此之外我们还需要一个与patch 的中心及发散幅度有关的变量 v=(u,s) ,其中 u=(u,v)∈R^2代表了 patch 的中心, s∈R^+ 代表了 patch 中相邻两个采样像素点间的距离(有些类似 CNN 中 stride 的概念)。因此一个 K×K 尺寸的 patch 采样点的集合为:

有如下采样示例:

从而,光线的方向和位置也就确定了下来。通过 NeRF 中的光线采样方法,所有要查询的点的 (x,d) 也就定了下来。x:位置,d:姿态。

Conditional Radiance Field

和NeRF的网络基本一致,只是增加了shape和appearance参数。

将上述结果经过体渲染即可得到图像P'。

Discriminator

至于 D ,它就和 GAN 中 Discriminator 的任务一样,努力分辨从真实样本中取出的 patch P(u,s) 和Generator 生成的 patch P′(u,s) 。

在训练时作者为了提高效率,先用大的patch去训练,以捕捉高层抽象的全局语义信息,然后再逐步减小 K ,用较小的patch去训练,以捕捉局部的细节信息。

Loss Function

Experiments

实验结果:好

Conclusion

我们引入了生成辐射场 (GRAF),用于高分辨率 3D 感知图像合成。 我们表明,与基于体素的方法相比,我们的框架能够生成具有更好的多视图一致性的高分辨率图像。 然而,我们的结果仅限于具有单个对象的简单场景。 我们相信,结合归纳偏差(例如深度图或对称性)将允许将我们的模型扩展到未来更具挑战性的现实场景。

Summary

GRAF使用的3D generator,关键之处在于把物体用NeRF表示,而非之前基于 voxel 的方法(voxel会造成内存立方式增长,如HoloGAN,PlatonicGAN),后面就结合 volume rendering 渲染得出图像,缺点是只能生成简单场景、单一物体。

文章中提到的场景的视角不变性,是由 NeRF 的固有特性保证的。训练时,每一个 G 应该只能针对特定某一类物体,比如汽车,比如椅子,G 在这个基础上,可以修改简单的 shape/appereance(有一定的解耦性),D也只能判断一个 patch 是不是汽车,这个判断与视角无关,只要是汽车,D 就认为是 True。

从 G 的结构可以看出,pose 和 shape/appereance 直接可以解耦,但 shape/appereance 之间却可能存在纠缠。

Others

camera matrix K

相机矩阵(Camera Matrix)通常用来描述相机的内部参数和几何特性,它是在相机成像过程中将三维空间中的点映射到二维图像平面上的关键组成部分之一。

相机矩阵通常表示为一个 3×3 的矩阵,对应着相机的内部参数,它包括了相机的焦距、主点位置以及图像的缩放和畸变等信息。在计算机视觉和计算机图形学中,相机矩阵通常用来执行三维空间点到二维图像点的转换,是进行相机几何矫正、图像重建和三维重建等操作的重要工具。

相机矩阵通常由以下几个参数构成:

  • 焦距(Focal Length):表示相机的镜头焦距,影响到图像的视野范围和放大比例。

  • 主点(Principal Point):相机图像的原点,通常表示图像平面中心的位置。

  • 图像缩放因子(Scale Factors):用来调整图像的缩放,以修正成像过程中的尺度变化。

  • 畸变参数(Distortion Parameters):描述镜头畸变的程度,例如径向畸变和切向畸变等。

这些参数组成了相机矩阵,它是描述相机成像过程的数学模型,能够将三维空间中的点投影到相机图像平面上。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用C++实现拓扑排序的代码: ```c++ #include <iostream> #include <vector> #include <queue> template <typename T, typename WGT_T> std::vector<typename DASS::graf<T, WGT_T>::size_type> topsort(const DASS::graf<T, WGT_T>& g) { // 初始化入度为 0 的结点队列 std::queue<typename DASS::graf<T, WGT_T>::size_type> q; std::vector<typename DASS::graf<T, WGT_T>::size_type> in_degree(g.size(), 0); for (typename DASS::graf<T, WGT_T>::size_type u = 0; u < g.size(); ++u) { for (const auto& e : g[u]) { ++in_degree[e.v]; } } for (typename DASS::graf<T, WGT_T>::size_type u = 0; u < g.size(); ++u) { if (in_degree[u] == 0) { q.push(u); } } // 执行拓扑排序 std::vector<typename DASS::graf<T, WGT_T>::size_type> order; while (!q.empty()) { typename DASS::graf<T, WGT_T>::size_type u = q.front(); q.pop(); order.push_back(u); for (const auto& e : g[u]) { --in_degree[e.v]; if (in_degree[e.v] == 0) { q.push(e.v); } } } // 如果存在环,则说明无法进行拓扑排序 if (order.size() != g.size()) { throw std::runtime_error("The graph contains a cycle"); } return order; } ``` 使用方法如下: ```c++ DASS::graf<int, int> g(6); g[0].emplace_back(1, 1); g[0].emplace_back(2, 1); g[1].emplace_back(3, 1); g[2].emplace_back(3, 1); g[2].emplace_back(4, 1); g[3].emplace_back(5, 1); g[4].emplace_back(5, 1); std::vector<DASS::graf<int, int>::size_type> order = topsort(g); for (auto u : order) { std::cout << u << " "; } // 输出:0 2 1 4 3 5 ``` 上述代码中,我们使用了一个队列来存储入度为 0 的结点,然后依次访问队列中的结点并将其从图中删除。如果存在环,则说明无法进行拓扑排序,我们在最后抛出了一个运行时错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值