坐标变换及视图变换和透视变换(相机透视模型)

文章目录

      • 2D transformation
        • Scale
        • Reflection
        • Shear(切变)
        • Rotation around origin
        • Translation
        • Reverse
        • 变换顺序
        • 复杂变换的分解
      • 齐次坐标(Homogenous Coordinates)
      • 3D transformation
        • Scale&Translation
        • Rotation
      • Viewing / Camera transformation
      • Projection transformation
      • 视口变换
      • 相机内参和相机外参
      • 参考链接

2D transformation

Scale
  • Uniform

image-20240610131838782

  • Non-Uniform

image-20240610131903605

Reflection

image-20240610132151747

Shear(切变)

image-20240610132849601

Rotation around origin

假设旋转矩阵的4个未知数,取特殊点列方程可推导

image-20240610133654334

如果旋转 − θ -\theta θ角度,那么经过推导很容易得出旋转矩阵为原来旋转 θ \theta θ角度的矩阵的转置

image-20240612162331025

又考虑到实际上如果一个图形旋转 θ \theta θ角度再旋转 − θ -\theta θ角度会变回原来的形状,也就是 R − θ R θ X = E X R_{-\theta}R_\theta X=EX RθRθX=EX,即 R − θ R θ = E R_{-\theta}R_\theta=E RθRθ=E​两个矩阵是互逆的。

image-20240612162716886

补充:如果一个矩阵的逆等于它的转置,那么这个矩阵是正交矩阵

以上变换都属于线性变换,都可以写成矩阵相乘的形式:

image-20240610133923619

Translation

需要注意平移(Translation)变换不属于Linear Transformation:

image-20240610134631675

但以上变换可以统称为仿射变换(Affine Transformations)

image-20240610135400637

Reverse

做逆变换相当于把变换后的图形又变回去,假如对 X X X做了变换 M M M,变为 X ′ = M X X'=MX X=MX,再对 X ′ X' X做逆变换 M − 1 M^{-1} M1 M − 1 M X = X M^{-1}MX=X M1MX=X,即变回 X X X

image-20240610141644378

变换顺序

由于矩阵乘法是不可交换的,所以变换的顺序是很重要的,不同的变换顺序得到的结果也不一样,顺序是先线性变换后平移

image-20240610142339298

复杂变换的分解

image-20240610143021276

齐次坐标(Homogenous Coordinates)

将一个 n n n维空间中的点或向量,表示为 n + 1 n+1 n+1维空间中的向量,能够达到合并矩阵运算中乘法和加法操作的目的,简化计算

image-20240610140106905

这样可以定义至少3种有效操作:

image-20240610140352028

Point+Point由于没有什么实质性意义,所以给出一个定义, ( x y w ) \begin{pmatrix}x \\ y \\ w\end{pmatrix} xyw 这个点实际上定义为 ( x / w y / w 1 ) \begin{pmatrix}x/w \\ y/w \\ 1\end{pmatrix} x/wy/w1 这个点,那么这时,两个点相加就被赋予了两个点中点这一意义

那么通过使用齐次坐标,可以将仿射变换改写为:

image-20240610140944932

缩放、旋转、平移可以表示成:

image-20240610141034088

3D transformation

和2D变换中的相似,齐次坐标在3维空间中变成了4维,仿射变换矩阵如下:

image-20240612163848238

注意是先应用线性变换,再应用平移变换!

Scale&Translation

image-20240612164016369

Rotation

三维空间中的旋转和2维相似,绕某个轴旋转就固定哪个轴的坐标不变,其他两个轴应用2维旋转矩阵即可,但我们发现绕y轴旋转的矩阵中 sin ⁡ α \sin α sinα的符号有点不同,这是因为图中y的方向是 z × x z×x z×x得到的,如果y轴是向下的,即由 x × z x×z x×z得到,那么 sin ⁡ α \sin α sinα会刚好相反

image-20240612164412560

留下几个知识点:欧拉角四元数罗德里格兹旋转公式

