将针孔模型相机 应用到3DGS

Motivation

3DGS 的 投影采用的是 CG系的投影矩阵 P P P, 默认相机的 principal point (相机光心) 位于图像的中点处。但是 实际应用的 绝大多数的 相机 并不满足这样一个设定, 因此我们 需要根据 f , c x , c y {f,c_x, c_y} f,cx,cy 这几个参数重新构建3D GS 的 投影矩阵。

3DGS 的相机模型的构建

原理:

目的: 将一个 相机View 坐标系的一个3D 点 变换到 NDC 坐标系

维基百科:https://www.songho.ca/opengl/gl_projectionmatrix.html

一共有如下3个坐标系

Eye 坐标系(View 坐标系) : ( x e , y e , z e ) (x_e,y_e,z_e) (xe,ye,ze)

View 坐标系 通过转化 矩阵 M p r o j M_{proj} Mproj 转化到Clip 坐标系。**先进行 缩放变换,**缩放之后的坐标是 ( x p , y p , z p ) (x_p,y_p,z_p) (xp,yp,zp), 缩放之后继续做正交投影 【 就是把 (l,r)映射到 (-1,1)】,最后才可以变换到Clip坐标系下面的坐标 ( x c , y c , z c ) (x_c,y_c,z_c) (xc,yc,zc)

Clip坐标系 : ( x c , y c , z c ) (x_c,y_c,z_c) (xc,yc,zc)

Clip 坐标系通过除以 齐次坐标系的 最后一个分量转换到 NDC 坐标系

NDC坐标系 : ( x n , y n , z n ) (x_n,y_n,z_n) (xn,yn,zn)

在这里插入sd图片描述
n为视锥体近面z坐标,f为远面z坐标,
t为视锥体top面z坐标,b为 bottom面y坐标,
r为视锥体right x坐标,left为左面x坐标,

1. 从 View 坐标系转化到 Clip 坐标系

主要是通过相似三角形的 原理去列方程:
x p = − n ⋅ x e z e = n ⋅ x e − z e x_p=\frac{-n \cdot x_e}{z_e}=\frac{n \cdot x_e}{-z_e} xp=zenxe=zenxe
y p = − n ⋅ y e z e = n ⋅ y e − z e y_p=\frac{-n \cdot y_e}{z_e}=\frac{n \cdot y_e}{-z_e} yp=zenye=zenye
z p z_p zp 坐标的求解,可以观看 闫令琪 的计算机图像学:有两个基本假设:

  • Near 的平面的所有点 Z 缩放之后的 Z值不会发生变化;
  • Far 平面的所有点 Z 缩放之后的 Z值不会发生变化;

得到了 缩放之后的 ( x p , y p , z p ) (x_p,y_p, z_p) (xp,yp,zp), 然后我们再通过线性变换做正交投影将Cuboid 的长和宽分别缩放到 一个 单位立方体, 即将 [l, r] ⇒ [-1, 1] and [b, t] ⇒ [-1, 1]。
Eq2:
x c = α x x p + β x x_c=\alpha_x x_p+\beta_x xc=αxxp+βx
y c = α y y p + β y y_c=\alpha_y y_p+\beta_y yc=αyyp+βy

x p x_p xp x e x_e xe 的关系带入上面Eq2式子当中。以 x 坐标为例,由于l对应-1,r对应1,求解出 α \alpha α β \beta β我们有:

