NeRF 核心思想简记
Overview
- 输入:空间中的位置 x,相机的方向 d
- 输出:x 位置的颜色和体密度 (sigma)
- 映射:(F_{ heta}(x,d)->(c,sigma)),c是颜色,( heta)是网络的参数。
这个输出不是最终像素的颜色,而是空间中一点的颜色和密度,还需要用体渲染的算法将颜色混合,才能得到最终的像素颜色。
网络结构
很简单,x 经过一定层数的 MLP,输出一个特征向量和 (sigma),然后将特征向量和相机方向向量拼接,进入MLP,输出颜色c,(c, (sigma)) 作为网络最终的输出。
体渲染
常见的体渲染的方法,网络的输出只是解决了空间一点的密度和颜色问题,还需要对他们进行累加。这里只截取了论文的离散后的公式,分别讨论一下符号的意义。
- (sigma) 表示密度,密度越大代表当射线遍历到这里的时候,被阻挡的概率越大,所以后面的颜色可能就看不见了,也能理解为不透光率。
- (T_i) 累计的透光率,从j出发一直累计到i-1,计算出i点之前的透光率,这个值越大,代表能看到此点颜色概率越大。其实和密度意思差不都,只是这里用exp做了变换,将其压缩在0-1之间,而且(sigma)表示是不透光率,这里取个反。
- (c) 是当前点的颜色。
- (r = O + dt),代表沿着观察射线取一点空间位置
- (delta) 代表差分,两次采样的距离 (t_{i+1} - t_{i})
- 所以前面的式子表示 “当前点之前的透光率 X 当前点的不透光率 X 当前的颜色”。为什么是当前的不透光率?因为如果当前的不透光率越大,代表射线大概率会终止在这个地方,所以此点的颜色应该贡献也越大。所以(c)之前的系数,相当于这个点对最终像素颜色值得贡献。
如何将连续空间的体渲染离散?
体渲染可以选定固定的步长,例如(t_{i+1} - t_{i})可以选择固定的数值例如0.001,但是这会损失多样性,因为场景是连续,因为可能恰好细节被跨过了。 文中采用的分层抽样的方法。
从(t_n)到(t_f)划分成(N)个区间,然后每次从这个(N)个区间均匀采样,得到采样点。
优化
位置编码
直接将位置和方向信息输入网络,根据论文里描述会降低生成的质量,因此将低维的输出编码到高维空间。
其中(p)是位置信息,用这个函数进行编码,位置和方向在论文中都进行了编码,详细的参数可以参考论文。
层次化采样
有些地方可能被遮挡或者是空的空间,因此可以不采样那么多点,而是在细节丰富的地方进行采样。基于此,论文中提出了训练两个网络,一个是coarse一个是fine,粗网络选择(N_c = 64)个分段采样,正常利用体渲染混合公式输出颜色。得到一个射线上所有点的贡献值后,进行归一化,做成一个PDF,然后fine网络在进行采样的时候,用这个PDF采样,这样就会在细节丰富的地方多采样,而且采样点也多 (N_f = 128)。他们的联合采样点混合成最终的颜色。
损失函数
MSE作为损失,其中coarse和fine输出的颜色和GT进行比较来监督,coarse参与损失是为了让PDF更准确。
参考
- NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis
- FastNeRF: High-Fidelity Neural Rendering at 200FPS