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/22639.shtml

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

相关文章

【Vue】v-model在其他表单元素的使用

讲解内容&#xff1a; 常见的表单元素都可以用 v-model 绑定关联 → 快速 获取 或 设置 表单元素的值 它会根据 控件类型 自动选取 正确的方法 来更新元素 输入框 input:text ——> value 文本域 textarea ——> value 复选框 input:checkbox ——> checked…

AI提示词Prompts有没有好公式?( 计育韬老师高校公益巡讲答疑实录2024)

这是计育韬老师第 8 次开展面向全国高校的新媒体技术公益巡讲活动了。而在每场讲座尾声&#xff0c;互动答疑环节往往反映了高校师生当前最普遍的运营困境&#xff0c;特此计老师在现场即兴答疑之外&#xff0c;会尽量选择有较高价值的提问进行文字答疑梳理。 *本轮巡讲主题除了…

Collection接口使用原则和常用方法

Collection接口的实现类的特点&#xff1a; public interface Collection<E> extends Iterable<E> 1.collection实现的子类可以存放多种元素&#xff0c;每个元素可以是Object类及其子类 2.实现Collection实现类&#xff0c;有些是有序的&#xff08;List&#…

探索Linux中的gzip命令:压缩与解压缩的艺术

探索Linux中的gzip命令&#xff1a;压缩与解压缩的艺术 在Linux世界中&#xff0c;文件压缩和解压缩是日常任务中不可或缺的一部分。gzip命令是这些任务中的佼佼者&#xff0c;它提供了高效的压缩和解压缩功能&#xff0c;广泛应用于各种场景。本文将带您深入了解gzip命令的工…

国内这些免费好用的saas软件你知道几个?

什么是saas软件&#xff1f; 软件即服务&#xff0c;或简称SaaS&#xff0c;是一种用于向用户提供软件的基于云的方法。软件即服务&#xff08;SaaS&#xff09;是一种基于云的软件模型&#xff0c;可通过Internet 浏览器将应用程序交付给最终用户。SaaS 供应商托管服务和应用程…

将现有web项目打包成electron桌面端教程

后续项目需要web端和桌面端&#xff0c;为了提高开发效率&#xff0c;准备直接将web端的代码打包成桌面端&#xff0c;在此提前记录一下demo打包的过程&#xff0c;我的项目是vue3tsvite&#xff0c;需要注意的是vue2或者vue3jsvite或者vue-cli的打包方式各不同&#xff0c;如果…

adb server version (22000) doesn‘t match this client (41); killing...

参考链接: adb server version (31) doesn’t match this client (41); killing… 解决此问题 电脑安装了360手机助手占用了adb的端口引起的。因为套接字的唯一性&#xff08;一个套接字只能由 协议/网络地址/端口号 唯一确定 &#xff09;&#xff0c;一个电脑只能有一个程序…

降低Redis内存使用和提升性能的一些方案

前言 一、前言 Redis在现在开发中已经成为了一个不可或缺的组件&#xff0c;很多项目都会依赖Redis进行开发&#xff0c;当数据量和请求量以及Redis本身访问率不高的情况下&#xff0c;Redis不会成为性能瓶颈&#xff0c;但是如果本身处于高并发海量数据这些情况下&#xff0…

伏图(Simdroid)5.0 电子散热模块介绍

伏图-电子散热模块&#xff08;Simdroid-EC&#xff09;是云道智造基于通用多物理场仿真PaaS平台伏图开发的针对电子元器件、设备等散热的专用热仿真模块&#xff0c;内置电子产品专用零部件模型库&#xff0c;支持用户通过“搭积木”的方式快速建立电子产品的热分析模型&#…

Facebook开户|如何科学高效投放Facebook Ads

中午好家人们~今天Zoey来聊聊如何科学高效投放Facebook Ads~ 一、定义目标受众 在开始广告投放之前&#xff0c;需要明确定义你的目标受众。你可以根据受众的年龄、性别、兴趣、行为以及他们所在的地理位置等信息来确定目标受众。这样有助于创建精准的广告&#xff0c;并确保广…