x c = 2 x p r − l − r + l r − l ( x p = n x e − z e ) = 2 ⋅ n ⋅ x e − z e r − l − r + l r − l = 2 n ⋅ x e ( r − l ) ( − z e ) − r + l r − l = 2 n r − l ⋅ x e − z e − r + l r − l = 2 n r − l ⋅ x e − z e + r + l r − l ⋅ z e − z e = ( 2 n r − l ⋅ x e + r + l r − l ⋅ z e ⏟ x c ) / − z e \begin{aligned} x_c& =\frac{2 x_p}{r-l}-\frac{r+l}{r-l} \quad\left(x_p=\frac{n x_e}{-z_e}\right) \\ & =\frac{2 \cdot \frac{n \cdot x_e}{-z_e}}{r-l}-\frac{r+l}{r-l} \\ & =\frac{2 n \cdot x_e}{(r-l)\left(-z_e\right)}-\frac{r+l}{r-l} \\ & =\frac{\frac{2 n}{r-l} \cdot x_e}{-z_e}-\frac{r+l}{r-l} \\ & =\frac{\frac{2 n}{r-l} \cdot x_e}{-z_e}+\frac{\frac{r+l}{r-l} \cdot z_e}{-z_e} \\ & =(\underbrace{\frac{2 n}{r-l} \cdot x_e+\frac{r+l}{r-l} \cdot z_e}_{x_c}) /-z_e\end{aligned} xc=rl2xprlr+l(xp=zenxe)=rl2zenxerlr+l=(rl)(ze)2nxerlr+l=zerl2nxerlr+l=zerl2nxe+zerlr+lze=(xc rl2nxe+rlr+lze)/ze

y c = 2 y p t − b − t + b t − b ( y p = n y e − z e ) = 2 ⋅ n ⋅ y e − z e t − b − t + b t − b = 2 n ⋅ y e ( t − b ) ( − z e ) − t + b t − b = 2 n t − b ⋅ y e − z e − t + b t − b = 2 n t − b − z e ⋅ y e + t + b t − b − z e = ( 2 n t − b ⋅ y e + t + b t − b ⋅ z e ⏟ y c ) / − z e \begin{aligned} y_c & =\frac{2 y_p}{t-b}-\frac{t+b}{t-b} \quad\left(y_p=\frac{n y_e}{-z_e}\right) \\ & =\frac{2 \cdot \frac{n \cdot y_e}{-z_e}}{t-b}-\frac{t+b}{t-b} \\ & =\frac{2 n \cdot y_e}{(t-b)\left(-z_e\right)}-\frac{t+b}{t-b} \\ & =\frac{\frac{2 n}{t-b} \cdot y_e}{-z_e}-\frac{t+b}{t-b} \\ & =\frac{2 n}{\frac{t-b}{-z_e} \cdot y_e}+\frac{t+b}{\frac{t-b}{-z_e}} \\ & =(\underbrace{\frac{2 n}{t-b} \cdot y_e+\frac{t+b}{t-b} \cdot z_e}_{y_c}) /-z_e\end{aligned} yc=tb2yptbt+b(yp=zenye)=tb2zenyetbt+b=(tb)(ze)2nyetbt+b=zetb2nyetbt+b=zetbye2n+zetbt+b=(yc tb2nye+tbt+bze)/ze

上面的恰好是 Clip 坐标系的 齐次坐标系。 发现 计算的 x c , y c x_c,y_c xc,yc 恰好是 除以了 − z e -z_e ze, 因此 我们可以预先指定 齐次坐标的 第四项是: w c = − z e w_c = -z_e wc=ze earlier。 下面是 Clip 坐标系的齐次坐标:
( x c y c z c w c ) = ( 2 n r − l 0 r + l r − l 0 0 2 n t − b t + b t − b 0 ⋅ ⋅ ⋅ ⋅ 0 0 − 1 0 ) ( x e y e z e w e ) \left(\begin{array}{c}x_c \\ y_c \\ z_c \\ w_c\end{array}\right)=\left(\begin{array}{cccc}\frac{2 n}{r-l} & 0 & \frac{r+l}{r-l} & 0 \\ 0 & \frac{2 n}{t-b} & \frac{t+b}{t-b} & 0 \\ \cdot & \cdot & \cdot & \cdot \\ 0 & 0 & -1 & 0\end{array}\right)\left(\begin{array}{l}x_e \\ y_e \\ z_e \\ w_e\end{array}\right) xcyczcwc = rl2n000tb2n0rlr+ltbt+b1000 xeyezewe

