一文搞懂 神经辐射场(Neural Radiance Fields,NeRF)

[复制链接]
查看634 | 回复0 | 2023-8-23 11:45:49 | 显示全部楼层 |阅读模式
简介

神经辐射场(Neural Radiance Fields,简称NeRF)是一种盘算机视觉技能,用于生成高质量的三维重修模型。它利用深度学习技能从多个视角的图像中提取出对象的几何形状和纹理信息,然后利用这些信息生成一个一连的三维辐射场,从而可以在任意角度和间隔下呈现出高度逼真的三维模型。NeRF技能在盘算机图形学、捏造实际、加强实际等范畴有着广泛的应用远景。
输入输出

NeRF(神经辐射场)的输入是多个视角的图像和相机参数,输出是一连的三维辐射场。详细来说,输入是一组二维图像和相应的摄像机参数(包罗相机位置和方向),输出是一个表现三维场景中每个点的颜色和密度的函数。
优缺点

NeRF技能的长处是生成的三维模型质量高、逼真度高,可以在任意角度和间隔下呈现出真实的物体外貌和纹理细节。别的,它可以从任意数量的输入图像中生成三维模型,而不必要对输入举行特定处置处罚或标记。但是,NeRF技能也存在一些缺点,比方必要大量的盘算资源和时间举行练习,且难以处置处罚大规模的场景和复杂的光照条件。别的,由于NeRF是基于视图合成的技能,因此在生成模型时必要确保输入的视角充足广泛和充实,否则可能会导致模型中存在遮挡和空洞。
原理

NeRF技能通过将输入的多个视角的图像和相机参数组合起来,创建一个多层感知机(MLP)模型来表现场景中每个点的颜色和密度。在练习阶段,NeRF利用图像渲染技能将生成的三维场景渲染为二维图像,并与真实图像举行对比,以优化模型参数。NeRF模型的关键在于怎样表现场景中每个点的颜色和密度。为此,NeRF利用了一种称为体积渲染(volume rendering)的技能。体积渲染将三维空间分成许多小的体素(voxel),并对每个体素中的颜色和密度举行插值。通过对全部体素举行插值,可以得到整个场景的颜色和密度值。
布局

NeRF(神经辐射场)的实现布局包罗两个重要组件:编码器(encoder)息争码器(decoder)。
编码器通常由卷积神经网络(CNN)构成,负责从输入的多个视角图像和相机参数中提取出场景中每个点的空间位置和视角特征。编码器中的每个卷积层都可以将输入数据从低维空间映射到高维空间,并提取出更复杂的特征表现。
解码器通常由多层感知机(MLP)构成,负责从编码器提取的特征中生成一连的三维辐射场。详细来说,解码器担当来自编码器的每个点的空间位置和视角特征作为输入,并输出该点的颜色和密度值。解码器中的每个MLP层都可以将输入数据映射到另一个高维空间,并提取出更复杂的特征表现。
在练习阶段,NeRF利用一组二维图像和相应的相机参数作为输入,并利用渲染方程将输入数据转换为三维场景。渲染方程用于盘算从相机位置和方向发出的光线与场景中对象的相交点,并确定每个点的颜色和密度值。然后,NeRF利用神经网络迫近渲染方程,以最小化生成场景与真实图像之间的差异。
pytorch实现

第三方库举行 NeRF 的实现

PyTorch 没有直接集成 NeRF,但是可以利用第三方库举行 NeRF 的实现。此中一个比较流行的库是 nerf-pytorch,你可以通过以下下令安装:
  1. pip install nerf-pytorch
复制代码
安装完成后,你可以利用以下一行代码实现一个简单的 NeRF 模型:
  1. import torch
  2. import nerf
  3. model = nerf.models.NeRF()
复制代码
这行代码将创建一个包罗默认参数的 NeRF 模型。你可以利用 model 对象对输入数据举行前向流传,比方:
  1. x = torch.randn(10, 3)  # 10 samples with 3 features each
  2. y = model(x)
  3. print(y.shape)  # output shape: (10, 4)
