草庐IT

NeRF 源码分析解读(一)

面里多加汤 2023-09-07 原文

NeRF 源码解读(一)

前言

NeRF 是三维视觉中新视图合成任务的启示性工作,最近领域内出现了许多基于 NeRF 的变种工作。本文以pytorch 版 NeRF 作为基础对 NeRF 的代码进行分析。
主要从以下方面开展:

  1. 数据的加载
  2. 光线的生成
  3. NeRF 网络架构
  4. 渲染过程

一、数据的加载

本文以加载合成数据集中 lego 图像为例。
首先我们观察 ./data/nerf_synthetic/lego 文件夹下的树结构:

train、test、val 三个文件夹下包含了训练要用到的 .png 图像,每个文件夹下包含 100 个文件。.json 文件包含了相机的 camera2word 转置矩阵,下图展示了部分文件中的内容。关于此转置矩阵不再展开叙述,具体知识可查看 SLAM 14 讲。了解以上基本信息后解析数据加载的代码。

frame 的值是一个列表,其中列表中的值是字典

def train():

    # 设置参数
    parser = config_parser()
    args = parser.parse_args()
    
    ...
    
    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.
		
		# 将 RGBA 转换成 RGB 图像
	    if args.white_bkgd:
	    	# 如果使用白色背景
	        images = images[...,:3]*images[...,-1:] + (1.-images[...,-1:])
	    else:
	        images = images[...,:3]

我们通过 load_blender_data() 函数得到了指定文件夹下的所有图像、pose、测试渲染的pose、宽高焦距以及分割数组。下面对数据加载函数进行分析。

def load_blender_data(basedir, half_res=False, testskip=1):
	"""
	:param basedir: 数据文件夹路径
    :param half_res: 是否对图像进行半裁剪
    :param testskip: 挑选测试数据集的跳跃步长
    :return: 
	"""
    splits = ['train', 'val', 'test']
    metas = {}
    for s in splits:
    	# 分别加载三个 .json 文件,保存到字典中
        with open(os.path.join(basedir, 'transforms_{}.json'.format(s)), 'r') as fp:
            metas[s] = json.load(fp)

    all_imgs = []
    all_poses = []
    counts = [0]
    
    for s in splits:
        meta = metas[s]  # 加载 .json 文件中的内容
        imgs = []
        poses = []
        # 如果是 train 文件夹,连续读取图像数据
        if s=='train' or testskip==0:
            skip = 1
        else:
            skip = testskip
         
        for frame in meta['frames'][::skip]:
        	# 以指定步长读取列表中的字典
            fname = os.path.join(basedir, frame['file_path'] + '.png')
            
            imgs.append(imageio.imread(fname))  # 将读取到的图像文件添加到图像列表中
            poses.append(np.array(frame['transform_matrix']))  # 读取转置矩阵
        imgs = (np.array(imgs) / 255.).astype(np.float32) # 此时 图像数组是一个 [n, H, W, 4] 的数组
        poses = np.array(poses).astype(np.float32)  # [n, 4, 4]
        counts.append(counts[-1] + imgs.shape[0])  # 用于标定到train、test、val
        
        all_imgs.append(imgs)  # 包含了 train、test、val 的图像的列表
        all_poses.append(poses)
    
    i_split = [np.arange(counts[i], counts[i+1]) for i in range(3)]
    
    imgs = np.concatenate(all_imgs, 0)  # 把列表聚合称为一个数组 [N, H, W, 4]
    poses = np.concatenate(all_poses, 0)
    
    H, W = imgs[0].shape[:2]
    camera_angle_x = float(meta['camera_angle_x'])
    focal = .5 * W / np.tan(.5 * camera_angle_x)  # 计算焦距
    
    # 制作用于测试训练效果的 渲染pose
    render_poses = torch.stack([pose_spherical(angle, -30.0, 4.0) for angle in np.linspace(-180,180,40+1)[:-1]], 0)
    
    # 为了节省内存开销可以选择只加载一半的数据,这里不再展开解释
    if half_res:
        H = H//2
        W = W//2
        focal = focal/2.

        imgs_half_res = np.zeros((imgs.shape[0], H, W, 4))
        for i, img in enumerate(imgs):
            imgs_half_res[i] = cv2.resize(img, (W, H), interpolation=cv2.INTER_AREA)
        imgs = imgs_half_res
        # imgs = tf.image.resize_area(imgs, [400, 400]).numpy()

        
    return imgs, poses, render_poses, [H, W, focal], i_split

通过对以上代码的分析,我们可以得到以下结果:

imgs : 根据 .json 文件加载到的所有图像数据。(N,H,W,4)N 代表用于 train、test、val 的总数量
poses : 转置矩阵。(N,4,4)
render_poses : 用于测试的 pose 。(40,4,4)
i_split : [[0:train], [train:val], [val:test]]

完成数据加载以后,就可以根据 image 数据模拟生成光线。具体代码解析见下一节:
NeRF源码分析解读(二)