旋转矩阵不适合做插值,而四元数是可以的

image-20240612172907881

Viewing / Camera transformation

考虑我们现实场景重拍摄一张图片的步骤:

  • 找一个好地方并摆出姿势(model transformation)
  • 找一个好的拍摄角度并放置相机(view transformation)
  • 在相机上投影出相片(projection transformation)

这三部就是图形学中的MVP变换

我们首先考虑视角变换,也即相机变换。通常,相机可以通过三个方向向量来确定一个唯一的视图/相机位置(可以注意到 g ^ \hat g g^ t ^ \hat t t^总是垂直的):

  • Position e ⃗ \vec e e (决定相机的物理位置)
  • Gaze direction g ^ \hat g g^ (决定俯视仰视平视方向)
  • Up direction t ^ \hat t t^ (相机的角度,决定拍出的图像是什么角度,相机旋转,则拍出的照片也会旋转)

由于如果我们保持相机和物体的相对位置不变,同时移动二者,可能会得到相同的拍摄图像,因此不妨将相机固定到一个位置,即:

  • 原点
  • up at Y Y Y
  • gaze at − Z -Z Z

对于这样的位置,可以采取如下仿射变换

  • e e e平移到原点
  • g g g旋转到 − Z -Z Z
  • t t t旋转到 Y Y Y
  • ( g × t ) (g×t) (g×t)旋转到 X X X

这个变换实际上也就是世界坐标系转换到相机坐标系的过程。

但实际上,上面这些变换是不好表示的,由于前面提到旋转矩阵是正交的,所以我们可以考虑上述旋转变换的逆变换

image-20240612193435943

这样我们对所有的物体都事先运用这种变换就相当于我们的相机在一个固定位置去拍摄,并且相机位置是原点。这种变换也被称为ModelView Transformation。这实际上是世界坐标系相机坐标系的一个变换。

Projection transformation

投影变换就是从3D物体投影到2D图像的变换,可以分为:

  • 正交投影(Orthographic Projection)
  • 透视投影(Perspective Projection)

二者本质的区别是是否具有近大远小的性质,透视投影具有近大远小的性质而正交投影没有。透视投影中,原本平行的线投影后可能不再平行。如下图所示,正交投影相当于把相机拉到无限远的位置。下图中,Near clip plane是近平面,也相当于相机的成像平面。

image-20250223190053089

正交投影

当按照前面的方式进行视图变换后,正交投影其实就相当于丢弃掉Z轴坐标,然后将物体的中心平移到相机位置,并且将物体缩放到一个小的矩型中(归一化)。如下图,但这里还有一个问题是物体的正反我们无法分辨。

image-20250223191731040

在实际操作中,我们通常是将一个长方体通过平移和缩放映射一个中心位于原点,边长为1的一个立方体中:

image-20250223192051848

变换矩阵就是(先平移后缩放):

image-20250223192537273

在这个过程中,实际上物体是被拉伸了,后面会提到在做完MVP变换后还要进行视口变换

透视投影

首先需要明确齐次坐标中的一个知识点:就是 ( x , y , z , 1 ) (x,y,z,1) (x,y,z,1) ( k x , k y , k z , k ) (kx,ky,kz,k) (kx,ky,kz,k)表示的是同一个点。

透视投影实际上可以拆分为两步:

  • 将远平面到近平面内的frustum(截锥体)挤压变换成一个长方体。变换需要满足:近平面的所有点坐标不变。远平面只有xy变换而z不变。该变换表示为 M p e r s o − > o r t h o M_{perso->ortho} Mperso>ortho。注意近平面和远平面的中心连线是和z轴平行的。相机位置在中心连线上。
  • 对长方体进行正交投影。

image-20250223195710817

实际上,远平面(右)要挤压成与近平面(左)一样的大小,实际上是一个相似变换。

image-20250223200429050

