对于NeRF,可以先回顾NeRF神经辐射场ECCV2020;
首先,我们需要准备多张从不同角度拍摄的同一场景的2D图像,然后用COLMAP估计与相机相关的参数,通过COLMAP可以得到场景的稀疏重建结果,其输出文件包括相机内参,相机外参和3D点的信息,然后进一步利用LLFF开源代码中的imgs2poses文件将内外参整合到一个文件poses_boudns.npy中,假设该场景有 N N N张图像,则poses_boudns.npy存储了一个形状为 N × 17 N\times17 N×17的数组,对于每一行,即每张图像,存储以下信息:
论文中提到MLP的输入是 ( x , y , z , θ , ϕ ) (x,y,z,\theta,\phi) (x,y,z,θ,ϕ)是什么,和相机内参外参有什么联系?要明白这个问题,先要理解坐标变换。
总的来说,坐标变换的目的在于将不同视角下视角特定的坐标系投影到一个统一的世界坐标中进行三维重建,见get_rays_np函数。首先,我们在像素坐标下进行网格点采样,得到特定分辨率图像的各个像素点坐标。
然后,进行像素坐标到相机坐标的变换。像素坐标到相机坐标的变换属于投影变换的逆变换,即2D点到3D的变化,即我们需要根据像素点的坐标 ( u , v ) (u,v) (u,v)计算该像素点在相机坐标系下的三维坐标 ( x c , y c , z c ) (x_c,y_c,z_c) (xc,yc,zc);
然后,我们进行相机坐标到世界坐标的转换得到光线始发点与方向向量:
现在,我们通过了相机的内外参数将像素坐标转换为了统一的世界坐标下的光线始发点与方向,结合深度 t t t(范围在光线的始发深度和终止深度内),可以得到当前光线上任意一点的位置 r ( t ) = r o + t r d \textbf{r}(t)=\textbf{r}_{o}+t\textbf{r}_{d} r(t)=ro+trd;
所以实际上,NeRF的MLP并不是5D的输入 ( x , y , z , θ , ϕ ) (x,y,z,\theta,\phi) (x,y,z,θ,ϕ),而是 r ( t ) \textbf{r}(t) r(t)(在世界坐标下看还是 ( x , y , z ) (x,y,z) (x,y,z))和标准化处理的 r d \textbf{r}_{d} rd(对应观察方向 ( θ , ϕ ) (\theta,\phi) (θ,ϕ),但 r d \textbf{r}_{d} rd是三维的);
渲染时,我们沿着 r d \textbf{r}_{d} rd采样出很多 r ( t ) \textbf{r}(t) r(t),对这些点上的MLP输出的RGB结果求和作为最终的RGB。
注意NeRF中所说的观察方向,严格来说,是相机连接某个像素的方向,因为我们要沿着这个方向去渲染得到像素的值。