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

news2024/11/22 17:13:37

【三维重建】【深度学习】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 = camorigin
    p = 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.coloradmin.cn/o/940191.html

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

相关文章

GCNet论文总结和代码实现

GCNet: Non-local Networks Meet Squeeze-Excitation Networks and Beyond(当非局部网络遇到挤压激励网络) 论文:GCNet: Non-local Networks Meet Squeeze-Excitation Networks and Beyond 源码:https://gitcode.net/mirrors/xvji…

【LeetCode】227. 基本计算器 II

227. 基本计算器 II(中等) 方法:双栈解法 思路 我们可以使用两个栈 nums 和 ops 。 nums : 存放所有的数字ops :存放所有的数字以外的操作 然后从前往后做,对遍历到的字符做分情况讨论: 空格 …

爬虫逆向实战(二十三)--某准网数据

一、数据接口分析 主页地址:某准网 1、抓包 通过抓包可以发现数据接口是api_to/search/company_v2.json 2、判断是否有加密参数 请求参数是否加密? 通过查看“载荷”模块可以发现b参数和kiv参数是加密参数 请求头是否加密? 无响应是否加…

torch.mul()函数使用说明,含高维张量实例及运行结果

torch.mul函数使用说明,含实例及运行结果 torch.mul() 函数torch.mul() 函数定义参数及功能高维数据实例解释 参考博文及感谢 torch.mul() 函数 对输入的张量或数做点积运算,如果维度不统一会想进行维度统一(广播机制)&#xff0…

PConv : Run, Don’t Walk: Chasing Higher FLOPS for Faster Neural Networks

摘要 为了设计快速的神经网络,**许多研究都集中在减少浮点运算(FLOPs)**的数量。然而,我们观察到这种FLOPs的减少并不一定会导致相同程度的延迟减少。这主要是由于浮点运算每秒效率较低的问题所致。为了实现更快的网络,我们重新审视了流行的操作算子,并证明这种低FLOPS主…

docker高级(DockerFile解析)

1、构建三步骤 编写Dockerfile文件 docker build命令构建镜像 docker run依镜像运行容器实例 2、DockerFile构建过程解析 Dockerfile内容基础知识 1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数 2:指令按照从上到下,顺序执行…

异地访问Oracle数据库的解决方案:利用内网穿透实现PL/SQL远程连接的建议与步骤

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle ​ 小月糖糖主页 在强者的眼中,没有最…

SolidWorks软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 SolidWorks是一款由达索系统(Dassault Systmes)开发的三维计算机辅助设计(CAD)软件,被广泛应用于机械、电子、建筑和航空航天等领域。它以易学易用、强大的功能和良好的…

Michael.W基于Foundry精读Openzeppelin第32期——SignatureChecker.sol

Michael.W基于Foundry精读Openzeppelin第32期——SignatureChecker.sol 0. 版本0.1 SignatureChecker.sol 1. 目标合约2. 代码精读2.1 isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) 0. 版本 [openzeppelin]:v4.8.3,[for…

华为OD机试 - 云短信平台优惠活动 - 回溯(Java 2023 B卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…

教师如何有效地发放开学通知并收集签名回执?

老师在即将开学时,希望能够向家长发送开学通知,并确认家长已经收到通知。接下来教给各位老师如何完成这个需求的步骤: 好消息!博主给大家争取到的易查分福利,只需要在注册时输入邀请码:xmt66,就…

从AD迁移至AAD,看体外诊断领军企业如何用网络准入方案提升内网安全基线

摘要: 某医用电子跨国集团中国分支机构在由AD向AzureAD Global迁移时,创新使用宁盾网络准入,串联起上海、北京、无锡等国内多个职场与海外总部,实现平滑、稳定、全程无感知的无密码认证入网体验,并通过合规基线检查,确…

CAD的清除命令如何使用?CAD的清除命令使用方法

CAD广泛应用于土木建筑、装饰装潢、城市规划、园林设计、电子电路、机械设计、服装鞋帽、航空航天、轻工化工等诸多领域,因此CAD越来越成为一项基本技能,很多用人岗位都会要求会使用CAD,为帮助更多人快速学会CAD,而且CAD的使用本身…

taobao.trade.fullinfo.get(获取单笔交易的详细信息)天猫国际站店铺订单接口方法

淘宝交易API taobao.trade.fullinfo.get(获取单笔交易的详细信息) 获取单笔交易的详细信息 1. 只有单笔订单的情况下Trade数据结构中才包含商品相关的信息 2. 获取到的Order中的payment字段在单笔子订单时包含物流费用,多笔子订单时不包含物…

STM32--SPI通信与W25Q64(2)

STM32–SPI通信与W25Q64(1) 文章目录 SPI外设特征 SPI框图传输模式主模式全双工连续传输 非连续传输硬件SPI读写W25Q64 SPI外设 STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能,减轻CPU的负担。 特…

leetcode 496. 下一个更大元素 I

2023.8.28 这题提供暴力解法和单调栈法两种方法。 暴力解&#xff1a; class Solution { public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {vector<int> ans(nums1.size(),-1);for(int i0; i<nums1.size…

『FastGithub』一款.Net开源的稳定可靠Github加速神器,轻松解决GitHub访问难题

&#x1f4e3;读完这篇文章里你能收获到 如何使用FastGithub解决Github无法访问问题了解FastGithub的工作原理 文章目录 一、前言二、项目介绍三、访问加速原理四、FastGithub安装1. 项目下载2. 解压双击运行3. 运行效果4. GitHub访问效果 一、前言 作为开发者&#xff0c;会…

springMVC之拦截器

文章目录 前言一、拦截器的配置二、拦截器的三个抽象方法三、多个拦截器的执行顺序总结 前言 拦截器 一、拦截器的配置 SpringMVC中的拦截器用于拦截控制器方法的执行 SpringMVC中的拦截器需要实现HandlerInterceptor SpringMVC的拦截器必须在SpringMVC的配置文件中进行配置&…

数字化智能工厂信息化系统集成整合规划建设方案[150页word]

导读&#xff1a;原文《150页6万字数字化智能工厂信息化系统集成整合规划建设方案》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 数字化智能工厂建设方案 设备智…

大数据学习:Hive常用函数

Hive常用函数 1. Hive的参数传递 1.1 Hive命令行 查看hive命令的参数 [hadoopnode03 ~]$ hive -help语法结构: hive [-hiveconf xy]* [<-i filename>]* [<-f filename>|<-e query-string>][-S] 说明&#xff1a; -i 从文件初始化HQL。-e从命令行执行指定…