# 【三维重建】【深度学习】NeRF代码Pytorch实现--数据加载(中)

【三维重建】【深度学习】NeRF代码Pytorch实现–数据加载(中)

论文提出了一种5D的神经辐射场来作为复杂场景的隐式表示,称为NeRF,其输⼊稀疏的多⻆度带pose的图像训练得到⼀个神经辐射场模型。简单来说就是通过输入同一场景不同视角下的二维图片和相机位姿,对场景进行三维隐式建模,并通过体素渲染方程实现了合成任意新视角下的场景图片。本篇博文将根据代码执行流程解析数据加载过程中具体的功能模块代码。


文章目录

  • 【三维重建】【深度学习】NeRF代码Pytorch实现--数据加载(中)
  • 前言
  • load_llff_data
  • spherify_poses
  • 总结


前言

在详细解析NeuS网络之前,首要任务是搭建NeRF【win10下参考教程】所需的运行环境,并完成模型的训练和测试,展开后续工作才有意义。
本博文是对NeuS数据加载过程中涉及的部分功能代码模块进行解析,其他代码模块后续的博文将会陆续讲解。

博主将各功能模块的代码在不同的博文中进行了详细的解析,点击【win10下参考教程】,博文的目录链接放在前言部分。


load_llff_data

load_llff_data在load_llff.py文件内,由于内容太多,博主将这个函数的代码分段进行讲解,本博文将继续讲解load_llff_data函数的后续代码。

# 用于将相机分布限制在固定球体内并返回一个环绕的相机轨迹位姿用于新视角合成。
if spherify:poses, render_poses, bds = spherify_poses(poses, bds)

spherify_poses

spherify_poses在load_llff.py文件内,函数代码比较简洁,但内容比较丰富,理解存在难度(博主个人觉得),比较难理清每行代码乃至每个变量表达的含义和目的,因此博主将函数代码拆分成几段分别讲解,懂得可以快速过。

  • min_line_dist找到离所有相机中心射线距离之和最短的点,博主找遍了现有网络公开资料也没有发现其具体的原理支持,有知道的朋友可以再评论区留言。
# 让位姿[3×4]变为[4×4]
p34_to_44 = lambda p : np.concatenate([p, np.tile(np.reshape(np.eye(4)[-1, :], [1, 1, 4]), [p.shape[0], 1, 1])], 1)
# 位姿的旋转矩阵R的第三列(z轴相关) 方向向量
rays_d = poses[:, :3, 2:3]  # [N,3,1]
# 位姿的平移矩阵t  相机光心
rays_o = poses[:, :3, 3:4]  # [N,3,1]# 找到离所有相机中心射线距离之和最短的点
def min_line_dist(rays_o, rays_d):A_i = np.eye(3) - rays_d * np.transpose(rays_d, [0,2,1])    # [N,3,3]b_i = -A_i @ rays_o         # [N,3,1]pt_mindist = np.squeeze(-np.linalg.inv((np.transpose(A_i, [0,2,1]) @ A_i).mean(0)) @ (b_i).mean(0))  # [N,3]return pt_mindist# 简单理解为场景的中心位置
pt_mindist = min_line_dist(rays_o, rays_d)      # [3]
center = pt_mindist

代码的示意图如下图所示:

  • c2w用于中心化相机位姿,这段代码的功能类似于上篇博文的recenter_poses方法,这里不再赘述。
# 所有相机光心到场景中心的方向向量的平均距离向量(xyz轴上)
up = (poses[:, :3, 3] - center).mean(0)     # [3]
# 归一化:平均单位向量
vec0 = normalize(up)    # [3]
# 找到俩俩垂直的单位方向向量
vec1 = normalize(np.cross([.1,.2,.3], vec0))    # [3]
vec2 = normalize(np.cross(vec0, vec1))             # [3]
pos = center
# 构建坐标系
c2w = np.stack([vec1, vec2, vec0, pos], 1)  # [3,4]
# 求c2w的逆矩阵,并与poses进行矩阵运算,目的是完成所有相机位姿的归一化
poses_reset = np.linalg.inv(p34_to_44(c2w[None])) @ p34_to_44(poses[:, :3, :4])      # [N,4,4]

代码的示意图如下图所示:

  • 将所有相机的位置缩放到单位圆内。
# 理解为归一化后所有光心距离的平均
rad = np.sqrt(np.mean(np.sum(np.square(poses_reset[:, :3, 3]), -1)))
# 缩放因子
sc = 1./rad
# 缩放光心
poses_reset[:, :3, 3] *= sc
# 缩放边界
bds *= sc
# 归一化
rad *= sc

代码的示意图如下图所示:

  • 生成新视角的相机位姿。