$Z的推导 和 x,y 没有关系。因此 上面的矩阵写成下面的形式:
( x c y c z c w c ) = ( 2 n r − l 0 r + l r − l 0 0 2 n t − b t + b t − b 0 0 0 A B 0 0 − 1 0 ) ( x e y e z e w e ) \left(\begin{array}{c}x_c \\ y_c \\ z_c \\ w_c\end{array}\right)=\left(\begin{array}{cccc}\frac{2 n}{r-l} & 0 & \frac{r+l}{r-l} & 0 \\ 0 & \frac{2 n}{t-b} & \frac{t+b}{t-b} & 0 \\ 0 & 0 & A & B \\ 0 & 0 & -1 & 0\end{array}\right)\left(\begin{array}{c}x_e \\ y_e \\ z_e \\ w_e\end{array}\right) xcyczcwc = rl2n0000tb2n00rlr+ltbt+bA100B0 xeyezewe ,
其中的 Z 项 单目提出来应该等于下面的式子:
z n = z c / w c = A z e + B w e − z c z_n=z_c / w_c=\frac{A z_e+B w_e}{-z_c} zn=zc/wc=zcAze+Bwe
最后根据: Z_near 平面 和 Z_far 平面不会移动的原因,得到最后的 投影矩阵:
M p r o j = ( 2 n r − l 0 r + l r − l 0 0 2 n t − b t + b t − b 0 0 0 − ( f + n ) f − n − 2 f n f − n 0 0 − 1 0 ) M_{proj}=\left(\begin{array}{cccc}\frac{2 n}{r-l} & 0 & \frac{r+l}{r-l} & 0 \\ 0 & \frac{2 n}{t-b} & \frac{t+b}{t-b} & 0 \\ 0 & 0 & \frac{-(f+n)}{f-n} & \frac{-2 f n}{f-n} \\ 0 & 0 & -1 & 0\end{array}\right) Mproj= rl2n0000tb2n00rlr+ltbt+bfn(f+n)100fn2fn0

Code:

3DGS 设定:

self.zfar = 100.0
self.znear = 0.01

下面这个 Projection_Matrix 的构建 和上面公式推导会有一点不一样的地方,尤其是对于 Z值的计算上,Github 上也有人提出过疑问。 矩阵的P[2,2] 有误, 但是作者又说 他在 Code 中没有 使用 Z的数值。

https://github.com/graphdeco-inria/gaussian-splatting/issues/388
https://github.com/graphdeco-inria/gaussian-splatting/issues/376

def getProjectionMatrix(znear, zfar, fovX, fovY):tanHalfFovY = math.tan((fovY / 2)) ## 视场角一半的正切数值tanHalfFovX = math.tan((fovX / 2))## 得到 l,b,top,righttop = tanHalfFovY * znearbottom = -topright = tanHalfFovX * znearleft = -rightP = torch.zeros(4, 4)z_sign = 1.0P[0, 0] = 2.0 * znear / (right - left)P[1, 1] = 2.0 * znear / (top - bottom)P[0, 2] = (right + left) / (right - left)P[1, 2] = (top + bottom) / (top - bottom)P[3, 2] = z_signP[2, 2] = z_sign * zfar / (zfar - znear)P[2, 3] = -(zfar * znear) / (zfar - znear)return P
带有Cx, Cy的相机模型:

https://github.com/graphdeco-inria/gaussian-splatting/issues/144

def getProjectionMatrixShift(znear, zfar, focal_x, focal_y, cx, cy, width, height, fovX, fovY):tanHalfFovY = math.tan((fovY / 2))tanHalfFovX = math.tan((fovX / 2))# the origin at center of image planetop = tanHalfFovY * znearbottom = -topright = tanHalfFovX * znearleft = -right# shift the frame window due to the non-zero principle point offsetsoffset_x = cx - (width/2)offset_x = (offset_x/focal_x)*znearoffset_y = cy - (height/2)offset_y = (offset_y/focal_y)*zneartop = top + offset_yleft = left + offset_xright = right + offset_xbottom = bottom + offset_yP = torch.zeros(4, 4)z_sign = 1.0P[0, 0] = 2.0 * znear / (right - left)P[1, 1] = 2.0 * znear / (top - bottom)P[0, 2] = (right + left) / (right - left)P[1, 2] = (top + bottom) / (top - bottom)P[3, 2] = z_signP[2, 2] = z_sign * zfar / (zfar - znear)P[2, 3] = -(zfar * znear) / (zfar - znear)return P

