NeRF学习——基于Pytorch代码复现的笔记

news2024/9/21 22:48:31

代码复现的框架是基于:pengsida 的 Learning NeRF
源代码框架是基于 Linux 的,我在 Windows 上进行复现有些许 bug,Windows 上 bug 修复的框架版本:Learning NeRF

希望各位可以通过学习 NeRF-Pytorch 的源码来自己复现一下试试看!

文章目录

    • 1 创建Dateset
      • 1.1 `__init__`
      • 1.2 `__getitem__`
        • 1.2.1 训练数据
        • 1.2.2 测试数据
      • 1.3 `__len__`
    • 2 Network
      • 2.1 NeRF 类
      • 2.2 Network 类
      • 2.3 Render
    • 3 Loss & Evaluate
      • 3.1 Loss
      • 3.2 Evaluate

1 创建Dateset

核心函数包括:initgetitemlen

  • init函数负责从磁盘中load指定格式的文件,计算并存储为特定形式

  • getitem函数负责在运行时提供给网络一次训练需要的输入,以及 groundtruth 的输出

    例如对NeRF,分别是1024条 rays 以及1024个 RGB 值

  • len函数是训练或者测试的数量:getitem函数获得的index值通常是[0, len-1]

1.1 __init__

这里我们主要要做3件事(公平公平还是tmd公平

  1. 加载图像数据和相机位姿信息:

    • 从磁盘中读取指定格式的文件,这些文件包含了图像路径和相机位姿信息,位姿保存在 self.poses

    • 从图片路径保存图片,并根据参数进行处理(白色背景+缩放比例)

    • 最后,将处理后的图像添加到self.images列表中

  2. 计算相机内参:

    • 根据相机的视场角(FOV)和图像尺寸计算相机的焦距和相机矩阵
  3. 生成射线数据:

    • 首先,对于每一个位姿,使用rh.get_rays_np函数生成射线,并将所有射线堆叠起来

    • 然后,将射线和图像数据合并,并进行一系列的变换和重塑操作形成形状为 [N, H, W, ro+rd+rgb, 3] 的numpy数组 rays_rgb

      • N 是图像的数量

      • H 是图像的高度

      • W 是图像的宽度

      • ro+rd+rgb 表示每个射线的数据,包括射线的起始点(ro)、射线的方向(rd)和射线对应的像素颜色(rgb)

      • 3 表示每个数据都是一个三维向量(例如,rgb颜色是一个三维向量,包含红色、绿色和蓝色的强度)

      表示有 N*H*W 条射线,每条射线有3个数据(ro、rd、rgb),每个数据都是一个三维向量

    • 存储打乱前的射线 img_rays_rgb , 一张一张图片存储的,没有整合在一起 ,形状为 [N, H*W, ro+rd+rgb, 3],再转换为 Tensor

1.2 __getitem__

1.2.1 训练数据

主要功能是负责在运行时提供给网络一次训练需要的输入,以及 groundtruth 的输出 —— N_raysraysN_raysRGB值 ( N_rays = 1024)

  1. 将所有的光线(rays)和对应的RGB值整合到一个数组中,然后将这个数组的形状从 [N, H, W, ro+rd+rgb, 3] 改变为 [-1, 3, 3],即将所有的光线和RGB值平铺到一个一维数组中得到 [N*H*W, ro+rd+rgb, 3],并转为 Tensor

  2. 对所有的光线和RGB值进行打乱,这里使用GPU加速了一下

  3. 打乱后,根据索引 index 选择一个批次(1024条)的数据,再将批次的维度从第二位转换到第一位([1024,3,3] to [3,1024,3])

    在PyTorch中,通常希望批次维度在第一位,以便于进行批次处理

  4. 将选择的数据分为两部分:光线的数据(batch_rays)和对应的RGB值(target_s),并以字典的形式返回

    return {'H': self.H,
            'W': self.W,
            'K': self.K,
            'near': self.near,
            'far': self.far,
            'rays': batch_rays,
            'target_s': target_s}
    
1.2.2 测试数据

在测试时,输出一张图像的 rays 和 RGB 值,即 400 * 400 条 rays 和 400 * 400 个 RGB 值

  1. self.img_rays_rgb中根据索引index获取一张图片的光线

  2. 使用torch.transpose函数将批次的维度从第二位转换到第一位([1024,3,3] to [3,1024,3])

    在PyTorch中,通常希望批次维度在第一位,以便于进行批次处理

  3. 将数据分解为射线数据rays和对应的RGB值img_rgbrays包含了每条射线的起始点和方向img_rgb是每条射线对应的RGB值

  4. 返回一个字典,包含了射线数据和对应的RGB值,以及对应的图片索引 index

    return {'H': self.H,
            'W': self.W,
            'K': self.K,
            'near': self.near,
            'far': self.far,
            'rays': rays,
            'target_s': img_rgb,
            'index': index}
    

通过data_loader我们可以得到一个batch

  • train:

    image-20240428163506491
  • test:

    image-20240428163651114

1.3 __len__

返回数据集的大小,即数据集中的样本数量,即图像的数量

2 Network

核心函数包括:__init____forward__

  • init 函数负责定义网络所必需的模块

  • forward函数负责接收Dataset的输出,利用定义好的模块,计算输出

对于NeRF来说,我们需要在init中定义两个 MLP 以及 encoding 方式,在forward函数中,使用rays完成计算

定义了两个主要的神经网络模型:NeRFNetwork

2.1 NeRF 类

NeRF 类是NeRF的实现。它的结构包括了用于处理采样点和观察坐标方向的一系列MLP,以及相应的参数。主要方法是 forward,用于执行前向传播操作

  • 结构

    • __init__ 方法中定义了模型的各种参数和MLP

    • forward 方法实现了模型的前向传播逻辑,分别计算了辐射值和密度值,返回 output ——将 rgbalpha 两个张量在最后一个维度上进行拼接

      outputs = torch.cat([rgb, alpha], -1)
      

2.2 Network 类

Network 类是整个神经网络的集成,其中包括了对 NeRF 模型的调用以及render的实现,完成模型的调用和计算模型产生的预估值(即在这部分完成渲染)

  • 结构

    • __init__ 方法中初始化了整个网络模型,包括定义了两个 NeRF 模型(一个粗网络和一个精细网络),并根据配置参数进行设置

    • batchify 方法用于将函数应用于较小的批次数据

    • network_query_fn 方法,即网络查询函数,准备输入并将其传递给网络,并输出结果,使用 batchify 将一批一批的数据传入NeRF网络进行 forward

    • forward 方法,从 batch 中得到 dataloader 的数据,调用 render 函数:

      • 计算并创建射线,使用 render_utils 中的 batchify_rays 进行放入网络得到结果,再渲染射线得到 render_rays 返回的字典(即最后的结果):
      - 'rgb_map' (torch.Tensor): 每条光线的估计 RGB 颜色。形状:[num_rays, 3]- 'disp_map' (torch.Tensor): 每条光线的视差图(深度图的倒数)。形状:[num_rays]- 'acc_map' (torch.Tensor): 沿每条光线的权重总和。形状:[num_rays]- 'rgb0' (torch.Tensor): 粗模型的输出 RGB。见 rgb_map。形状:[num_rays, 3]- 'disp0' (torch.Tensor): 粗模型的输出视差图。见 disp_map。形状:[num_rays]- 'acc0' (torch.Tensor): 粗模型的输出累积不透明度。见 acc_map。形状:[num_rays]- 'z_std' (torch.Tensor): 每个样本沿光线的距离的标准差。形状:[num_rays]

      再对结果进行整理得到一个列表

通过dataloaderbatch传入网络,最终得到整理后的结果:

一个包含了所有渲染结果和相关信息的列表

前面 0、1、2 对应 'rgb_map''disp_map''acc_map'

image-20240331160722758

所有张量类型如下

dtype = torch.float64
device = device(type='cuda', index=0)

2.3 Render

增加 render_utils,并修改 raw2outputs()render_rays() 函数使数据移动至 cuda 进行计算

3 Loss & Evaluate

3.1 Loss

loss 模块主要为 NetworkWrapper 的类。forward 方法即是 loss 计算的过程。

  • 方法中,首先通过 self.net(batch) 调用传入的神经网络模型进行预测
  • 然后计算预测的RGB值与目标RGB值之间的MSE,并将其转换为PSNR。如果输出中包含rgb0(即包含粗网络预测的值),则还会计算粗网络的预测值RGB与目标RGB值之间的MSE和PSNR。
  • 最后,将所有的统计量(包括PSNR和损失)添加到scalar_stats字典中,并返回。

3.2 Evaluate

evaluate 模块在这个项目中主要用于评估模型的性能。并将评估结果保存为图像文件和JSON文件。

  1. 首先从模型的输出和批次数据中获取预测的RGB值和真实的RGB值
  2. 计算均方误差(MSE)和峰值信噪比(PSNR)
  3. 将预测的RGB值和真实的RGB值重塑为图像的形状。再将真实的RGB值和预测的RGB值水平拼接在一起,并保存为图像,形成对比

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1974220.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Lanproxy开箱即用的内网穿透工服务!!

Lanproxy快速上手配置服务器转发到内网!! 本教程云服务器推荐使用的开发环境如下:服务器端配置配置端口登录Web界面 内网客户端配置下载客户端配置客户端端口 最终效果测试 本文主要记录了使用Lanproxy搭建内网穿透服务的过程,其中包括服务端和客户端的详…

使用redis缓存文章浏览量

效果展示 好处 首先初始化所有浏览量 访问文章后增加的浏览量**不直接修改数据库,先存到redis然后访问也是获取redis的浏览量,做个定时任务,后续自定义时间同步数据库**,好像也就是一个集中处理罢了 CommandLineRunner实现项目…

鸿蒙系统学习指南

🐟作者简介:一名大三在校生,喜欢编程🪴 🐡🐙个人主页🥇:Aic山鱼 🐠WeChat:z7010cyy 🦈系列专栏:🏞️ 前端-JS基础专栏✨前…

8月2日SpringBoot学习笔记

今日内容: AOP 面向切面 代理模式 springmvc 运行原理 拦截器 springmvc异常处理机制 代理模式 为其他对象提供一种代理以控制对这个对象的访问。想在访问一个类时做一些控制是使用。 静态代理 优点:便于理解 缺点: 1.代码冗余&…

Linux 内核源码分析---I/O 体系结构与访问设备

I/O 体系结构 与外设的通信通常称之为输入输出,一般都缩写为I/O。 在实现外设的I/O时,内核必须处理3个可能出现的问题: (1)必须根据具体的设备类型和模型,使用各种方法对硬件寻址; &#xff08…

java面试题Spring部分(四)

一、什么事spring的三级缓存 典型回答 在Spring的BeanFactory体系中,BeanFactory是Spring IOC容器的基础接口,其DefaultSingletonBeanRegistry类实现了BeanFactory接口,并维护了三级缓存: public class DefaultSingletonBeanRe…

如何在OpenHarmony 4.1R上设置系统默认不锁屏(修改系统锁屏应用)

本文介绍如何修改系统锁屏应用,从而实现在OpenHarmony 4.1R上设置系统默认不锁屏。 环境配置 1.DevEco Studio 4.1 Release,下载链接地址 API10 Full SDK,安装教程 步骤 1.首先下载4.1r分支的系统锁屏应用applications_screenlock 2.修改系统锁屏应…

【Plotly-驯化】一文画出漂亮的流量漏斗图:plotly.funnel函数使用技巧

【Plotly-驯化】一文画出漂亮的流量漏斗图:plotly.funnel函数使用技巧 本次修炼方法请往下查看 🌈 欢迎莅临我的个人主页 👈这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合,智慧小天地! 🎇 免费获…

HTML+CSS練習---空隙產生記錄

1.第一層和第二層之間的間隙&#xff1a;以為導航欄超過高度朝下擠下來了 2.第2層兩個div中的空隙 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title><style>font-face {f…

ATTCK实战系列-红队评估 (一)Vulnstack三层网络域渗透

目录 一、搭建环境 1.靶场下载地址&#xff1a; 2、网络拓扑 3、环境配置 Win7&#xff08;外网服务器 &#xff09; Win2008&#xff08;域控&#xff09; Win2003&#xff08;域成员&#xff09; 4、启动环境 二、信息收集 1、端口扫描 2、目录扫描 三、漏洞利用…

IM即时通讯客服聊天系统源码(某站售8千)

即时通讯客服聊天系统已经成为企业提供卓越客户服务的不可或缺的工具。为了帮助您快速搭建强大的客服聊天系统&#xff0c;提供了一款全面的源码模板&#xff0c;基于Java和Spring Boot微服务架构构建&#xff0c;支持多种功能模块&#xff0c;以及消息加密、红包、消息撤回等功…

基于JSP的学生综合考评管理系统

你好&#xff0c;我是专注于教育信息化的开发者&#xff0c;很高兴为您介绍本系统。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSPJava 工具&#xff1a;Eclipse、MySQL数据库管理工具 系统展示 首页 管理员功能 教师功能 学生功能 摘要 本文…

笔记本怎么手动设置ip地址:一步步教你操作

在使用笔记本电脑连接网络时&#xff0c;有时候我们需要手动设置IP地址以满足特定的网络需求或解决网络问题。手动设置IP地址可以帮助我们更好地控制网络连接&#xff0c;确保设备在网络中的稳定性和安全性。然而&#xff0c;对于不熟悉网络设置的用户来说&#xff0c;手动设置…

EPLAN EDZ 文件太大导入很慢如何解决?

目前各个品牌都在提供 EPLAN EDZ部件库文件,但是一般都是一个总的EDZ文件,导入过程中,因为电脑配置和其他问题,导致导入过程中EPLAN会崩溃或者长时间不动。 我们分析下EDZ文件的构成,这是个压缩文件,换了个壳而已。用压缩软件把edz打开,这里不是解压,直接右键,用解压…

[CP_AUTOSAR]_系统服务_DEM模块(二)功能规范介绍

目录 1、DEM 功能规范描述1.1、Startup behavior1.2、Monitor re-initialization 在前面 《[CP_AUTOSAR]_系统服务_DEM模块&#xff08;一&#xff09;》文中&#xff0c;简要介绍了 DEM 模块的功能、与其它模块之间的功能交互&#xff0c;本文将接着介绍 DEM 模块的功能规范。…

Web前端:Vue开发环境搭建

一、搭建开发环境&#xff1a; 1.nodejs安装&#xff1a; 下载地址&#xff1a; https://nodejs.org/dist/v20.13.1/node-v20.13.1-x64.msi 查看版本号&#xff1a; node -v 2.安装nrm(用于指定国内镜像源&#xff0c;加速依赖包下载速度)&#xff1a; 安装nrm&#xff…

程序员的魔法石!

本文由 ChatMoney团队出品 AI自己写代码&#xff0c;这只是传说&#xff1f;还是摸鱼新指南&#xff1f; AI出现之前&#xff0c;从来都是老板或产品经理提需求&#xff0c;程序员熬夜加班吭哧吭哧写代码或者是从Github&#xff0c;Stackoverflow上controlc&#xff0c;control…

为面试准备的一些内容

开发中使用了什么技术&#xff1f; mvvm、compose、livedata、单例模式、工厂模式、弱引用、线程池、Handler。 对于项目一开始我们打算使用aosp原生的管控方式&#xff0c;如UsageStatManager获取每个app的使用时长&#xff0c;和使用PackageManager的setPackagesSuspended方…

【数据结构入门 】栈

目录 前言 一、栈的概念及结构 二、栈的实现 1. 栈的声明 2.初始化栈 3. 栈的销毁 4.判断是否为空栈 5.入栈&#xff08;只能插入栈顶元素&#xff09; 6. 出栈&#xff08;只能从栈顶删除&#xff09; 7.栈的大小 8.获取栈顶元素 总结 前言 在计算机科学中&#xf…

黑马Java零基础视频教程精华部分_10_面向对象进阶(2)

系列文章目录 文章目录 系列文章目录一、多态1、什么是多态&#xff1f;2、多态的表现形式3、多态的前提4、多态的好处5、多态调用成员的特点6、多态的优势和弊端7、引用数据类型的类型转换 二、包1、什么是包&#xff1f;2、包名的规则3、使用其他类的规则 三、final 最终的&a…