NeRF-pytorch源码解读:论文Representing Scenesas Neural Radiance Fieldsfor View Synthesis

论文:https://dl.acm.org/doi/pdf/10.1145/3503250

代码 :GitHub - yenchenlin/nerf-pytorch: A PyTorch implementation of NeRF (Neural Radiance Fields) that reproduces the results.

de774ec43db64fb3b416853ccfe4b8f0.png

 

6202ee41b7524ace9783c6345a9cd7d0.png

 项目速览:01ea4a30bb6a44d1aacf736bde1d7215.png

 

config  //存放不同数据集训练的参数

download_example_data.sh  //下载数据集

load_blender.py

load_deepvoxel.py

load_LINEMOD.py

load_llff.py  

//加载预处理不同格式的数据集,会在run_nerf.py中得到调用;

run_nerf.py  //网络训练和渲染,主函数是程序的入口,从当中的train()函数开始运行。

run_nerf_helpers.py //构造一些run_nerf.py需要的组件函数

1.数据加载

 

(1)数据集格式和内容

  1. LLFF(Layered Light Field Flow)数据集: LLFF数据集是用于视角一致性和深度学习重建的数据集。它包含通过拍摄相机移动的图像序列和深度图像。每个场景的图像序列捕捉了不同视角下的场景外观,而深度图像提供了场景的几何信息。LLFF数据集提供了相机参数、图像序列和深度图像,可以用于训练和评估视角一致性和深度估计算法。

  2. Blender数据集: Blender数据集是使用Blender软件生成的数据集,其中包含虚拟场景的三维模型、材质、相机参数以及渲染的图像。这些数据可以用于训练和评估三维重建、渲染、视觉SLAM等算法。

  3. LINEMOD数据集: LINEMOD(LINEmod Object Detection)数据集是用于物体检测和位姿估计的数据集。它包含多个物体的RGB图像和相应的标注信息,例如物体的二维边界框和位姿。LINEMOD数据集用于训练和评估物体检测和位姿估计算法,旨在解决物体在复杂背景下的检测和定位问题。

  4. DeepVoxel数据集: DeepVoxel数据集是用于稠密三维重建的数据集。它包含了真实场景的RGB图像和深度图像,可以用于训练和评估三维重建算法,例如基于体素表示的方法。DeepVoxel数据集提供了场景的多视图图像和深度信息,可用于生成高质量的三维重建结果。

 

 images, poses, bds, render_poses, i_test = load_llff_data(args.datadir, args.factor,
                                                                  recenter=True, bd_factor=.75,
                                                                spherify=args.spherify)

 从load_llff_data 中取出的pose 是一个(20,3,5)的list。20代表一共有20张image,3×5是每一个image 的pose matrix

hwf = poses[0,:3,-1]  // 取出前三行最后一列元素(红色部分)
poses = poses[:,:3,:4]  // 取出pose里的平移和旋转部分
....中间代码略去.......
H, W, focal = hwf   // 分别赋予 Hieight、Width、focal

关于poses_bounds.npy 解释:这个文件存储这一个numpy 的数组:N×17,N 是图像的数量,17 个元素将会被转化为 3*5 的矩阵和两个深度值:视角 到 场景的最近和最远距离。

blender 数据集 lego 的读取
介绍代码中的一个参数:arg.white_bkgd:
在Blender 的数据集图像有四个通道RGBA,其中A表示的是alpha通道,一般情况下就是两个取值【0,1】,当alpha=0 表示该处的pixel是透明的;当alpha=1 表示该处的pixel是不透明的。 而 white_bkgd 这个参数就是负责将透明像素的部分转化为白色的背景,转化的代码部分如下:

        if args.white_bkgd:
            images = images[...,:3]*images[...,-1:] + (1.-images[...,-1:])

代码的解读:
images是Normalize到【0,1】之间的图像,当alpha=0(也就是 images[…,-1:] = 0 ),那么images的像素将设置为1(纯白色);当alpha=1的时候,那么images的像素的就是本来的RGB通道对应的颜色。

llff

blender

LINEMOD

DeepVoxel

该数据集包含四个具有简单几何结构的朗伯对象(Lambertian objects)。视图为512×512像素,每个对象从上半球(the upper hemisphere)采样的视点渲染(479个作为输入,1000用于测试)。