# 平均光心位置
centroid = np.mean(poses_reset[:, :3, 3], 0)        # [3]
zh = centroid[2]            # 平均光心z轴距离
radcircle = np.sqrt(rad**2-zh**2)
new_poses = []
for th in np.linspace(0., 2.*np.pi, 120):camorigin = np.array([radcircle * np.cos(th), radcircle * np.sin(th), zh])up = np.array([0, 0, -1.])vec2 = normalize(camorigin)# 构建坐标系vec0 = normalize(np.cross(vec2, up))vec1 = normalize(np.cross(vec2, vec0))pos = camoriginp = np.stack([vec0, vec1, vec2, pos], 1)       # [3,4]new_poses.append(p)# 新视角:拼接在一起
new_poses = np.stack(new_poses, 0)      # [num,3,4]
# [num,3,5] 新视角位姿都拼接了原始位姿的起始位姿
new_poses = np.concatenate([new_poses, np.broadcast_to(poses[0, :3, -1:], new_poses[:, :3, -1:].shape)], -1)
# [num,3,5] 旋转平移后的新位姿都拼接了原始位姿的起始位姿
poses_reset = np.concatenate([poses_reset[:, :3, :4], np.broadcast_to(poses[0, :3, -1:], poses_reset[:, :3, -1:].shape)], -1)   

代码的示意图如下图所示:

左图是xy平面的视角,对于生成的新视角的相机光心的位置camorigin,z的大小是固定的zh,x和y则在半径为radcircle 的圆上;右图是世界坐标系下的视角,右图中列举了四个点,分别对应左图中在坐标轴上的四个点,并计算出这四个点位姿。

其他点画图表示太难了,读者领会精神即可


总结

尽可能简单、详细的介绍数据加载过程中部分代码:spherify_poses球面化相机分布并获取环绕相机位姿。后续会讲解其他功能模块的代码。

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

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

相关文章

【java】LinkedList 和 ArrayList的简介与对比

Java LinkedList和 ArrayList 在使用上,几乎是一样的。由于LinkedList是基于双向链表的,会多出list.getFirst();获取头部元素等方法 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按…

nginx会话保持

ip_hash:通过IP保持会话 作用: nginx通过后端服务器地址将请求定向的转发到服务器上。 将客户端的IP地址通过哈希算法加密成一个数值 如果后端有多个服务器,第一次请求到服务器A, 并在务器登录成功,那么再登录B服务器就要重新…

基于Visual studio创建API项目

API(英文全称:Application Programming Interface,中文:应用程序编程接口) 为什么要 通过API接口可以与其他软件实现数据相互通信,API这项技术能够提高开发效率。 本文是基于vs2017 .net平台搭建API。希望可以帮助到学…

机器学习:什么是分类/回归/聚类/降维/决策

目录 学习模式分为三大类:监督,无监督,强化学习 监督学习基本问题 分类问题 回归问题 无监督学习基本问题 聚类问题 降维问题 强化学习基本问题 决策问题 如何选择合适的算法 我们将涵盖目前「五大」最常见机器学习任务&#xff1a…

VS Code内存占用过高 - 解决方案

前言 使用VS Code时,其占用的内存可能会急剧增加,从而增加计算机内存的压力,下文介绍如何减少VS Code的内存占用。 通过此方案,本人从3G的内存占用降到了700M的内存占用。 解决方案 打开VS Code的设置,如下图&…

无锁并发:探秘CAS机制的魔力

😊 作者: 一恍过去 💖 主页: https://blog.csdn.net/zhuocailing3390 🎊 社区: Java技术栈交流 🎉 主题: 无锁并发:探秘CAS机制的魔力 ⏱️ 创作时间: 2…

Qt --- QTimer

在Qt开发界面的时候,非常多的时候都得使用定时器,定时器具体可以干什么呢?比如:控制时钟、定时改变样式、改变进度等。。。说到这里,经常使用QQ,而不同的时段都会显示不同的背景,我认为如果用Qt…

《网络是怎样连接的》(五)

本文主要取材于 《网络是怎样连接的》 第五章。 目录 5.1 Web服务器的部署地点 5.2 防火墙的结构和原理 5.3服务器负载平衡 5.4 使用缓存服务器分担负载 5.5 内容分发服务 简述:本文主要内容是解释 网络包如何朝服务器前进,并通过服务器前面的防…

Tomcat10安装及配置教程win11

Tomcat10安装及配置教程win11 Tomcat下载链接 Tomcat官网 Tomcat官网地址 https://tomcat.apache.org/ Tomcat的版本列表 点击上图中左侧红框内**Which version?**即可得下图 下载Tomcat 点击上图中左侧红框内红框内tomcat版本即可得下图,下载zip包 解压zip包…

在日本做程序员能攒到钱吗?

如果你就是无欲无求,和人合租,自己做饭,不买高级食材,没有业余爱好,那我可以肯定告诉你一定能攒下钱,问题你是吗?能不能攒下钱丰俭由人,拿的少也有人能攒下钱,拿的多的也…

HTTP 框架修炼之道 | 青训营

Powered by:NEFU AB-IN 文章目录 HTTP 框架修炼之道 | 青训营 走进 HTTP 协议HTTP 框架的设计与实现应用层中间件层路由设计协议层 传输层(网络层)1. BIO(Blocking I/O):2. NIO(Non-blocking I/O):区别&…