NeRF原理学习

2024-09-03 02:04
文章标签 学习 原理 nerf

本文主要是介绍NeRF原理学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一个2020年的工作我现在才来学习并总结它的原理,颇有种“时过境迁”的感觉。这篇总结是基于NeRF原文 NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis 阅读理解后写的,作用是以后如果记不太清了可以回忆。

目的&应用

先说一下NeRF这个架构的功能是什么。它的主要功能是进行新视角的合成:给定若干张不同视角的同一物体或场景的图片(已知相机参数和位姿),训练一个神经网络来隐式地学习物体的三维表征,然后对于新的视角进行图片合成。因为它是隐式的表示,所以并不能直接重建为三维模型,后面也有一些工作是研究怎么去进行显示三维重建的。

原理

NeRF的意思是 Neural Radiance Fields,可以翻译成“神经辐射场”,辐射场在物理上的意义是去描述空间中光照强度的分布,也就是空间中某一点在某一方向发射或接受的光强;在数学上的形式一般是一个五维空间上的函数 f : R 5 → R n f:R^5 \rightarrow R^n f:R5Rn ,5维包括了空间中的位置(3维)和空间中的方向(2维)。而Neural顾名思义就是表示神经网络,所以NeRF从名字来解释就是用神经网络去拟合一个辐射场函数
f : ( x , y , z , θ , ϕ ) → ( r , g , b , σ ) 或   f : ( x , d ) → ( c , σ ) f:(x,y,z,\theta,\phi)\rightarrow (r,g,b,\sigma) \ \ 或 \ \ f:(\mathbf{x},\mathbf{d})\rightarrow (\mathbf{c},\sigma) f:(x,y,z,θ,ϕ)(r,g,b,σ)    f:(x,d)(c,σ)
这个神经网络的输入是空间中某一点的坐标以及视角方向,输出是颜色和密度。输入很好理解,就不详细说了,主要比较难理解的概念是这个密度。从物理角度来说,密度可以表示物质的集中程度或稠密程度,可以用来描述空间中物质或内容的分布情况,高密度的部分表示有物质存在,比如物体表面或内部,意味着该部分对光线的吸收或散射较强;而低密度的部分则相反,光线可以更自由地通过。

体渲染的角度来说,密度会影响体渲染积分的过程。

普通渲染管线大致流程是:顶点投影、光栅化、片段处理,当然还包括深度测试、alpha混合等,这都是很熟悉的概念了。光线追踪是从相机射出一条光线,模拟光线的反射折射等,对路径上碰到的颜色进行混合。这两种渲染方式主要常用于Mesh这种矢量形式的场景。而对于体积数据则更适合用体渲染:从相机出发向每个像素点发射光线,对光线路径上的颜色和密度进行积分
C ( r ) = ∫ t n t f T ( t ) ⋅ σ ( r ( t ) ) ⋅ c ( r ( t ) ) d t C(\mathbf{r})=\int_{t_n}^{t_f}T(t)\cdot\sigma(\mathbf{r}(t))\cdot\mathbf{c}(\mathbf{r}(t)) dt C(r)=tntfT(t)σ(r(t))c(r(t))dt
其中 T ( t ) T(t) T(t)是累积的透射率, σ \sigma σ c \textbf{c} c是密度和颜色,其中累积的透射率通过以下公式计算
T ( t ) = exp ⁡ ( − ∫ t n t σ ( r ( s ) ) d s ) T(t)=\exp(-\int_{t_n}^t\sigma(\mathbf{r}(s))ds) T(t)=exp(tntσ(r(s))ds)
这个体渲染的公式其实很好理解,对于光线路径上的点,它的密度越大,且光线在这点的透射率越大,这一点的颜色对最终颜色(积分)的贡献就越大;而这一点的光线透射率,就是 e − ( 在这一点之前的密度积分 ) ∈ ( 0 , 1 ) e^{-(在这一点之前的密度积分)}\in(0,1) e(在这一点之前的密度积分)(0,1),之前的密度积分越大,透射率越小。

因此NeRF实际上就是学习一个神经网络去对空间每个点和方向预测一个颜色和密度,然后对于新的视角,也就是新的观测点或者相机,用体渲染来计算每个像素的颜色值,以此得到新视角的合成图片。

神经网络结构

image-20240902152746202

NeRF的神经网络结构就是简单的MLP模型,每一层之间都是全连接层+ReLU,并添加了一个残差连接。其中有几个要注意的点:

空间中每个点的密度 σ \sigma σ应该是场景固有属性,与光照、视角这些变量无关,因此MLP一开始的输入只有坐标,在预测完密度之后,才拼接视角进行后面颜色的预测。

