Nerstudio 相机优化代码理解

源码

有两种模式,SO3xR3和SE3,代表不同的刚体变换,都是6个参数,表述三个旋转角+3个偏移量

        # Initialize learnable parameters.if self.config.mode == "off":passelif self.config.mode in ("SO3xR3", "SE3"):self.pose_adjustment = torch.nn.Parameter(torch.zeros((num_cameras, 6), device=device))else:assert_never(self.config.mode)

通过相应的函数计算出调整结果adj

def exp_map_SO3xR3(tangent_vector: Float[Tensor, "b 6"]) -> Float[Tensor, "b 3 4"]:"""Compute the exponential map of the direct product group `SO(3) x R^3`.This can be used for learning pose deltas on SE(3), and is generally faster than `exp_map_SE3`.Args:tangent_vector: Tangent vector; length-3 translations, followed by an `so(3)` tangent vector.Returns:[R|t] transformation matrices."""# code for SO3 map grabbed from pytorch3d and stripped down to bare-boneslog_rot = tangent_vector[:, 3:]nrms = (log_rot * log_rot).sum(1)rot_angles = torch.clamp(nrms, 1e-4).sqrt()rot_angles_inv = 1.0 / rot_anglesfac1 = rot_angles_inv * rot_angles.sin()fac2 = rot_angles_inv * rot_angles_inv * (1.0 - rot_angles.cos())skews = torch.zeros((log_rot.shape[0], 3, 3), dtype=log_rot.dtype, device=log_rot.device)skews[:, 0, 1] = -log_rot[:, 2]skews[:, 0, 2] = log_rot[:, 1]skews[:, 1, 0] = log_rot[:, 2]skews[:, 1, 2] = -log_rot[:, 0]skews[:, 2, 0] = -log_rot[:, 1]skews[:, 2, 1] = log_rot[:, 0]skews_square = torch.bmm(skews, skews)ret = torch.zeros(tangent_vector.shape[0], 3, 4, dtype=tangent_vector.dtype, device=tangent_vector.device)ret[:, :3, :3] = (fac1[:, None, None] * skews+ fac2[:, None, None] * skews_square+ torch.eye(3, dtype=log_rot.dtype, device=log_rot.device)[None])# Compute the translationret[:, :3, 3] = tangent_vector[:, :3]return retdef exp_map_SE3(tangent_vector: Float[Tensor, "b 6"]) -> Float[Tensor, "b 3 4"]:"""Compute the exponential map `se(3) -> SE(3)`.This can be used for learning pose deltas on `SE(3)`.Args:tangent_vector: A tangent vector from `se(3)`.Returns:[R|t] transformation matrices."""tangent_vector_lin = tangent_vector[:, :3].view(-1, 3, 1)tangent_vector_ang = tangent_vector[:, 3:].view(-1, 3, 1)theta = torch.linalg.norm(tangent_vector_ang, dim=1).unsqueeze(1)theta2 = theta**2theta3 = theta**3near_zero = theta < 1e-2non_zero = torch.ones(1, dtype=tangent_vector.dtype, device=tangent_vector.device)theta_nz = torch.where(near_zero, non_zero, theta)theta2_nz = torch.where(near_zero, non_zero, theta2)theta3_nz = torch.where(near_zero, non_zero, theta3)# Compute the rotationsine = theta.sin()cosine = torch.where(near_zero, 8 / (4 + theta2) - 1, theta.cos())sine_by_theta = torch.where(near_zero, 0.5 * cosine + 0.5, sine / theta_nz)one_minus_cosine_by_theta2 = torch.where(near_zero, 0.5 * sine_by_theta, (1 - cosine) / theta2_nz)ret = torch.zeros(tangent_vector.shape[0], 3, 4).to(dtype=tangent_vector.dtype, device=tangent_vector.device)ret[:, :3, :3] = one_minus_cosine_by_theta2 * tangent_vector_ang @ tangent_vector_ang.transpose(1, 2)ret[:, 0, 0] += cosine.view(-1)ret[:, 1, 1] += cosine.view(-1)ret[:, 2, 2] += cosine.view(-1)temp = sine_by_theta.view(-1, 1) * tangent_vector_ang.view(-1, 3)ret[:, 0, 1] -= temp[:, 2]ret[:, 1, 0] += temp[:, 2]ret[:, 0, 2] += temp[:, 1]ret[:, 2, 0] -= temp[:, 1]ret[:, 1, 2] -= temp[:, 0]ret[:, 2, 1] += temp[:, 0]# Compute the translationsine_by_theta = torch.where(near_zero, 1 - theta2 / 6, sine_by_theta)one_minus_cosine_by_theta2 = torch.where(near_zero, 0.5 - theta2 / 24, one_minus_cosine_by_theta2)theta_minus_sine_by_theta3_t = torch.where(near_zero, 1.0 / 6 - theta2 / 120, (theta - sine) / theta3_nz)ret[:, :, 3:] = sine_by_theta * tangent_vector_linret[:, :, 3:] += one_minus_cosine_by_theta2 * torch.cross(tangent_vector_ang, tangent_vector_lin, dim=1)ret[:, :, 3:] += theta_minus_sine_by_theta3_t * (tangent_vector_ang @ (tangent_vector_ang.transpose(1, 2) @ tangent_vector_lin))return ret

