NeRF算法原理总结概述

简介

本文旨在对NeRF算法进行总结。论文翻译见博客:《NeRF算法论文解析与翻译》

参考链接:
神经网络辐射场NeRF、实时NeRF Baking、有向距离场SDF、占用网络Occupancy、NeRF 自动驾驶
NeRF详解
NeRF入门之体渲染 (Volume Rendering)
NeRF中的位置编码

1.算法概述

整体上NeRF干了这么一件事,输入一组静态场景的连续RGB图像和每帧图像对应的位姿,基于体渲染技术构建损失函数,通过借助一个全连接神经网络MLP得到关于新视角图像中每个像素对应3D点的体积密度RGB颜色信息。其中不包含3D场景重建,只是将场景隐式的通过一个函数进行表达。

算法整体的pipeline如下图所示:
在这里插入图片描述

其主要的工作在于:

  • 将连续场景表示为一个5D输入的神经辐射场,输入采样点的3D坐标和方向,可以得到其体积密度和颜色信息
  • 在寻找采样点时使用一种分层采样,”粗采样“计算相机射线上的点的分布,”细采样“获取概率分布较大处的点,避免过多选择"空"处的无效点,以及忽略"密集处"的好点
  • 对位置和方向坐标使用位置编码,以提高渲染的分辨率
  • 基于体渲染技术构建损失函数,并对位置和颜色进行分层训练

主要内容大概可以分为:数据预处理、分层体积采样、位置编码、MLP网络、损失函数

2.数据输入

2.1 数据信息说明

这里要区分一下NeRF的算法输入数据和MLP的神经网络输入。对于NeRF算法,输入只需要一组关于静态场景的RGB图像数据和每帧图像对应的位姿。然后,通过数据预处理模块会将RGB图像数据转换为MLP神经网络需要的5D坐标,包括xyz位置信息,和2D的旋转信息。

(1)xyz位置信息

背景:已经知道位于真实场景下的3D空间点[x,y,z]通过相机投影落在成像平面上会得到一个对应的像素[u,v],即连接真实世界中某个3D点和相机光心之间的连线,和相机成像平面相交于对应的像素位置。

在进行3D重建或是本文的新视角图像合成工作时,已知的是2D图像和对应的相机光心位置(位姿),需要很据这些信息反推出3D点的位置。对于3D重建工作可以通过视差或者深度滤波器来进行估计,在本文中是通过在这条射线上进行采样来得到深度学习网络的输入,也就是上面图像中左图中射线上的黑点。

根据相机投影原理,由像素坐标[u,v]可以得到3D采样点的[x,y]坐标,然后当采样点的位置确定后可以确定3D点的z坐标。
在这里插入图片描述

(2)旋转信息(θ,φ)

从相机光心出发,连接图像中的每个像素会得到一组射线,这里的旋转信息指的是每条相机射线的方向信息。3D空间中的方向可以由一个方向矢量表示,这个方向矢量由相机光心坐标和像素在焦距f处的3D坐标决定,然后通过相机位姿可以将该方向转换为世界坐标系下,并以方位角θ和仰角φ形式作为神经网络的输入。

2.2 分层体积采样

  • 首先,根据数据集中稀疏地图可以得到一个地图中点到光心的最大最小距离,称之为边界

  • 然后,在每条射线上的边界范围内,均匀选择N_c个采样点(如下面左图),使用coarse网络对其进行训练可以得到每条射线上点的体积密度和颜色信息

  • 然后,将coarse网络的预测结果(体积密度和颜色)带入到相关的体渲染函数中,可以得到关于该光线的概率密度分布函数( w ^ i \hat{w}_{i} w^i)
    在这里插入图片描述

在这里插入图片描述

  • 然后,根据估计出的分布进行第二次重要性采样,共计N_f个点(如下面右图橘色点)

  • 最后,将两次采样共N_c+N_f个点送到fine网络进行训练

此过程将更多样本分配给我们希望包含可见内容的区域(即采样点分布比较密集的区域)。这解决了与重要性采样类似的目标,但我们使用采样值作为整个积分域的非均匀离散化,而不是将每个样本视为整个积分的独立概率估计。
在这里插入图片描述

3.位置编码