利用相似变换的性质,可以求出 ( x , y , z ) (x,y,z) (x,y,z) ( x ′ , y ′ , z ′ ) (x',y',z') (x,y,z)的变换。
y ′ = n z y x ′ = n z x y^{\prime}=\frac{n}{z} y \quad x^{\prime}=\frac{n}{z} x y=znyx=znx
对于截锥体内的所有平面,xy变换都满足上述关系,但z的关系目前还不知道,只知道远平面和近平面的z不变。表示成齐次坐标为:

image-20250223200933762

M p e r s o − > o r t h o M_{perso->ortho} Mperso>ortho的目标就是:

image-20250223201044878

至此我们可以推导出 M p e r s o − > o r t h o M_{perso->ortho} Mperso>ortho矩阵的一部分:

image-20250223201130878

至于第三行,我们利用近平面的任意一点和远平面的任意一点z都不会改变可以推导出第三行,最终的 M p e r s o − > o r t h o M_{perso->ortho} Mperso>ortho矩阵就是:
M p e r s o − > o r t h o = ( n 0 0 0 0 n 0 0 0 0 n + f − n f 0 0 1 0 ) M_{perso->ortho}=\begin{pmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0 \\ 0 & 0 & n+f & -nf\\ 0 & 0 & 1 & 0 \end{pmatrix} Mperso>ortho= n0000n0000n+f100nf0
n n n是近平面的z值, f f f是远平面的z值。

然后就是用正交变换矩阵再去做一次变换即得到最终的投影变换矩阵。
M persp  = M ortho  M persp  → ortho  M_{\text {persp }}=M_{\text {ortho }} M_{\text {persp } \rightarrow \text { ortho }} Mpersp =Mortho Mpersp  ortho 
这也是相机坐标系图像坐标系的过程。

透视投影中还涉及到两个概念,视锥的长宽比(aspect ratio)垂直可视角度(vertical field-of-view,fovY)。实际含义可以从下图看出:

image-20250224165545646

我们假设前面经过矩型块是对称的,即 l = − r ( x 方向 ) , b = − t ( y 方向 ) l=-r(x 方向),b=-t(y方向) l=r(x方向),b=t(y方向)。那么可以从 t , r t,r t,r推出两个概念的表达式:
tan ⁡ f o v Y 2 = t ∣ n ∣ aspect  = r t \begin{aligned} \tan \frac{f o v Y}{2} & =\frac{t}{|n|} \\ \text { aspect } & =\frac{r}{t} \end{aligned} tan2fovY aspect =nt=tr
image-20250224165606254

视口变换

在MVP变换过后,我们的目标就是将前述的小立方块投影到一个图片上,这实际上也是图像坐标系到像素坐标系的变换。

首先我们假设像素坐标系是如下形式:坐标原点在左下角,每个像素是有单位宽度和高度的小颜色块,像素内部每一点颜色都一样,像素坐标系放的是像素的索引。如下图。

image-20250224170145528

设定y轴方向的长度为高度(height),x轴方向的长度是宽度(width),整个屏幕的范围就是上图灰色区域。

视口变换的目标是:

  • 保持相机坐标系的z不变
  • xy平面要从原来小立方体 [ − 1 , 1 ] 2 [-1,1]^2 [1,1]2的范围变换到 [ 0 , w i d t h ] × [ 0 , h e i g h t ] [0,width]\times[0,height] [0,width]×[0,height]的范围

变换矩阵很容易写出,就是缩放+平移操作。视口变换矩阵 M v i e w p o r t M_{viewport} Mviewport
M viewport  = ( width  2 0 0 width  2 0 height  2 0 height  2 0 0 1 0 0 0 0 1 ) M_{\text {viewport }}=\left(\begin{array}{cccc} \frac{\text { width }}{2} & 0 & 0 & \frac{\text { width }}{2} \\ 0 & \frac{\text { height }}{2} & 0 & \frac{\text { height }}{2} \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{array}\right) Mviewport = 2 width 00002 height 0000102 width 2 height 01
经过视口变换后,下一步就是光栅化(Rasterization)的过程。

相机内参和相机外参

外参就是上面从世界坐标系到相机坐标系的变换矩阵,可以简单理解为相机的位置、角度。

内参是上面另外两个变换矩阵的叠加,简单理解就是相机的内部特性,如焦距,畸变系数等。

参考链接

[1] https://www.bilibili.com/video/BV1X7411F744?spm_id_from=333.788.videopod.episodes&vd_source=bac8ddf04ec0b6386d58110f67353bc7&p=4

[2] https://www.bilibili.com/video/BV1r8411f72j/?spm_id_from=333.337.search-card.all.click&vd_source=bac8ddf04ec0b6386d58110f67353bc7

[3] https://zhuanlan.zhihu.com/p/692565077

还有一些不太理解的地方以及一些概念以后再更新。

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

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

相关文章

文字语音相互转换

目录 1.介绍 2.思路 3.安装python包 3.程序: 4.运行结果 1.介绍 当我们使用一些本地部署的语言模型的时候,往往只能进行文字对话,这一片博客教大家如何实现语音转文字和文字转语音,之后接入ollama的模型就能进行语音对话了。…

Unity Shader 学习13:屏幕后处理 - 使用高斯模糊的Bloom辉光效果

目录 一、基本的后处理流程 - 以将画面转化为灰度图为例 1. C#调用shader 2. Shader实现效果 二、Bloom辉光效果 1. 主要变量 2. Shader效果 (1)提取较亮区域 - pass1 (2)高斯模糊 - pass2&3 (3&#xff…

PING命令TTL解析

在 ping 命令中,TTL(Time to Live,生存时间) 是 IP 数据包的核心字段之一,用于控制数据包在网络中的生命周期。以下是针对 TTL 的简明解析: 1. TTL 的核心作用 防循环机制:TTL 是一个计数器&a…

Linux 第三次脚本作业

源码编译安装httpd 2.4,提供系统服务管理脚本并测试(建议两种方法实现) 一、第一种方法 1、把 httpd-2.4.63.tar.gz 这个安装包上传到你的试验机上 2、 安装编译工具 (俺之前已经装好了) 3、解压httpd包 4、解压后的httpd包的文…

(七)趣学设计模式 之 适配器模式!

目录 一、 啥是适配器模式?二、 为什么要用适配器模式?三、 适配器模式的实现方式1. 类适配器模式(继承插座 👨‍👩‍👧‍👦)2. 对象适配器模式(插座转换器 &#x1f50c…

【NLP】注意力机制

目录 一、认识注意力机制 1.1 常见注意力计算规则 1.2 注意力机制的作用 1.3 注意力机制代码实现 二、注意力机制原理 2.1 attention计算过程 2.2 attention的计算逻辑 2.3 有无attention模型对比 2.3.1 无attention机制的模型 2.3.2 有attention机制的模型 三、Se…

Spring Boot 整合 Druid 并开启监控

文章目录 1. 引言2. 添加依赖3. 配置数据源4. 开启监控功能5. 自定义 Druid 配置(可选)6. 访问监控页面7. 注意事项8. 总结 Druid 是一个由阿里巴巴开源的高性能数据库连接池,它不仅提供了高效的连接管理功能,还自带了强大的监控…

红帽7基于kickstart搭建PXE环境

Kickstart 文件是一种配置文件,用于定义 Linux 系统安装过程中的各种参数,如分区、网络配置、软件包选择等。system-config-kickstart 提供了一个图形界面,方便用户快速生成这些配置文件。 用户可以通过图形界面进行系统安装的详细配置&…

C/C++跳动的爱心

系列文章 序号直达链接1C/C李峋同款跳动的爱心2C/C跳动的爱心3C/C经典爱心4C/C满屏飘字5C/C大雪纷飞6C/C炫酷烟花7C/C黑客帝国同款字母雨8C/C樱花树9C/C奥特曼10C/C精美圣诞树11C/C俄罗斯方块小游戏12C/C贪吃蛇小游戏13C/C孤单又灿烂的神14C/C闪烁的爱心15C/C哆啦A梦16C/C简单…

MongoDB 简介

MongoDB 是一种高性能、开源的 NoSQL 数据库,以其灵活的文档模型和强大的扩展性而闻名。 1.MongoDB 是什么 MongoDB 是一种 NoSQL 数据库,采用 文档模型 存储数据,支持灵活的 JSON 格式文档。它无需预定义表结构,能够动态调整数据…

记录首次安装远古时代所需的运行环境成功npm install --save-dev node-sass

最开始的报错: 最后根据报错一步步 安装所需要的pythong之类的环境,最后终于成功了,得以让我在github上拉的vuehr项目(狗头18年还是20年的远古项目)成功本地运行,最后附上本地运行成功的贴图。如果大家也在…

华为guass在dbever和springboot配置操作

下面记录华为guass在dbever和springboot配置操作,以备忘。 1、安装dbeaver-ce-23.2.0-x86_64-setup.exe和驱动程序 Download | DBeaver Community 2、配置高斯数据库驱动 3、新建数据库连接 4、操作指引 opengauss官方文档 https://docs-opengauss.osinfra.cn/zh…

今日运维之-Mac笔记本python环境问题

1. 问题:MAC升级系统后git报错? Error: Cant create update lock in /usr/local/var/homebrew/locks! Fix permissions by running:sudo chown -R $(whoami) /usr/local/var/homebrew Traceback (most recent call last):11: from /usr/local/Homebrew/…

c3p0、Druid连接池+工具类 Apache-DbUtils (详解!!!)

数据库连接池是在应用程序启动时创建一定数量的数据库连接,并将这些连接存储在池中。当应用程序需要与数据库通信时,它可以向池中请求一个连接,使用完后将连接归还给池,而不是关闭连接。这样可以减少创建和关闭连接的开销&#xf…

数仓搭建实操(传统数仓oracle):DWD数据明细层

数据处理思路 DWD层, 数据明细层>>数据清洗转换, 区分事实表,维度表 全是事实表,没有维度表>>不做处理 数据清洗>>数据类型varchar 变成varchar2, 日期格式统一(时间类型变成varchar2); 字符数据去空格 知识补充: varchar 存储定长字符类型 ; 存储的数据会…

2.1 第一个程序:从 Hello World 开始

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 同大多数编程语言教程一样,本书第一个代码也是输出:Hello world! 这似乎也是惯例。我们也先从这个简单的代码…

2025年02月21日Github流行趋势

项目名称:source-sdk-2013 项目地址url:https://github.com/ValveSoftware/source-sdk-2013项目语言:C历史star数:7343今日star数:929项目维护者:JoeLudwig, jorgenpt, narendraumate, sortie, alanedwarde…

【WSL2】 Ubuntu20.04 GUI图形化界面 VcXsrv ROS noetic Vscode 配置

【WSL2】 Ubuntu20.04 GUI图形化界面 VcXsrv ROS noetic Vscode 配置 前言整体思路安装 WSL2Windows 环境升级为 WIN11 专业版启用window子系统及虚拟化 安装WSL2通过 Windows 命令提示符安装 WSL安装所需的 Linux 发行版(如 Ubuntu 20.04)查看和设置 WS…

7.建立文件版题库|编写model文件|使用boost split字符串切分(C++)

建立文件版题库 题目的编号题目的标题题目的难度题目的描述,题面时间要求(内部处理)空间要求(内部处理) 两批文件构成第一个:questions.list : 题目列表(不需要题目的内容)第二个:题目的描述,题目的预设置…

LabVIEW中CFURL.llb 工具库说明

CFURL.llb 是 LabVIEW 2019 安装目录下 C:\Program Files (x86)\National Instruments\LabVIEW 2019\vi.lib\Platform\ 路径下的工具库,主要用于处理 LabVIEW 与 URL 相关的操作,涵盖 URL 解析、HTTP 请求发送、数据传输等功能模块,帮助开发者…