叠加到 camera_to_worlds 矩阵上

        return torch.cat([# Apply rotation to directions in world coordinates, without touching the origin.# Equivalent to: directions -> correction[:3,:3] @ directionstorch.bmm(adj[..., :3, :3], camera.camera_to_worlds[..., :3, :3]),# Apply translation in world coordinate, independently of rotation.# Equivalent to: origins -> origins + correction[:3,3]camera.camera_to_worlds[..., :3, 3:] + adj[..., :3, 3:],],dim=-1,)

对比两种方式

在你提供的代码中,exp_map_SO3xR3exp_map_SE3是两个函数,它们都用于计算从切空间到特殊欧几里得群SE(3)的指数映射。SE(3)是结合了旋转和平移的群,用于描述三维空间中的刚体运动。这两个函数的主要差异在于它们处理旋转部分的方式不同,以及它们对切向量的解释略有不同。

exp_map_SO3xR3

这个函数计算的是SO(3)(三维旋转群)和R^3(三维平移空间)的直积群的指数映射。它假定输入的切向量前三个分量是平移分量,后三个分量是SO(3)的切向量(通常表示为旋转向量或轴角表示法)。函数首先计算旋转部分的指数映射,然后与平移部分结合,生成最终的[R|t]变换矩阵。

关键步骤包括:

  1. 计算旋转角度(rot_angles)。
  2. 使用旋转角度和对应的旋转向量构造旋转矩阵(通过计算skewsskews_square)。
  3. 结合旋转矩阵和平移向量生成最终的变换矩阵。

exp_map_SE3

这个函数直接计算SE(3)的指数映射。输入的切向量同样包含平移和旋转信息,但是这个函数在处理旋转时采用了不同的方法。它首先计算旋转角度(theta),然后根据旋转角度的大小采用不同的近似方法来计算旋转矩阵。

关键步骤包括:

  1. 分离平移向量(tangent_vector_lin)和旋转向量(tangent_vector_ang)。
  2. 根据旋转角度的大小,选择使用精确计算还是近似计算来得到旋转矩阵。
  3. 计算旋转矩阵并与平移向量结合,生成最终的变换矩阵。

主要差异

  • 旋转处理exp_map_SO3xR3使用了一个简化的方法来直接从旋转向量构造旋转矩阵,而exp_map_SE3则根据旋转角度的大小采用不同的近似方法。
  • 性能exp_map_SO3xR3通常比exp_map_SE3更快,因为它采用了更直接的方法来构造旋转矩阵。
  • 适用性exp_map_SO3xR3适用于学习SE(3)上的位姿增量,而exp_map_SE3则直接处理SE(3)的切向量。

总的来说,这两个函数都是用于从SE(3)的切空间到SE(3)本身的映射,但是它们在处理旋转部分时采用了不同的策略,这可能会影响它们的性能和适用性。

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

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

相关文章

ABC353

A #include<bits/stdc.h>using namespace std;int n;int main() {cin>>n;int m0;int i0;int pos0;while(m<n){mpow(2,i);i;pos;}cout<<pos; }B 模拟 #include <iostream> #include <cstring> #include <algorithm>using namespace s…

进入新公司有焦虑感怎么办?

前因 前两天技术交流群里有童鞋问了一个很有意思的问题&#xff0c;他问如何克服进入新公司的焦虑感&#xff1f;很多热心的童鞋都纷纷支招&#xff0c;比如 “主动干活”、“专注干活”、“让时间冲淡焦虑感”、……等等&#xff0c;这些都很有道理&#xff0c;不过&#xff…

今时今日蜘蛛池还有用吗?

最近不知道哪里又开始刮起“蜘蛛池”这个风气了&#xff0c;售卖、购买蜘蛛池的行为又开始在新手站长圈里开始蔓延和流行了起来&#xff0c;乍一看到“蜘蛛池”这个词给明月的感受就是陌生&#xff0c;要经过回忆才能想起来一些残存的记忆&#xff0c;所谓的蜘蛛池说白了就是利…

PHP编程入门:揭开Web开发的神秘面纱

PHP编程入门&#xff1a;揭开Web开发的神秘面纱 在数字化时代&#xff0c;PHP作为一种广泛使用的服务器端脚本语言&#xff0c;为Web开发领域注入了强大的活力。无论你是编程新手还是有一定经验的开发者&#xff0c;掌握PHP编程都将为你开启一扇通往Web开发新世界的大门。接下…

grpc接口调用

grpc接口调用 准备依赖包clientserver 参考博客&#xff1a; Grpc项目集成到java方式调用实践 gRpc入门和springboot整合 java 中使用grpc java调用grpc服务 准备 因为需要生成代码&#xff0c;所以必备插件 安装后重启 依赖包 <?xml version"1.0" encoding&…

mysql buffer pool 详解

概念&#xff1a;为了缓存磁盘中的页&#xff0c;mysql服务器启动时会向操作系统申请一片连续的内存空间&#xff0c;这片连续的内存空间叫做buffer pool&#xff0c;即缓冲池。 buffer pool 默认大小&#xff1a;128M innodb_buffer_pool_size&#xff1a;自定义缓冲池大小 …

ECS搭建redis4.0集群版

在 CentOS 上安装 Redis 4.0 集群版涉及多个步骤&#xff0c;包括安装 Redis、配置集群并启动它。下面将详细介绍整个过程&#xff1a; 1. 系统更新 首先&#xff0c;保证系统是最新的。 sudo yum update2. 安装依赖项 安装构建 Redis 所必需的依赖&#xff1a; sudo yum …

计算机三级等级考试

计算机等级考试&#xff1a; 一&#xff1a;理论知识考试 100分考60分 1&#xff1a;题库 二&#xff1a;技能考试 100分考60分 1&#xff1a;写文档 项目概述 功能描述 数据库设计 UML 绘 图 用例图 与 包图&#xff08;两个图&#xff09; 2&…

使用 nmcli 命令设置 IP 地址并排查网络故障

在现代网络管理中&#xff0c;nmcli&#xff08;NetworkManager Command Line Interface&#xff09;是一个非常强大和实用的工具。它不仅可以帮助你设置 IP 地址&#xff0c;还能协助排查各种网络故障。今天&#xff0c;我们将深入探讨如何使用 nmcli 命令来高效地管理你的网络…

node mysql的增删改查基础

学习koa时&#xff0c;不选择mongodb&#xff0c;而是MySQL&#xff0c;虽然node对mongodb更亲和&#xff0c;但是我感觉MySQL的键值对的储存结构更正规 1.首选确认你的数据库有个库。有个表,我的如下 2.配置 let mySqlConfig{host:localhost,user:root,password:123456,data…

C#操作MySQL从入门到精通(10)——对查询数据进行通配符过滤

前言 我们有时候需要查询数据,并且这个数据包含某个字符串,这时候我们再使用where就无法实现了,所以mysql中提供了一种模糊查询机制,通过Like关键字来实现,下面进行详细介绍: 本次查询的表中数据如下: 1、使用(%)通配符 %通配符的作用是,表示任意字符出现任意次数…

rose 聊开源—1 你为什么需要一个开源项目

我自己从最开始开源 rosedb/lotusdb&#xff0c;以及一些其他组件&#xff0c;折腾开源也有很多年了&#xff0c;这次想写一个关于开源项目的系列&#xff0c;结合我自己的实际经历&#xff0c;讲讲开源项目的开发、参与、维护、流程规范、收获、盈利等内容&#xff0c;希望这个…

2024.6.5

1、react原理学习&#xff0c; hook、fiber 2、瀑布流组件完善 3、代码随想录二刷

如何充分利用代理IP扩大网络接触面

目录 前言 第一部分&#xff1a;什么是代理IP&#xff1f; 第二部分&#xff1a;如何获取代理IP&#xff1f; 1. IP质量 2. 匿名性 3. 限制 第三部分&#xff1a;如何使用代理IP&#xff1f; 第四部分&#xff1a;如何充分利用代理IP&#xff1f; 总结&#xff1a; 前…

【java前端课堂】04_类的继承

类的继承 在Java中&#xff0c;继承是面向对象编程的四大基本特性之一&#xff0c;它允许我们根据一个已有的类来定义一个新的类&#xff0c;这个新的类继承了原有类的特性&#xff08;属性和方法&#xff09;&#xff0c;并可以添加新的特性或修改原有特性。这样&#xff0c;…

Web前端框架:深入探索与实践

Web前端框架&#xff1a;深入探索与实践 在当下数字化飞速发展的时代&#xff0c;Web前端框架的选择与应用成为了开发者们关注的焦点。Node.js&#xff0c;作为一种强大的后端技术&#xff0c;在前端框架的构建中也发挥着不可或缺的作用。本文将围绕Node.js Web前端框架&#…

KNN 算法【python,机器学习,算法】

KNN&#xff08;K-Nearest Neighbors&#xff09;算法是一种基本的、易于理解的机器学习算法&#xff0c;用于分类和回归问题。在 KNN 中&#xff0c;一个对象的分类或值是基于其k个最近邻居的多数投票或平均值来决定的。 基本原理 距离度量&#xff1a;首先&#xff0c;KNN …

SRE养成计划之02-基本命令(持续更新)

基本命令&#xff08;续&#xff09; 软连接 软连接 --> 原始文档 --> 文档数据格式&#xff1a;ln -s 原始文件或目录 软连接文件若原始文件或目录被删除&#xff0c;链接文件将失效软连接可存放在不同分分区/文件系统 硬链接 硬链接 --> 文档数据格式&#xff1…

【Python数据预处理系列】Pandas 数据操作实战:掌握 .loc[] 方法进行高效数据选取

文章将详细介绍.loc[]方法的各种使用场景&#xff0c;帮助读者深入理解并掌握这一核心功能。 在Pandas库中&#xff0c;.loc[]方法是一种强大而灵活的数据选取工具。本文将通过详细的步骤和示例&#xff0c;手把手教您如何利用这一工具进行高效的数据操作。 首先&#xff0c;我…

waf安全事件的监控指标

概述 Web应用防火墙&#xff08;WAF&#xff09;是一种网络安全设备&#xff0c;主要用于保护网站免受各种网络攻击&#xff0c;如SQL注入、跨站脚本&#xff08;XSS&#xff09;等。WAF通过监视和分析传入的应用程序流量&#xff0c;根据预设的规则集对流量进行过滤&#xff…