目前深度学习网络对低频的数据训练效果较好,因为现实场景中的变化在低频数据中的反映差距更明显(参考一下逆深度的概念),但是场景的3D点一般是高频数据,比如位置(237, 332, 198)和位置(237,332,199)这两个点作为MLP的输入,如果直接将原始数据送入到网络中进行训练,MLP可能对个位不够敏感,导致输出过平滑的问题,最终无法得到高分辨率的结果,具体表现为最终的渲染图片会出现模糊,如下图中第4张图像:
在这里插入图片描述

针对这一问题,作者选择对位置数据和方向信息进行位置编码,即将原始的数据送入到一个映射函数:
在这里插入图片描述

当然,也如公式所示,我们并不以单一的频率来表示位置编码,比如我们挨个用[1,2,4,8,16,32,64,128,256,512]这10种频率来表示编码位置(只需用公式r=sin(p*x),然后简单concat到一起)。这就完成了基本的位置编码。当然,我们还可以加入相位平移,把cos(p*x)的结果也concat到一起。

所以,对于一个位置p(x,y,z),我们用10种频率来编码,每种频率采用两种相位(sin和cos),那编码后的位置应该有3×10×2=60维来表示原始的三维坐标向量。

NeRF除了位置(x,y,z)输入外,还需要输入观测角度(θ,ϕ)。观测角度可以用ray direction来表示,通常采用三维向量。也需要进行编码,也可以统称为位置编码。我们用同样的方法,但可以少用一些频率,比如我们用[1,2,4,8]这四种频率来编码观测角度。编码后的维度也可计算出来:3x4x2=24
在这里插入图片描述

4.MLP网络

该MLP网络先使用8个全连接层处理三维位置(x,y,z),输出体素密度σ和256维特征向量(因此体素密度σ仅是关于三维位置(x,y,z)的函数);

然后将上面得到的256维特征向量与二维方位视角(θ,φ)concat,接着用1个全连接层处理,输出颜色c=(r,g,b)
在这里插入图片描述

5.损失函数

再次回顾一下NeRF的任务:即通过对一个3D场景进行学习,然后实现该场景新视角下的图像合成。只要知道每个像素对应的RGB信息即可以得到一张图像,NeRf通过将生成的每个光线对应像素的体积密度信息和颜色信息,带入到体渲染公式中可以得到一个基于NeRF的预测值,然后通过和对应图像的真值结果作差得到2范数的损失函数。

然后,综合上述coarse网络fine网络的预测结果可以得到最终的误差损失函数。

在这里插入图片描述

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

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

相关文章

C++力扣题目501--二叉搜索树中的众数

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 如果树中有不止一个众数,可以按 任意顺序 返回。 假定 BST 满足如下定义&#xf…

中国X射线管行业研究与投资预测报告(2024版)

内容介绍: X射线管俗称球管,是X射线机的核心部件。X射线管在医学上可用于诊断和治疗,在工业技术方面可用于材料的无损检测、结构分析、光谱分析和底片曝光等。 目前,X射线管的壳体材料主要采用玻璃、陶瓷、金属材料这三种材质。玻…

项目中Ant Design Pro业务问题解决方案

ProTable实现多选反显筛选项多级关联选择 import {forwardRef,useImperativeHandle,useEffect,useRef,useReducer, } from "react"; import { Drawer, Space, Button, message } from "antd"; import * as PC from "ant-design/pro-components";…

Berstagram ——模拟

Polycarp最近注册了一个新的社交网络Berstagram。他立即在那里发表了 n 篇帖子。他给所有帖子分配了从 1 到 n 的数字,并逐一发布。所以,就在发布Polycarp的新闻推送后,包含了从 1 到 n 的帖子——最高的帖子编号为 1,下一个帖子编…

Snakemake:初探

我已经安装了mamba(没有的话可以这样试试) curl -L https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh -o Mambaforge-Linux-x86_64.sh bash Mambaforge-Linux-x86_64.sh 安装snakemake Setup - Snakem…

PHP项目添加分布式锁,这里是ThinkPHP8框架实现分布式锁

背景:公司旧项目,最初访问量不多,单机部署的。后来,访问量上来了,有阵子很卡,公司决定横向扩展,后端代码部署了三台服务器。部署调整后,有用户反馈,一个订单支付了三次。…

【Java高级应用:深入探索Java编程的强大功能,JVM 类加载机制, JVM 内存模型,垃圾回收机制,JVM 字节码执行,异常处理机制】

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