复制代码
这里我们生成了一个包罗 10 个样本的输入数据 x,每个样本都有 3 个特征。我们将输入数据输入到 model 中,并将输出结果 y 打印出来。可以看到,输出结果 y 的形状是 (10, 4),此中第一维表现有 10 个样本,第二维表现有 4 个特征。在 NeRF 中,最后一维通常用于表现颜色大概透明度等信息。
自行实现

  1. import torch
  2. from torch import nn
  3. from torch.nn import functional as F
  4. class NeRF(nn.Module):
  5.     def __init__(self, input_dims, output_dims, hidden_dims=256, num_layers=8):
  6.         super().__init__()
  7.         self.input_dims = input_dims
  8.         self.output_dims = output_dims
  9.         # MLP layers
  10.         layers = []
  11.         for i in range(num_layers):
  12.             layers.append(nn.Linear(input_dims, hidden_dims))
  13.             layers.append(nn.ReLU(inplace=True))
  14.             input_dims = hidden_dims
  15.         layers.append(nn.Linear(hidden_dims, output_dims))
  16.         self.mlp = nn.Sequential(*layers)
  17.     def forward(self, x):
  18.         x = self.mlp(x)
  19.         return x
复制代码
这里界说了一个名为 NeRF 的 PyTorch 模型类,该类担当一个输入维度 input_dims、输出维度 output_dims、隐蔽层维度 hidden_dims 和层数 num_layers 等参数。在初始化函数中,我们界说了一个包罗多个线性层和 ReLU 激活函数的 MLP 模型。在前向流传函数中,我们利用 MLP 模型对输入数据 x 举行处置处罚,并将输出返回。
要利用这个模型,我们可以先创建一个实例对象,然后将输入数据输入到模型中,比方:
  1. # create model instance
  2. model = NeRF(input_dims=3, output_dims=3)
  3. # generate input data
  4. x = torch.randn(10, 3)
  5. # forward pass
  6. y = model(x)
  7. print(y.shape)  # (10, 3)
复制代码
在这个例子中,我们创建了一个包罗 10 个样本的输入数据 x,每个样本都有 3 个特征。我们将输入数据输入到 NeRF 模型中,并将输出结果 y 打印出来。可以看到,输出结果 y 的形状是 (10, 3),表现有 10 个样本,每个样本有 3 个特征。
相关名词解释

辐射场

辐射场(Radiance Field)形貌了光的流传活动。在三维空间中,对于任意一条光线(即出发点和方向),场景中的每个点都可以盘算出该光线在该点的辐射度。对于每个点,辐射场可以用一个颜色值和一个辐射度值来表现。颜色值指的是该点的外貌颜色,而辐射度值指的是该点在光照下的明暗水平。通过在整个三维场景中盘算光线的辐射度,可以生成高质量的渲染图像。
在NeRF(神经辐射场)中,辐射场的概念被扩展为在三维空间中对于任意一条光线,盘算场景中的每个点在该光线方向上的颜色和密度。因此,NeRF的辐射场可以用来表现三维场景中的物体外貌颜色和密度信息。利用这些信息,可以在任意角度和间隔下呈现出高度逼真的三维模型。
多层感知机(MLP)

多层感知机(Multilayer Perceptron,简称MLP)是一种前馈神经网络(Feedforward Neural Network)布局。它由多个全毗连的神经元层构成,每层的神经元与上一层的全部神经元相连。重要头脑是通过非线性映射将输入数据映射到高维空间中,并通过多层的非线性变动,将这些映射结果组合成输出。
可以说激活函数是一种非线性映射,非线性映射可以引入新的特征。当我们将数据从原来的低维空间映射到一个更高维的空间时,我们可以以为是将原始数据的特征举行了扩展,引入了更多的特征。这使得输入数据在新的空间中变得更加分离,这种分离性使得我们可以更好地对数据举行建模和分类,同时还能提高模型的表达本事和性能。
在呆板学习和深度学习中,我们通常将高维空间中的数据视为一组特征,这些特征用于形貌输入数据的不同方面。通过将原始数据映射到高维空间中,并在这个空间中对数据举行建模和分析,我们可以更好地明白数据的含义,并发现数据之间的关系,从而提高我们的模型性能。
点的密度

在盘算机图形学中,点的密度通常指的是在一个给定的区域内,所包罗的点的数量。比方,如果我们有一个场景,必要对其举行渲染,我们可以将场景分成多个小区域,并盘算每个区域内的点的密度。如果一个区域内的点的密度较高,阐明在该区域内有更多的几何细节,必要更高的采样率来捕获细节;相反,如果一个区域内的点的密度较低,阐明在该区域内的几何布局相对简单,必要较低的采样率来捕获几何信息。
在 NeRF 中,点的密度也是一个很重要的概念。我们盼望在渲染图像时可以或许在场景中匀称地采样点,以捕获更全面的几何信息。因此,在练习 NeRF 模型时,我们必要对场景举行采样,并尽可能地让采样点的密度匀称。通常环境下,我们会在场景中随机生成一些点,并根据相机位置和方向,盘算每个点的可见性,并将可见的点用于练习模型。在这个过程中,我们必要衡量采样点的数量和密度,以得到最佳的结果。
体积渲染