nerf_synthetic

其中包含八个对象的路径跟踪图像(pathtraced images),这些对象具有复杂的几何结构和逼真的非朗伯材质(non-Lambertian materials)。六个从上半球上采样的视点渲染,两个从整个球体上采样的点渲染。Nerf渲染每个场景的100个视图作为输入,200个视图用于测试,所有视图均为800×800像素。
 

def train():

# 添加参数并解析参数

    parser = config_parser()
    args = parser.parse_args()

# 声明内参矩阵K
    # Load data
    K = None
# 由这里调用了load_blender_data函数加载数据,在load_blender.py中给出了该函数的定义


    if args.dataset_type == 'llff':
        images, poses, bds, render_poses, i_test = load_llff_data(args.datadir, args.factor,
                                                                  recenter=True, bd_factor=.75,
                                                                  spherify=args.spherify)
        hwf = poses[0,:3,-1]
        poses = poses[:,:3,:4]
        print('Loaded llff', images.shape, render_poses.shape, hwf, args.datadir)
        if not isinstance(i_test, list):
            i_test = [i_test]

        if args.llffhold > 0:
            print('Auto LLFF holdout,', args.llffhold)
            i_test = np.arange(images.shape[0])[::args.llffhold]

        i_val = i_test
        i_train = np.array([i for i in np.arange(int(images.shape[0])) if
                        (i not in i_test and i not in i_val)])

        print('DEFINING BOUNDS')
        if args.no_ndc:
            near = np.ndarray.min(bds) * .9
            far = np.ndarray.max(bds) * 1.
            
        else:
            near = 0.
            far = 1.
        print('NEAR FAR', near, far)

    elif args.dataset_type == 'blender':
        images, poses, render_poses, hwf, i_split = load_blender_data(args.datadir, args.half_res, args.testskip)
        print('Loaded blender', images.shape, render_poses.shape, hwf, args.datadir)
        i_train, i_val, i_test = i_split

        near = 2.
        far = 6.

        if args.white_bkgd:
            images = images[...,:3]*images[...,-1:] + (1.-images[...,-1:])
        else:
            images = images[...,:3]

    elif args.dataset_type == 'LINEMOD':
        images, poses, render_poses, hwf, K, i_split, near, far = load_LINEMOD_data(args.datadir, args.half_res, args.testskip)
        print(f'Loaded LINEMOD, images shape: {images.shape}, hwf: {hwf}, K: {K}')
        print(f'[CHECK HERE] near: {near}, far: {far}.')
        i_train, i_val, i_test = i_split

        if args.white_bkgd:
            images = images[...,:3]*images[...,-1:] + (1.-images[...,-1:])
        else:
            images = images[...,:3]

    elif args.dataset_type == 'deepvoxels':

        images, poses, render_poses, hwf, i_split = load_dv_data(scene=args.shape,
                                                                 basedir=args.datadir,
                                                                 testskip=args.testskip)

        print('Loaded deepvoxels', images.shape, render_poses.shape, hwf, args.datadir)
        i_train, i_val, i_test = i_split

        hemi_R = np.mean(np.linalg.norm(poses[:,:3,-1], axis=-1))
        near = hemi_R-1.
        far = hemi_R+1.

    else:
        print('Unknown dataset type', args.dataset_type, 'exiting')
        return
 

Nerf 网络的搭建:

3c7ca874aed3436b88ba51edf0749e61.png

 

input: layer = 0,Position Encoding 后的长度为 63 的vector
layer =9 时,将第8层的输出(channel=256)和 direction 进行Postion Encoding 之后(channel=27)进行concat

Output: 第8层的 density 为 alpha 的输出 和第10层的 rgb 3channel 的输出

netdepth = 8 , netwidth = 256 , input_ch = 63,是指position输入的维度(position encoding 之后的编码),skip = 4, 是因为在论文中 第5层出现了 skip connection.
 

model = NeRF(D=args.netdepth, W=args.netwidth,
                 input_ch=input_ch, output_ch=output_ch, skips=skips,
                 input_ch_views=input_ch_views, use_viewdirs=args.use_viewdirs).to(device)

Nerf 的 网络构建代码如下:

 

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LeapMay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值