下载Keil芯片包的方法

Keil里面弹出来的这个蓝色超链接&#xff0c;没梯子不要用edge浏览器 Arm Keil | Devices

对接专有钉钉(浙政钉)登陆步骤

背景 因为项目需要对接浙政钉&#xff0c;我想应该和之前对接阿里云的钉钉登陆钉钉登陆类似&#xff0c;就上网搜索看看&#xff0c;出现了个专有钉钉的概念&#xff0c;就一时间搞不清楚&#xff0c;钉钉&#xff0c;专有钉钉&#xff0c;浙政钉的区别&#xff0c;后续稍微理…

儿童护眼灯什么牌子好点?五款儿童护眼灯品牌推荐

儿童护眼灯什么牌子好点&#xff1f;根据往年的统计&#xff0c;我国青少年近视率位居世界第一&#xff0c;儿童青少年总体近视率达到了52.7%。其中&#xff0c;6岁儿童的近视率为14.5%&#xff0c;小学生为36.0%&#xff0c;初中生为71.6%&#xff0c;高中生为81%。造成近视的…

基于STM32的位置速度环PID控制伺服电机转动位置及程序说明

PID控制原理 PID控制原理是一种广泛应用于工业自动化和其他领域的控制算法。PID控制器的名字来源于其三个主要组成部分&#xff1a;比例&#xff08;Proportional&#xff09;、积分&#xff08;Integral&#xff09;和微分&#xff08;Derivative&#xff09;。PID控制器实现…

Go方法特性详解:简单性和高效性的充分体现

本文深入探讨了Go语言中方法的各个方面&#xff0c;包括基础概念、定义与声明、特性、实战应用以及性能考量。文章充满技术深度&#xff0c;通过实例和代码演示&#xff0c;力图帮助读者全面理解Go方法的设计哲学和最佳实践。 关注作者&#xff0c;分享互联网架构、云服务技术的…

excle中数据分析,excle导入用sql简单处理

前言&#xff1a; 办法一&#xff1a;直接用excle导入db就行&#xff0c;如果excle导如db不能用&#xff0c;就用笨办法下面这个方法去做 1、从系统中导出excle 2、db中插入相应的表和标题 3、先手动插入条件&#xff0c;把insert语句复制出来 INSERT INTO test.test (orders…

Linux 命令 `diff` 的深度解析

Linux 命令 diff 的深度解析 在 Linux 系统中&#xff0c;diff 命令是一个非常重要的工具&#xff0c;用于比较两个文件或目录的差异。无论是代码审查、版本控制还是日常的文件管理&#xff0c;diff 命令都能为我们提供极大的便利。下面&#xff0c;我们将详细解析 diff 命令的…

呼叫中心系统一些常用的功能都有哪些?okcc呼叫中心磐石云pscc呼叫中心

批量上传数据 号码、客户信息一键导入&#xff0c;自动识别归属地等信息&#xff0c;可指定范围呼叫号码。 可视化流程编辑 在线可视化流程编辑&#xff0c;仅需轻轻拖拽便可创建外呼话术流程&#xff0c;话术预览、设置机器人回答机制、外呼测试一步搞定&#xff01; 真人声音…

Objective-C相关开发中, 为什么 delegate protocol 不建议单独写一个头文件 ?

概述 将 delegate protocol 定义放在与相关类的头文件中&#xff0c;有助于保持代码组织的一致性、减少编译依赖、避免命名冲突&#xff0c;并增强逻辑上的一致性。这些因素综合起来&#xff0c;使得这种做法在 Objective-C 开发中被广泛推荐。 在 Objective-C 开发中&#xf…

动态规划详细解释

动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&#xff09;是一种用于解决复杂问题的算法思想&#xff0c;特别适用于具有重叠子问题和最优子结构性质的问题。它通过将问题分解为更小的子问题&#xff0c;并保存这些子问题的解以避免重复计算&#xff0c;从而提高…