体积渲染(Volume Rendering)是一种将 3D 数据(比方医学图像、CT 扫描、地质勘探数据等)转换成可视化图像的技能。在 3D 数据中,每个像素不但包罗颜色信息,还包罗了各种物理量信息,如密度、温度、速率等。体积渲染技能可以将这些物理量信息可视化出来,使得人们可以更好地明白和分析 3D 数据。
体积渲染的焦点头脑是在 3D 数据中对每个像素举行采样,并根据每个采样点的物理量信息盘算其颜色和透明度。详细来说,我们可以将 3D 数据表现为一个体积纹理,然后利用光线追踪算法在体积纹理中采样点,盘算每个采样点的颜色和透明度,并将其合成成终极的图像。
在 NeRF 中,体积渲染技能被用于将 3D 场景转换成可视化图像。我们可以将 3D 场景表现为一个密集的点云,并利用 NeRF 模型预测每个点的颜色和透明度。然后,在渲染图像时,我们可以利用体积渲染技能在点云中举行采样,盘算每个采样点的颜色和透明度,并将其合成成终极的图像。如许就可以将 3D 场景可视化成 2D 图像,使得人们可以更好地明白和分析场景中的几何和光学信息。
体积纹理

体积纹理(volume texture)是指一种将三维图像数据储存在三维纹理(3D texture)中的技能,可以实现在三维空间中对体积数据举行快速渲染和操纵。
通常环境下,体积纹理是由离散的体素(volumetric pixel)构成的,每个体素代表三维空间中的一个小立方体。每个体素储存了该立方体内的物理量信息,比方密度、颜色、纹理等。通过对体素数据举行插值,可以在三维空间中生成一连的体积数据,从而实现渲染结果。
体积纹理常被应用于医学图像处置处罚、盘算机辅助设计、仿真等范畴。在nerf中,体积纹理用于储存场景中的密度信息和颜色信息,从而实现对场景的渲染。
渲染方程

在 NeRF 的练习阶段,模型必要学习到每个场景中每个点的颜色和透明度。为了实现这个目的,NeRF 引入了渲染方程(Rendering Equation),用于形貌从相机到场景中某个点的光线经过的路径上全部光线与物体之间相互作用的物理规律。
渲染方程是盘算机图形学中的一个重要概念,它形貌了光线从相机出发穿过场景中各种材质的路径,终极到达像素的过程,并盘算出该像素的颜色值。渲染方程通常表现为一个积分方程,此中包罗场景中的各种光线流传和交互的物理过程。
渲染方程的焦点是在积分符号下的反射模型,它形貌了从一个点反射出去的光线的分布规律,通常也被称为 BRDF(双向反射分布函数)。BRDF 形貌了在某个点上,入射光线的方向和出射光线的方向之间的关系,而且取决于物体的材质和外貌状态。
渲染方程的盘算过程分为两个阶段:第一个阶段是求解相机射线与场景中物体的交点;第二个阶段是盘算渲染方程的积分式。在第一个阶段,必要利用光线追踪算法盘算相机射线与场景中的物体的交点,并确定该光线在场景中的流传路径。在第二个阶段,必要盘算在该交点处的光线颜色和亮度,并将其与全部从其他方向发出的光线的颜色和亮度相加,得到终极的渲染结果。
对于 NeRF 模型来说,在练习阶段,必要根据渲染方程对模型举行优化,使其可以或许生成与真实场景尽可能相似的图像。在测试阶段,必要利用渲染方程对相机从不同角度拍摄的场景举行渲染,得到高质量的 3D 渲染图像。
在练习阶段,我们的目的是通过最小化真实图像与渲染图像之间的差异,来优化神经网络中的权重。因此,渲染方程在练习阶段重要用于生成渲染图像,盘算渲染图像和真实图像之间的毛病,从而优化神经网络。

来源:https://blog.csdn.net/qq_44324007/article/details/129998545
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则