或者其他人 也给了 Projection 基于 相机内参的写法:

https://github.com/graphdeco-inria/gaussian-splatting/issues/399

P[0, 0] = 2 * fx / W
P[1, 1] = 2 * fy / H
P[0, 2] = 2 * (cx / W) - 0.5
P[1, 2] = 2 * (cy / H) - 0.5
P[2, 2] = -(zfar + znear) / (zfar - znear)
P[3, 2] = 1.0
P[2, 3] = -(2 * zfar * znear) / (zfar - znear)

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

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

相关文章

docker安装【zookeeper】【kafka】【provectuslabs/kafka-ui】记录

目录 1.安装zookeeper:3.9.2-jre-172.安装kafka:3.7.03.安装provectuslabs/kafka-ui (选做)新环境没有jdk,安装jdk-17.0.10备用 mkdir -p /export/{data,apps,logs,conf,downloads}cd /export/downloadscurl -OLk https://download.oracle.…

Docker搭建Maven仓库Nexus

文章目录 一、简介二、Docker部署三、仓库配置四、用户使用Maven五、管理Docker镜像 一、简介 Nexus Repository Manager(简称Nexus)是一个强大的仓库管理器。 Nexus3支持maven、docker、npm、yum、apt等多种仓库的管理。 建立了 Maven 私服后&#xf…

中国发布首个汽车大模型标准

🦉 AI新闻 🚀 中国发布首个汽车大模型标准 摘要:中国信息通信研究院于4月28日发布了国内首个汽车大模型标准,标志着汽车行业正式迈向“人工智能+”时代。该标准包含三个核心能力域:场景丰富度、能力支持度…

Unity 异常 bug

OverlapBoxNonAlloc 使用bug 环境: Unity2021.3.15 在测试场景中使用 OverlapBoxNonAlloc 测试检测没有问题 但是到了真实应用场景,使用 OverlapBoxNonAlloc 检测移动中的小怪 小怪碰撞体为:带有 Rigidbody 的Circle Collider 2D 就会出现异…

了解JRE扩展

一、Java 运行环境的扩展 Java 运行环境提供的类库只是核心类,不可能满足用户的全部需求 将类打包为 jar 包,放入扩展 \jre\lib\ext 中,程序就可以使用 import 语句使用扩展中的类 二、字节码文件压缩成 jar 文件 编译源文件 --> 编写…

船用组装式中央空调案例

船用组装式空调的整体介绍 1.1 装置的主要技术数据及配套设备规格 该轮采用的是船用组装式空调装置。 1.1.1 空调装置 1)型号:CJKR-116船用组装式空调装置;2)制冷型式:直接蒸发式;3)制冷量&…

区间预测 | PSO-RF-KDE的粒子群优化随机森林结合核密度估计多变量回归区间预测(Matlab)

区间预测 | PSO-RF-KDE的粒子群优化随机森林结合核密度估计多变量回归区间预测(Matlab) 目录 区间预测 | PSO-RF-KDE的粒子群优化随机森林结合核密度估计多变量回归区间预测(Matlab)效果一览基本介绍程序设计参考资料 效果一览 基…

MemFire案例-政务应急物联网实时监测预警项目

客户背景 党的十八大以来,中央多次就应急管理工作做出重要指示:要求坚持以防为主、防抗救相结合,全面提升综合防灾能力;坚持生命至上、安全第一,完善安全生产责任制,坚决遏制重特大安全事故。 面对新形势…

【1429】招生管理管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 招生管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&…

#8松桑前端后花园周刊-谷歌推迟cookie弃用、JS Naked Day、Node22、pnpm9.0、Hexo、JSR、html-to-image

⚡️行业动态 谷歌再次推迟了 Chrome 中第三方 cookie 弃用计划 在 Chrome 上逐步淘汰第三方 cookie 计划的最新进展:延迟到2025年年初开始进行第三方 cookie 弃用。 JS Naked Day 4月24号被社区开发者定为 JS Naked Day,完全没有 JavaScript 的一天&…

