Pytorch Lighting 库的学习 mvsplat 的笔记

变量理解:

context_image: 表示投影的 refrence image
Epipolar Transformer vs Swin Transformer : 不同于 Pixel Splat 使用的是 Epipolar Transformer. MVspalt 使用的是 Swin Transformer, 但是作者在 Code 里面 也使用了 Epipolar Transformer 并对此进行了 消融实验:

网络架构,得到 CNN_feature 和 Transformer_feature :

  • 假设 context_imgae shape : (1,2,3,256,256)
  • 进入一个 Backbone Multiview 的Encoder; 这个是 一个 CNN 的 Encoder 去提取 Image 的 feature, 进行了 4 倍的 downsampling , 对应的 cnn_features shape (1,2,128,64,64)
## CNN 提取特征
features_list = self.extract_feature(self.normalize_images(images))  # list of features
  • 对这个 Feature 添加位置信息,使用Transformer 里面的 PE, 但是不会改变 Tensor 的大小。shape (1,2,128,64,64)
    在这里插入图片描述
  • 将上面的 Tensor 送入到 Transformer 当中, 输出的 Tensor 维度不变, transformer 计算的 shape 依然是(1,2,128,64,64)

经过Transformer 网络之后,预测 3D Gaussian feature 和 深度:

  depths, densities, raw_gaussians = self.depth_predictor(in_feats,             ## transformer feature (1,2,128,64,64)context["intrinsics"],context["extrinsics"],context["near"],context["far"],gaussians_per_pixel=True,deterministic=deterministic,extra_info=extra_info,cnn_features=cnn_features,  ## CNN feature (1,2,128,64,64))

变量 refine_out:(1,32,256,256)
image:(2,3,256,256)
pro_fea_in_fullers:(2,128,256,256)

1. 在这个函数中首先进行 数据预处理:
 feat_comb_lists, intr_curr, pose_curr_lists, disp_candi_curr = (   prepare_feat_proj_data_lists(features,intrinsics,extrinsics,near,far,num_samples=self.num_depth_candidates))

主要的 功能如下:

     * 对于 depth 进行等间距的 128 个采样点.* feat_comb_lists 第0个元素是 [0,1] 排列的 transformer feature  feature_01; 第1个元素是 [1,0] 排列的 transformer feature feature_10 ;* 对于 re10k format 的内参 unnormalize*  pose_curr_lists 分别是 0->1 的位姿变换和 1->0 的位姿变换
2. 构建两个 Feature 的 Cost Volume:

feat10: 第一个元素是feature map 1; 第2个元素是feature map 2
pose_curr: 第一个元素是camera 1 -> camera 0 的 Transform ; 第2个元素是camera 0 -> camera 1 的 Transform

2.1 作用: 将feature map 1 根据深度 lift 成一个 3D Volume, 然后根据 Pose 将 3D 点投影到 image 0 的 2D 平面上 interpolate feature.

 for feat10, pose_curr in zip(feat_comb_lists[1:], pose_curr_lists):# 1. project feature1  to camera0 and project feture0 to camera 1# feat10: [0] is feature map 1;  [1] is feature map 0feat01_warped = warp_with_pose_depth_candidates(feat10,intr_curr,pose_curr,1.0 / disp_candi_curr.repeat([1, 1, *feat10.shape[-2:]]),warp_padding_mode="zeros",)  # [B, C, D, H, W] [2, 128, 128, 64, 64] 表示 128,64,64 个3D点 投影到2D平面上query 的feature. 每个feature 的 维度是 128维度

在这里插入图片描述

2.2 根据 不同的 depth 投影得到的 featuure 和原始的 feature 计算 点积 (相似度),然后对于 feature channel 那一个维度 求取 sum

raw_correlation_in = (feat01.unsqueeze(2) * feat01_warped).sum(1) / (c**0.5)  # [vB, D, H, W]

在这里插入图片描述

2.3 使用2D U-Net 进行 CostVolume 的 Refine, 再使用Softmax 函数 估计 出每一个 采样 Depth的 权重。 (准确的Depth 权重应该最大)
   pdf = F.softmax(self.depth_head_lowres(raw_correlation), dim=1)  # [2xB, D, H, W]

在这里插入图片描述

2.4 SoftMax 得到的权重和 depth_candi 点积,可以得到 depth 的预测,然后上采样到原始分辨率
 coarse_disps = (disp_candi_curr * pdf).sum(dim=1, keepdim=True)  # (vb, 1, h, w)fullres_disps = F.interpolate(coarse_disps,scale_factor=self.upscale_factor,mode="bilinear",align_corners=True,)

coarse_disps :(2,1,64,64) 是feature map 的图像 的 Dpeth 预测
fullres_disps :(2,1,256,256) 是原始 Resolution 的图像 的 Dpeth 预测

2.5 对于预测的 Depth 使用 2DU-Net 进行Refine, 得到feature volume。
refine_out = self.refine_unet(torch.cat((extra_info["images"], proj_feature, fullres_disps, pdf_max), dim=1))

最后的 refine depth 是 fullres_disps + delta_disps

   fine_disps = (fullres_disps + delta_disps).clamp(1.0 / rearrange(far, "b v -> (v b) () () ()"),1.0 / rearrange(near, "b v -> (v b) () () ()"),)

refine_out :(2,32,256,256) 是输入U-Net 得到的feature, 是32通道

2.6 利用 Transformer feature, CNN feature, Depth 的预测 和 原始的color 图像, 得到 Gaussian 的 feature map

这个 self. to_gaussians 是一个 两层的 CNN。 输入c=163, 输出 c=84

 # gaussians head
raw_gaussians_in = [refine_out, extra_info["images"], proj_feat_in_fullres]
raw_gaussians_in = torch.cat(raw_gaussians_in, dim=1)
raw_gaussians = self.to_gaussians(raw_gaussians_in) 

输出raw_gaussians (2,84,256,256), 原始分辨率的 Gaussian feature map



下面是各种 Gaussian 属性的 预测 :

1. Opcaity 的 预测

对前面得到的 Costvolume 进行卷积。
输入是 refine_out:(1,32,256,256), 通过卷积 变成2个通道,其中一个作为 density, 另一个作为 视差。 文章的解释: matching volume 里面 对应关系越强,那么 density 越大

delta_disps_density = self.to_disparity(refine_out)
delta_disps, raw_densities = delta_disps_density.split(gaussians_per_pixel, dim=1)# combine coarse and fine info and match shape
densities = repeat(F.sigmoid(raw_densities),"(v b) dpt h w -> b v (h w) srf dpt",b=b,v=v,srf=1,
)

之后将 density 转成opacity, 转换通过一个构造函数进行的:
y = { 0 < x < 1 : 0.5 ⋅ ( 1 − ( 1 − x ) t + x 1 t ) } y = \left\{0<x<1: 0.5 \cdot\left(1-(1-x)^t+x^{\frac{1}{t}}\right)\right\} y={0<x<1:0.5(1(1x)t+xt1)}
在这里插入图片描述

2. Center 的 预测

每一个 pixel 生成一个坐标, 对应一个 Gaussian. Pixel 发生光线,根据 depth 反投影得到 Gaussian 的 Center.. 并不一定是从 像素 中点 发生光心, 因此,每一个 pixel 还有一个 2D 的offset 偏移量· offset_xy ,也是泛化得到的,从 raw_gaussians (2,84,256,256) 的前2个channel 生成。

offset_xy = gaussians[..., :2].sigmoid()  
pixel_size = 1 / torch.tensor((w, h), dtype=torch.float32, device=device)
xy_ray = xy_ray + (offset_xy - 0.5) * pixel_size means = origins + directions * depths[..., None]

3. Scale 的 预测

Scale 由 前3 个channel 确定,还需要和 depth 以及相机内参数有关系。 需要注意一下2点:

  1. Regarding multiplying by depths, further objects will be smaller when projected.
  2. Regarding multiplying by multiplier. This operation constrains the Gaussian scale concerning the pixel width in the image space, which
    aims to ensure that the Gaussian scale with scale 1 is roughly the
    same as 1 pixel in the image space.
scales = scale_min + (scale_max - scale_min) * scales.sigmoid()
h, w = image_shape
pixel_size = 1 / torch.tensor((w, h), dtype=torch.float32, device=device)
multiplier = self.get_scale_multiplier(intrinsics, pixel_size)
scales = scales * depths[..., None] * multiplier[..., None]

4. Covariance 的 预测

Rotations 是由 raw_gaussians 的4个通道预测的,先得到四元数。 之后再和 Scale 构成 协方差矩阵, 注意: 这里的 协方差矩阵是 camera 系下面的,还需要外参转到 world 坐标系

rotations = rotations / (rotations.norm(dim=-1, keepdim=True) + eps)
covariances = build_covariance(scales, rotations)
c2w_rotations = extrinsics[..., :3, :3]
covariances = c2w_rotations @ covariances @ c2w_rotations.transpose(-1, -2)

4. SH 的 预测

剩下的 75个 channel 对应着 SH 系数
opacity 的生成 在 传入下面的函数之前已经生成了,是将 density 转换成 Gaussian 的 Opacity

 # 得到SH系数
sh = rearrange(sh, "... (xyz d_sh) -> ... xyz d_sh", xyz=3)
sh = sh.broadcast_to((*opacities.shape, 3, self.d_sh)) * self.sh_mask

根据上面的属性,得到 泛化的 Gaussian

return Gaussians(means=means,covariances=covariances,harmonics=rotate_sh(sh, c2w_rotations[..., None, :, :]),opacities=opacities,# NOTE: These aren't yet rotated into world space, but they're only used for# exporting Gaussians to ply files. This needs to be fixed...scales=scales,rotations=rotations.broadcast_to((*scales.shape[:-1], 4)),)

生成当前场景的 3DGS 之后,在 Target View 上进行 Render

Pytorch Lighting 的基础知识:

Train 的主函数: training_step 函数:
Test 的主函数: test_step 函数:

Test 的 dataloader 的主函数:
val_dataloader 函数
test_dataloader 函数

数据Dataset 类 全部在 dataset_re10k.py 这个文件

  def test_dataloader(self, dataset_cfg=None):##主要用来 读取的数据文件都在   .torchdataset = get_dataset(self.dataset_cfg if dataset_cfg is None else dataset_cfg,"test",self.step_tracker,) dataset = self.dataset_shim(dataset, "test")return DataLoader(dataset,self.data_loader_cfg.test.batch_size,num_workers=self.data_loader_cfg.test.num_workers,generator=self.get_generator(self.data_loader_cfg.test),worker_init_fn=worker_init_fn,persistent_workers=self.get_persistent(self.data_loader_cfg.test),shuffle=False,)

MVSplat 是加载 chunk 进行实验的:

每一个 chunk 是由 一个 xx.torch 文件加载过来的:

chunk = torch.load(chunk_path)

每一个 chunk 里面有 5个 dtu数据集, 每一个数据集里面存放着 45 张图像, 而每一个 数据集的以字典的形式进行存放。 如下所示,里面存放在 图像的 camera, image 和 数据集的名称 “key”. ycamera 从 “camera” 读取随机一个场景的 内外参数:example 是 chunk 里面的某一个数据集:

 extrinsics, intrinsics = self.convert_poses(example["cameras"])之后 读取图像。

因此,代码里有两个 for loop, 一个 循环 .torch 文件, 一个 循环 torch 文件里面的数据集。

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

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

相关文章

容器项目之前后端分离

容器化部署ruoyi项目 #需要的镜像nginx、java、mysql、redis、 #导入maven镜像、Java镜像和node镜像 docker load -i java-8u111-jdk.tar docker load -i maven-3.8.8-sapmachine-11.tar docker load -i node-18.20.3-alpine3.20.tar #拉取MySQL和nginx镜像 docker pull mysql…

echarts学习:基本使用和组件封装

前言 我在工作中使用echarts较少&#xff0c;这就导致每次使用时都要从头再来&#xff0c;这让我很头疼。因此我决心编写一系列文章将我参与工作后几次使用echarts所用到的知识记录下来&#xff0c;以便将来可以快速查阅。 一、基本使用 像我一样的新手&#xff0c;想要入门e…

【Java】还有人不懂继承?25 个 Case 包教包会

还有人不懂继承&#xff1f;25 个 Case 包教包会 1.Implement single inheritance2.Implement multilevel inheritance3.Implement hierarchical inheritance4.Override a base class method into a derived class5.Demonstrate the protected access specifier6.Create an Stu…

《面试笔记》——MySQL终结篇30

三大范式&#xff1f; 第一范式&#xff1a;字段具有原子性&#xff0c;不可再分&#xff08;字段单一职责&#xff09; 第二范式&#xff1a;满足第一范式&#xff0c;每行应该被唯一区分&#xff0c;加一列存放每行的唯一标识符&#xff0c;称为主键&#xff08;都要依赖主…

10- Redis 键值对数据库是怎么实现的?

在开始将数据结构之前&#xff0c;先给介绍下 Redis 是怎样实现键值对&#xff08;key-value&#xff09;数据库的。 Redis 的键值对中的 key 就是字符串对象&#xff0c;而 value 可以是字符串对象&#xff0c;也可以是集合数据类型的对象&#xff0c;比如 List 对象&#xf…

Django序列化器中is_valid和validate

今天上班的时候分配了一个任务&#xff0c;是修复前端的一个提示优化&#xff0c;如下图所示&#xff1a; 按照以往的经验我以为可以直接在validate上进行校验&#xff0c;如何抛出一个异常即可 &#xff0c;例如&#xff1a; class CcmSerializer(serializers.ModelSerialize…

体验Photoshop:无需下载,直接在浏览器编辑图片

搜索Photoshop时&#xff0c;映入眼帘的是PS软件下载&#xff0c;自学PS软件需要多长时间&#xff0c;学PS软件有必要报班吗...PS软件的设计功能很多&#xff0c;除了常见的图像处理功能外&#xff0c;还涉及图形、文本、视频、出版等。不管你是平面设计师&#xff0c;UI/UX设计…

Servlet搭建博客系统

现在我们可以使用Servlet来搭建一个动态(前后端可以交互)的博客系统了(使用Hexo只能实现一个纯静态的网页,即只能在后台自己上传博客)。有一种"多年媳妇熬成婆"的感觉。 一、准备工作 首先创建好项目,引入相关依赖。具体过程在"Servlet的创建"中介绍了。…

FreeRTOS【14】软件定时器使用

1.开发背景 基于以上的章节&#xff0c;这个篇章主题是软件定时器使用&#xff0c;能使用 FreeRTOS 的基本都是从裸机 MCU 过来的&#xff0c;基本都知道 MCU 最基本的功能之一就是定时器&#xff0c;确切的说是硬件定时器&#xff0c;外围电路已经构建好的&#xff0c;精度很高…

【实战JVM】-实战篇-05-内存泄漏及分析

【实战JVM】-实战篇-05-内存泄漏及分析 1 内存溢出和内存泄漏1.1 常见场景1.2 解决内存溢出的方法1.2.1 发现问题1.2.1.1 top1.2.1.2 ViusalVM1.2.1.3 arthas1.2.1.4 PrometheusGrafana 1.2.2 堆内存状况对比1.2.3 内存泄漏原因-代码中1.2.3.1 equals()-hashCode()1.2.3.2 内部…

小程序-富文本编辑框的注意事项

富文本编辑框官网位置 表单组件 / editor (qq.com)https://developers.weixin.qq.com/miniprogram/dev/component/editor.html &#xff08;一&#xff09;富文本编辑框的作用 1.适用于一些表单的提交 2.这些表单内容需要自定义图片大小&#xff0c;编辑文字样式 主要用到的是…

【C++】10.list

list这个迭代器是双向迭代器&#xff0c;与vector的迭代器具有很大的区别&#xff0c;主要在于双向迭代器不支持&#xff0b;- 操作 正由于list的双向迭代器&#xff0c;因此<algorithm>中的sort()函数无法使用&#xff0c;list单独实现了一个sort()函数&#xff0c;但效…

统计信号处理基础 习题解答10-5

题目 通过令 并进行计算来重新推导MMSE估计量。提示&#xff1a;利用结果 解答 首先需要明确的是&#xff1a; 上式是关于观测值x 的函数 其次需要说明一下这个结果 和教材一样&#xff0c;我们用求期望&#xff0c;需要注意的是&#xff0c;在贝叶斯情况下&#xff0c;是个…

创刊即王炸?首个IF近7分,稳坐中科院1区!同领域全球第一!

【欧亚科睿学术】 01 期刊基本概况 【期刊类型】经济类SSCI 【出版社】SPRINGER出版社 【期刊概况】IF&#xff1a;8.0-9.0&#xff0c;JCR1区&#xff0c;中科院1区 【版面类型】正刊&#xff0c;仅少量版面 【预警情况】2020-2024年无预警记录 【收录年份】2016年被WO…

Facebook开户|Facebook做落地页的标准和建议

哈喽呀家人们下午好~今天Zoey来跟大家带来Facebook做落地页的标准和建议&#xff01;需要的家人建议点赞收藏啦&#xff01;&#xff01;用户通过点击你的推广链接、搜索引擎搜索结果页面的快照链接、社交媒体中的网页链接、电子邮件中的链接等进入你网站的特定页面&#xff0c…

tcp链接中的三次挥手是什么原因

一、tcp链接中的正常四次挥手过程&#xff1f; 刚开始双方都处于 ESTABLISHED 状态&#xff0c;假如是客户端先发起关闭请求。四次挥手的过程如下&#xff1a; 1、客户端打算关闭连接&#xff0c;此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文&#xff0c;也即 FIN 报文…

pytorch项目实战-分类模型李宏毅 21 机器学习第三次作业代码详解 CNN图片分类任务

CNN 卷积神经网络食物分类任务 前言一、数据集介绍二、CNN模型整体框架三、卷积神经网络代码详解3.1 导入需要使用的包3.2 数据集&#xff0c;数据加载器&#xff0c;数据增强操作3.2.1 数据增强3.2.2 数据集构建3.2.3 加载器构建 3.3 卷积神经网络构建3.4 训练代码3.4.1 半监督…

jmeter多用户登录并退出教程

有时候为了模拟更真实的场景&#xff0c;在项目中需要多用户登录并退出操作&#xff0c;大致参考如下 多用户登录前面已经实现&#xff1a;参考博文 多用户登录并退出jmx文件&#xff1a;百度网盘 提取码&#xff1a;0000 一、多用户退出操作 添加一个setUp线程组&#xff0…

Perplexity 搜索引擎刚刚推出了新的页面功能——维基百科可以扔了

Perplexity 允许用户根据搜索结果创建自定义页面 人工智能搜索引擎初创公司 Perplexity 推出了一项新功能&#xff0c;使其结果更具粘性&#xff0c;允许用户将研究转变为易于共享的页面。页面建立在 Perplexity 中现有的人工智能驱动的搜索功能之上&#xff0c;该功能使用与 …

云服务(ECS)Docker安装vulhub安装详解

本文以xshell进行远程控制 1.以ssh连接云服务器 ssh 服务器名公网ip [D:\~]$ ssh root47.99.138.9 在弹框中输入密码 2.安装docker curl -s http://get.docker.com/ | sh rootiZbp1fm14idjlfp53akni8Z:~# curl -s https://get.docker.com/ | sh # Executing docker insta…