有关NeRF 源码分析解读(一)的更多相关文章

  1. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

  2. 建模分析 | 平面2R机器人(二连杆)运动学与动力学建模(附Matlab仿真) - 2

    目录0专栏介绍1平面2R机器人概述2运动学建模2.1正运动学模型2.2逆运动学模型2.3机器人运动学仿真3动力学建模3.1计算动能3.2势能计算与动力学方程3.3动力学仿真0专栏介绍?附C++/Python/Matlab全套代码?课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。?详情:图解自动驾驶中的运动规划(MotionPlanning),附几十种规划算法1平面2R机器人概述如图1所示为本文的研究本体——平面2R机器人。对参数进行如下定义:机器人广义坐标

  3. 网站日志分析软件--让网站日志分析工作变得更简单 - 2

    网站的日志分析,是seo优化不可忽视的一门功课,但网站越大,每天产生的日志就越大,大站一天都可以产生几个G的网站日志,如果光靠肉眼去分析,那可能看到猴年马月都看不完,因此借助网站日志分析工具去分析网站日志,那将会使网站日志分析工作变得更简单。下面推荐两款网站日志分析软件。第一款:逆火网站日志分析器逆火网站日志分析器是一款功能全面的网站服务器日志分析软件。通过分析网站的日志文件,不仅能够精准的知道网站的访问量、网站的访问来源,网站的广告点击,访客的地区统计,搜索引擎关键字查询等,还能够一次性分析多个网站的日志文件,让你轻松管理网站。逆火网站日志分析器下载地址:https://pan.baidu.

  4. elasticsearch源码关于TransportSearchAction【阶段三】 - 2

    1.回顾.TransportServicepublicclassTransportServiceextendsAbstractLifecycleComponentTransportService:方法:1publicfinalTextendsTransportResponse>voidsendRequest(finalTransport.Connectionconnection,finalStringaction,finalTransportRequestrequest,finalTransportRequestOptionsoptions,TransportResponseHandlerT>

  5. (附源码)vue3.0+.NET6实现聊天室(实时聊天SignalR) - 2

    参考文章搭建文章gitte源码在线体验可以注册两个号来测试演示图:一.整体介绍  介绍SignalR一种通讯模型Hub(中心模型,或者叫集线器模型),调用这个模型写好的方法,去发送消息。  内容有:    ①:Hub模型的方法介绍    ②:服务器端代码介绍    ③:前端vue3安装并调用后端方法    ④:聊天室样例整体流程:1、进入网站->调用连接SignalR的方法2、与好友发送消息->调用SignalR的自定义方法 前端通过,signalR内置方法.invoke()  去请求接口3、监听接受方法(渲染消息)通过new signalR.HubConnectionBuilder().on

  6. ABB-IRB-1200运动学分析MATLAB RVC工具分析+Simulink-Adams联合仿真 - 2

    一、机器人介绍        此处是基于MATLABRVC工具箱,对ABB-IRB-1200型号的微型机械臂进行正逆向运动学分析,并利Simulink工具实现对机械臂进行具有动力学参数的末端轨迹规划仿真,最后根据机械模型设计Simulink-Adams联合仿真。 图1.ABBIRB 1200尺寸参数示意图ABBIRB 1200提供的两种型号广泛适用于各作业,且两者间零部件通用,两种型号的工作范围分别为700 mm 和 900 mm,大有效负载分别为 7 kg 和5 kg。 IRB 1200 能够在狭小空间内能发挥其工作范围与性能优势,具有全新的设计、小型化的体积、高效的性能、易于集成、便捷的接

  7. 关于Qt程序打包后运行库依赖的常见问题分析及解决方法 - 2

    目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'

  8. ruby-on-rails - 如何使用 ruby​​-prof 和 JMeter 分析 Rails - 2

    我想使用ruby​​-prof和JMeter分析Rails应用程序。我对分析特定Controller/操作/或模型方法的建议方法不感兴趣,我想分析完整堆栈,从上到下。所以我运行这样的东西:RAILS_ENV=productionruby-prof-fprof.outscript/server>/dev/null然后我在上面运行我的JMeter测试计划。然而,问题是使用CTRL+C或SIGKILL中断它也会在ruby​​-prof可以写入任何输出之前杀死它。如何在不中断ruby​​-prof的情况下停止mongrel服务器? 最佳答案

  9. 【Unity游戏破解】外挂原理分析 - 2

    文章目录认识unity打包目录结构游戏逆向流程Unity游戏攻击面可被攻击原因mono的打包建议方案锁血飞天无限金币攻击力翻倍以上统称内存挂透视自瞄压枪瞬移内购破解Unity游戏防御开发时注意数据安全接入第三方反作弊系统外挂检测思路狠人自爆实战查看目录结构用il2cppdumper例子2-森林whoishe后记认识unity打包目录结构dll一般很大,因为里面是所有的游戏功能编译成的二进制码游戏逆向流程开发人员代码被编译打包到GameAssembly.dll中使用il2ppDumper工具,并借助游戏名_Data\il2cpp_data\Metadata\global-metadata.dat

  10. Cesium源码解析一(terrain文件的加载、解析与渲染全过程梳理) - 2

    快速导航(持续更新中…)Cesium源码解析一(terrain文件的加载、解析与渲染全过程梳理)Cesium源码解析二(metadataAvailability的含义)Cesium源码解析三(metadata元数据拓展中行列号的分块规则解析)Cesium源码解析四(Quantized-Mesh(.terrain)格式文件在CesiumJS和UE中加载情况的对比)目录1.前言2.本篇的由来3.terrain文件的加载3.1更新环境3.2更新和执行渲染命令3.3数据优化3.4结束当前帧4.总结1.前言  目前市场上三维比较火的实现方案主要有两种,b/s的方案主要是Cesium,c/s的方案主要是u

随机推荐