网络原理--http

目录 一、 DNS(应用层协议) 1、域名概念 2、维护ip地址和域名之间的映射(域名解析系统) 3、DNS系统(服务器) 4、如何解决DNS服务器高并发问题 二、HTTP(应用层协议) 1、htt…

开源云真机平台-Sonic平台-python自定义脚本-config.json方式实现全局配置参数的读写操作

【主要功能】 config.json方式实现全局配置参数的读写操作 使用python实现以下功能: 1、使用将接口获取的变量值,写入到当前目录下的config文件中,如delayTime10; 2、读取当前目录下的config文件中,特定变量的值&…

修改默认负载均衡策略(Ribbon)

修改方式 配置类配置文件 配置类 增加配置类:配置类必须拥有 Configuration 且不能在 ComponentScan 包下 package com.learning.springcloud.config; import com.alibaba.cloud.nacos.ribbon.NacosRule; import com.netflix.loadbalancer.IRule; import org.sp…

vue3深入组件:组件事件

触发与监听事件 在组件的模板表达式中&#xff0c;可以直接使用 $emit 方法触发自定义事件&#xff1a; <button click"$emit(someEvent)">click me</button>父组件可以通过 v-on (缩写为 ) 来监听事件&#xff1a; <MyComponent some-event"…

fs 模块

1. fs写文件 1.1 普通写入 const fs require(fs) // 异步写入 fs.writeFile(./hello.txt,刚刚我错过的大雨,err>{console.log(err); }) // 同步写入 fs.writeFileSync(./text.txt,hello boy!)1.2 文件的追加写入 const fs require(fs) fs.appendFile(./text.txt,\r\r\r…

【华为OD机试真题2023CD卷 JAVAJS】高效货运

华为OD2023(C&D卷)机试题库全覆盖,刷题指南点这里 高效货运 知识点递归循环 时间限制:1s 空间限制:32MB 限定语言:不限 题目描述: 1.老李是货运公司承运人,老李的货车额定载货重量为wt 2.现有两种货物,货物A单件重量为wa,单件运费利润为pa,货物B单件重量为wb,单…

0115qt聊天室客户端+数据库

#ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QSqlDatabase>//数据库管理类 #include <QSqlQuery>//执行sql语句类 #include <QSqlRecord>//数据库记录类 #include <QSqlError>//数据库错误类 #include <QMessageBox>/…

win10安装ssh服务

前置条件&#xff1a; 远程虚拟机&#xff0c;防火墙关闭&#xff0c;本地主机与虚拟机互相可以ping通 虚拟机是win10专业版本 操作步骤&#xff1a; 1、搜索框搜索“Windows PowerShell”并以管理员身份运行 2、输入如下代码&#xff0c;检查本地是否有ssh服务&#xff0c…

【Docker】网络模式➕自定义网络

&#x1f973;&#x1f973;Welcome 的Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Docker的相关操作吧 目录 &#x1f973;&#x1f973;Welcome 的Huihuis Code World ! !&#x1f973;&#x1f973; 一.Docker网络模式的介绍 二. 网桥模…

Linux内核架构和工作原理详解(二)

Linux内核体系结构简析简析 图1 Linux系统层次结构 最上面是用户&#xff08;或应用程序&#xff09;空间。这是用户应用程序执行的地方。用户空间之下是内核空间&#xff0c;Linux 内核正是位于这里。GNU C Library &#xff08;glibc&#xff09;也在这里。它提供了连接内核…

【react】记录一次react组件props依赖异步数据(setFieldsValue)后传递form给子组件,再逐层传递给孙子组件引起的未渲染异常

背景 react祖父组件设置异步数据&#xff08;setFieldsValue&#xff09;后传递form给子组件&#xff0c;再逐层传递给孙子组件引起的未渲染异常&#xff0c;孙子组件如果不设置useEffect和useState去监听value的值进行重渲染&#xff0c;会出现获取得到value最新值&#xff0…

【JVM】类的生命周期

目录 类的生命周期 加载阶段 连接阶段 初始化阶段 类的使用阶段 类的加载阶段 类的生命周期 加载阶段 在加载阶段&#xff0c;类加载器首先会通过一个类的全限定名来获取定义此类的二进制字节流。这个步骤主要是将整个Class 文件解析成二进制流。 &#xff08;全限定名是…