在VSCode中调试其他软件执行的python文件

在VSCode中调试其他软件执行的python文件 0. 实际场景 我有一段python代码想在Metashape中运行,但是又想在中间某一步停下来查看变量值。由于Metashape的python环境不容易在vscode中配置,所以直接用vscode调试单个文件的方式无法实现这个想法。还好&am…

[NeurIPS-23] GOHA: Generalizable One-shot 3D Neural Head Avatar

[pdf | proj | code] 本文提出一种基于单图的可驱动虚拟人像重建框架。基于3DMM给粗重建、驱动结果,基于神经辐射场给细粒度平滑结果。 方法 给定源图片I_s和目标图片I_t,希望生成图片I_o具有源图片ID和目标图片表情位姿。本文提出三个分支:…

如何让用户听话?

​福格教授(斯坦福大学行为设计实验室创始人)通过深入研究人类行为20年,2007年用自己的名子命名,提出了一个行为模型:福格行为模型。 模型表明:人的行为发生,要有做出行为的动机和完成行为的能…

第七天 dfs剪枝优化

第七天 dfs剪枝&优化 1可行性剪枝 2最优性剪枝 3重复性剪枝 题 1 输入 5 5 6 …S. XX.X. …X… …D.X …X… 输出 YES —————————————— 题解 #include<iostream> #include<cstdio> using namespace std; const int N 10; int n,m,T; char …

GDPU 算法分析与设计 天码行空5

一、【实验目的】 &#xff08;1&#xff09;熟悉动态规划算法的基本思想. &#xff08;2&#xff09;理解动态规划算法中子问题的划分和递推方程设计的基本方法. &#xff08;3&#xff09;熟悉矩阵链乘法的基本思想并编程实现。 二、【实验内容】 输入:矩阵链Ai…j的输入为…

HCIP-Datacom-ARST必选题库_网络协议【道题】

一、单选 1.能够生成组播分发树的组播协议是: OSPF PIMv2 BGP IGMPv2 二、多选 1.以以下哪些属于多通道协议? Te1net P FTP H.323 SMTP LE 2.以下哪些协议属于多通道协议? SMTP Telnet H.323 FTP 三、简答 1.请将以下组网可靠性的备份技术与其相应特性进…

计算机系列之进程调度、死锁、存储管理、设备管理、文件管理

11、进程调度-死锁-存储管理-固定分页分段 1、进程调度 进程调度方式是指当有更高优先级的进程到来时如何分配CPU。分为可剥夺和不可剥夺两种&#xff0c;可剥夺指当有更高优先级进程到来时&#xff0c;强行将正在运行进程的CPU分配给高优先级进程&#xff1b;不可剥夺是指高…

【Burpsuite靶场】XSS专题精讲

【个人】&#xff1a;NEUQ大一学生 【专业】&#xff1a;通信工程 (Communication Engineering) 【个人方向】&#xff1a;网安、开发双管齐下 【座右铭】&#xff1a;真正的英雄主义,就是看清生活的真相后依然热爱生活 -- 罗曼.罗兰 一、认识XSS&#xff08;跨站脚本攻击&…

flutter笔记-webrtc使用1:依赖本地包socket.io-client

文章目录 1. 示例工程2. yaml 修改3. 使用4. socketio 关于自定义服务器自定义签名的问题封装成async和await方式 本文开始介绍webrtc的使用&#xff0c;阅读本文的前提是假设你已经使用过webrtc&#xff0c;了解webrtc的交互机制&#xff0c;不了解的可以看之前的文章&#xf…

Java设计模式 _结构型模式_过滤器模式

一、过滤器模式 1、过滤器模式 过滤器模式&#xff08;Filter Pattern&#xff09;是这一种结构型设计模式。过滤器&#xff0c;顾名思义&#xff0c;就是对一组数据进行过滤&#xff0c;从而最终获取到我们预期的数据。 2、实现思路 &#xff08;1&#xff09;、定义过滤器的…