神经网络偏向于学习低频信息,或者说,网络很难学习到低维域的高频信息,因此论文将输入映射到高维空间后再输入MLP

image-20240902163339187

对于每个分量先正则化到[-1, 1]后再使用上述公式。其实这个映射是傅里叶特征(Fourier Features)的一种特殊形式,参考 Fourier Features Let Networks Learn High Frequency Functions in Low Dimensional Domains。通过将低维输入映射到高维空间来更好地学习高频信息,一般针对的是基于点输入的神经网络,像NeRF或者DeepSDF这种就很适用。

体渲染

前面提到了体渲染在光线路径上的积分公式,以及有了一个输入输出适用于体渲染的神经网络,直接计算积分很难,需要转化为离散的求积公式,也就是对光线离散点求和来近似积分:
C ( r ) = ∑ i = 1 N T i ( 1 − exp ⁡ ( − σ i δ i ) ) c i , where  T i = exp ⁡ ( − ∑ j = 1 i − 1 σ j δ j ) C(\mathbf{r})=\sum_{i=1}^N T_i(1-\exp(-\sigma_i\delta_i))\mathbf{c}_i, \ \ \text{where} \ T_i=\exp(-\sum_{j=1}^{i-1}\sigma_j\delta_j) C(r)=i=1NTi(1exp(σiδi))ci,  where Ti=exp(j=1i1σjδj)
其中 δ i = t i + 1 − t i \delta_i=t_{i+1}-t_i δi=ti+1ti,表示相邻采样点之间的距离。实际上透射率 T i + 1 = T i ⋅ exp ⁡ ( − σ i δ i ) T_{i+1}=T_i \cdot \exp(-\sigma_i\delta_i) Ti+1=Tiexp(σiδi),表示每经过一小节透射率都要乘一个透射系数 exp ⁡ ( − σ i δ i ) \exp(-\sigma_i\delta_i) exp(σiδi),这个透射系数中当密度为0时透射系数为1,表示光线完全通过,当密度趋于无穷时投射系数趋于0,而 σ i δ i \sigma_i\delta_i σiδi就是近似的一小节的密度,被称为光学厚度。

因此公式里的 T i T_i Ti表示到第i小节时剩余的光线强度, ( 1 − exp ⁡ ( − σ i δ i ) ) (1-\exp(-\sigma_i\delta_i)) (1exp(σiδi))表示该小节的颜色贡献,可以理解为 exp ⁡ ( − σ i δ i ) \exp(-\sigma_i\delta_i) exp(σiδi)这一比例的光透射过去了,剩下的比例变成颜色贡献,物理意义就是散射。其实从连续形式的积分去离散化应该是能直接推出来的,但我不会推,只会解释结果的每一部分有什么意义。

另外,整个体渲染的计算过程都可以形式化的书写出来,是可微分的。

还有一个问题就是该如何在光线上进行采样,如果按照数量N平均采样,可能很多空的地方都是对训练没有用的,因此论文使用了一种“粗+细”的方式,即使用两个相同的网络,先用粗网络平均采样之后,根据每个点的 ( 1 − exp ⁡ ( − σ i δ i ) ) (1-\exp(-\sigma_i\delta_i)) (1exp(σiδi))划分权重,在细网络中对权重大的部分进行细分,以此提高训练效率。

训练

数据集就是对同一个场景的多视角图片,并且有相机位姿和参数。把所有像素点放在一起作为训练集,每个batch选若干个像素点参与训练,粗细网络的结果都参与梯度下降的优化过程,Loss为

image-20240902182616403

训练完之后的新视角合成只用细网络。

根据论文的描述, N c = 64 , N f = 128 N_c=64,N_f=128 Nc=64,Nf=128,batch_size为4096,100-300k个迭代数量,在一块V100上大概需要1-2天的训练时间。

这篇关于NeRF原理学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131711

相关文章

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

setsid 命令工作原理和使用案例介绍

《setsid命令工作原理和使用案例介绍》setsid命令在Linux中创建独立会话,使进程脱离终端运行,适用于守护进程和后台任务,通过重定向输出和确保权限,可有效管理长时间运行的进程,本文给大家介... 目录setsid 命令介绍和使用案例基本介绍基本语法主要特点命令参数使用案例1. 在后台运行命令2.

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

Spring @Scheduled注解及工作原理

《Spring@Scheduled注解及工作原理》Spring的@Scheduled注解用于标记定时任务,无需额外库,需配置@EnableScheduling,设置fixedRate、fixedDe... 目录1.@Scheduled注解定义2.配置 @Scheduled2.1 开启定时任务支持2.2 创建

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源