相机标定(二)—— 投影变换相关基础概述

本节主要介绍MVP(Model-View-Projection-模型视图投影)相关概念,来说明三维空间中的物体是如何映射到二维屏幕上的。其中包括:

  • View/Camera Transformation(视图/相机变换)
  • Projection Transformation(投影变换)
    • Orthographics Projection(正交投影)
    • Perspective Projection(透视投影)
  • ViewPort Transformation(视口变换)

1. View/Camera Transformation(视图/相机变换)

1.1 什么是视图变换?

视图变换顾名思义就是把你所看到的图做一个变换。我们可以用照相机的原理来阐释3D图形的绘制过程,想象一下,我们在摄影的时候都需要做哪些工作,大致可分为如下几个步骤:

  1. 摆放好待拍摄的物品,或者人物。
  2. 调整好拍摄角度。
  3. 调整焦距。
  4. 拍摄。

上面的第一步叫做Model Transformation(模型变换),将一个模型置于一个公认的坐标系中,这里所谓的公认,也就是大家都遵守的,目的是保证待拍摄的物体和照相机在同一个坐标系。第二步叫做View Transformation(视图变换),这个过程是调整Camera到合适的位置以便拍摄,在3D程序中,也就是设置View Matrix的过程。第三步和第四步就是Projection Transformation(投影变换)。
View Transformation(视图变换)的过程就是在世界坐标系中摆放Camera的过程,并将顶点由世界坐标系转换到Camera Space, 在Camera Space中,观察者(Camera)位于坐标原点,观察方向指向Z轴正方向。

1.2 为什么要进行视图变换?

在World Space中,Camera并不一定位于坐标原点,并且观察方向不一定指向 z z z轴正方向,对于投影变换及其他的一些操作来说,如果不满足这两个条件,后续的的操作就会变得非常低效,所以为了提高效率,我们需要进行视图变换。

1.3 视图变换有什么作用?

View Transform主要有下面两个作用:

  • 移动camera,使其位于world space的坐标原点
  • 旋转camera,使其朝向 z z z轴正方向,也就是视线由原点指向 z z z轴正方向。
    这两个过程,前一个实际上是平移,后一个实际上是旋转。你可以想象成Camera也有三个坐标轴 x , y , z x,y,z x,y,z,视图变换的过程就是将Camera的坐标轴与世界坐标系的坐标轴对齐的过程。
    注意:视图变换中,所有位于world space中的models都随着camera一起变换,所以视野并未发生变化,具体过程见下图:
    相机标定(二)—— 投影变换相关基础概述_第1张图片

1.4 怎样做视图变换?

了解了什么是视图变换,接下来就是怎么去做视图变换。做视图变换的前提是场景中得有一台摄像机,然后简单的给出几个物体。首先我们需要定义摄像机看向的方向为 g g g(向量),然后取摄像机的向上方向为 t t t(向量),再定义摄像机的位置position。
相机标定(二)—— 投影变换相关基础概述_第2张图片
此时一个简单的场景就搭好了,现在我们需要做视图变换,一般在图形学中摄像机永远是看向 − z -z z方向,摄像机上边在 y y y方向,所以需要将图示的摄像机变换到标准位置,但是这会出现一个问题,摄像机的位置一变,我们之前定义的 g g g t t t向量都会变换,这不是我们想看到的。
根据相对运动可知,如果所有物体和摄像机的位置一起改变一样的位置,那么摄像机看的画面就不会变。(比如你在中国的摄影棚拍照和在美国的摄影棚拍照,如果摄影棚的装饰完全一样,你所拍到的画面是没有区别的)
相机标定(二)—— 投影变换相关基础概述_第3张图片

所以接下来就是写出视图变换矩阵了,但是此时我们又陷入了麻烦,将一个任意位置,任意方向的相机和物体,变换到标准位置(看向 − z -z z轴,顶部在 y y y轴)是很困难去写这样的视图变换矩阵的。

常规做法:

  • 先平移到原点
  • 再将 g g g旋转到 − z -z z
  • 再将 t t t旋转到 y y y
  • 再将 g × t g\times t g×t旋转到 x x x
    上述常规做法的变换矩阵是非常难写的,所以可用线性代数中的逆这一知识点简化写法。

简化做法:

  • 平移到原点
  • 由任意位置转换到标准位置改成由标准位置转化为任意位置
  • 将求出的矩阵求逆矩阵
    这样就简化了视图变换矩阵的求法,因为由任意位置转换到标准位置的矩阵是非常容易写的。

平移矩阵
T v i e w = [ 1 0 0 − x e 0 1 0 − y e 0 0 1 − z e 0 0 0 1 ] T_{view} = \left[ \begin{matrix} 1 & 0 & 0 & -x_e\\ 0 & 1 & 0 & -y_e\\ 0 & 0 & 1 & -z_e\\ 0 & 0 & 0 & 1 \end{matrix} \right] Tview=100001000010xeyeze1

旋转矩阵
[ x g ^ × t ^ x t x − g 0 y g ^ × t ^ y t y − g 0 z g ^ × t ^ z t z − g 0 0 0 0 1 ] \left[ \begin{matrix} x_{\hat{g}\times\hat{t}} & x_t & x_{-g} & 0\\ y_{\hat{g}\times\hat{t}} & y_t & y_{-g} & 0\\ z_{\hat{g}\times\hat{t}} & z_t & z_{-g} & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right] xg^×t^yg^×t^zg^×t^0xtytzt0xgygzg00001

然后求该矩阵的逆
R v i e w = [ x g ^ × t ^ y g ^ × t ^ z g ^ × t ^ 0 x t y t z t 0 x − g y − g z − g 0 0 0 0 1 ] R_{view} = \left[ \begin{matrix} x_{\hat{g}\times\hat{t}} & y_{\hat{g}\times\hat{t}} & z_{\hat{g}\times\hat{t}} & 0\\ x_t & y_t & z_t & 0\\ x_{-g} & y_{-g} & z_{-g} & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right] Rview=xg^×t^xtxg0yg^×t^ytyg0zg^×t^ztzg00001

因为旋转矩阵是正交矩阵,所以求矩阵的逆就相当于求该矩阵的转置。
所以求得变换矩阵为
M v i e w = R v i e w T v i e w M_{view} = R_{view}T_{view} Mview=RviewTview

2. Projection Transformation(投影变换)

投影变换(projection transformation)分为正交投影变换(Orthographics projection)和透视投影变换(Persperctive projection),这两种投影的功能都是将三维空间的物体映射到二维空间;仿射变换(affine transformation)是透视变换的子集,透视变换是通过homography单应矩阵实现的。
相机标定(二)—— 投影变换相关基础概述_第4张图片
相机标定(二)—— 投影变换相关基础概述_第5张图片

2.1 Orthographics Projection(正交投影)

2.1.1 什么是正交投影?

正交投影就是摄像机在原点,看向 − z -z z方向,顶部在 y y y方向,在看向物体时将所有物体的 z z z值归0,然后将物体平移并缩放到 [ − 1 , 1 ] 2 [-1,1]^2 [1,1]2之间。

2.1.2 怎么做正交投影?

正交投影的做法就是把物体移到原点处的 [ − 1 , 1 ] 3 [-1, 1]^3 [1,1]3的标准立方体中。
相机标定(二)—— 投影变换相关基础概述_第6张图片

步骤分为两步:
① 先将物体中心平移到原点。
②再进行缩放,缩放到 [ − 1 , 1 ] 3 [-1,1]^3 [1,1]3的标准立方体中。
这两个变换矩阵很好写出

解释1:平移矩阵中的这三个平移量得出的原因是因为要将中心平移到原点,所以要取每个轴的中心坐标,平移量为负的原因是将任意一个点平移到原点都是负的平移量。
解释2:缩放矩阵中的这三个缩放量得出的原因是用的 [ − 1 , 1 ] [-1,1] [1,1]的标准长度除以物体的每个轴所对应的长度,得到的缩放量。

2.2 Perspective Projection(透视投影)

2.2.1 什么是透视投影?

简而言之,透视投影就是近大远小,平行线也会变得不平行,人们眼睛所看到的就是透视投影的结果。

2.2.2 怎么做透视投影?

常规法:硬性求解。此方法在各类图形学书中均有求解,在此暂不讨论。
由透视变换到正交解法:这种方法相对于复杂的常规解法要容易得多,下面我就说说具体的思路。
首先把透视投影“挤”成正交投影
相机标定(二)—— 投影变换相关基础概述_第7张图片

然后再做正交投影
由于正交投影我们在上方已经解出,所以现在要做的就是如何写出“挤”这一步的变换矩阵。
首先观察下图
相机标定(二)—— 投影变换相关基础概述_第8张图片
我们从截面观察各点的变化情况,由于远平面f要“挤”到和近平面一样大,所以可推导出图中远平面上的红点的 y y y值会向下移动到 y ′ y^\prime y这么高,所以由相似原理可写出
y ′ n = y z \frac{y^\prime}{n} = \frac{y}{z} ny=zy
y ′ = n z y y^\prime = \frac{n}{z}y y=zny
同理求得 x x x的变化
x ′ = n z x ( s i m i l a r   t o   y ′ ) x^\prime = \frac{n}{z}x(similar \ to \ y^\prime) x=znx(similar to y)
在齐次坐标中可以将原来远平面上的 ( x , y , z , 1 ) (x,y,z,1) (x,y,z,1)的点写为:
( x y z 1 ) ⟹ ( n x / z n y / z u n k o w n 1 ) = = ( n x n y s t i l l   u n k o w n z ) \left( \begin{matrix} x\\ y\\ z\\ 1 \end{matrix} \right) \Longrightarrow \left( \begin{matrix} nx/z\\ ny/z\\ unkown\\ 1 \end{matrix} \right)== \left( \begin{matrix} nx\\ ny\\ still \ unkown\\ z \end{matrix} \right) xyz1nx/zny/zunkown1==nxnystill unkownz
为什么乘以 z z z值之后得到的结果还相同?
因为在齐次坐标中,各个维度乘以相同的值得到点和原来一样。
此时可写出以下式子
M p e r s p → o r t h o ( 4 × 4 ) ( x y z 1 ) = ( n x n y u n k o w n z ) M_{persp\rightarrow ortho}^{(4\times4)} \left( \begin{matrix} x\\ y\\ z\\ 1 \end{matrix} \right)= \left( \begin{matrix} nx\\ ny\\ unkown\\ z \end{matrix} \right) Mpersportho(4×4)xyz1=nxnyunkownz
由于已经知道了三行的值,所以可以逆推出透视变正交矩阵的三行的值
M p e r s p → o r t h o = ( n 0 0 0 0 n 0 0 ? ? ? ? 0 0 1 0 ) M_{persp\rightarrow ortho} = \left( \begin{matrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ ? & ? & ? & ?\\ 0 & 0 & 1 & 0 \end{matrix} \right) Mpersportho=n0?00n?000?100?0
这是简单的线性代数矩阵和矩阵相乘的结果。
现在问题就简化为了如何求解矩阵第三行的值。
由于任何在近平面上的点是不会变的。
任何在远平面的点的 z z z值也不会变。
由以上两条结论可推导出
n n n:近平面
( x y n 1 ) ⟹ ( x y n 1 ) = = ( n x n y n 2 n ) \left( \begin{matrix} x\\ y\\ n\\ 1 \end{matrix} \right) \Longrightarrow \left( \begin{matrix} x\\ y\\ n\\ 1 \end{matrix} \right)== \left( \begin{matrix} nx\\ ny\\ n^2\\ n \end{matrix} \right) xyn1xyn1==nxnyn2n
由于其他三行的值都已知,所以现在只用算第三行的值。又因为由近平面得出的第三行为 n 2 n^2 n2,所以可确定透视变正交矩阵第三行的前两维为0,所以可得:
( 0 0 A B ) ( x y n 1 ) = n 2 \left( \begin{matrix} 0 & 0 & A & B \end{matrix} \right) \left( \begin{matrix} x\\ y\\ n\\ 1 \end{matrix} \right)=n^2 (00AB)xyn1=n2
应用矩阵乘法,对应位置相乘,得:
A n + B = n 2 An + B = n^2 An+B=n2
再由第二条已知条件,所有在远平面的点的 z z z值不变,可得( f f f为远平面):
( 0 0 f 1 ) ⟹ ( 0 0 f 1 ) = = ( 0 0 f 2 f ) \left( \begin{matrix} 0\\ 0\\ f\\ 1 \end{matrix} \right) \Longrightarrow \left( \begin{matrix} 0\\ 0\\ f\\ 1 \end{matrix} \right) == \left( \begin{matrix} 0\\ 0\\ f^2\\ f \end{matrix} \right) 00f100f1==00f2f

再和透视变正交矩阵的第三行相乘,得:
A f + B = f 2 Af + B = f^2 Af+B=f2
两个方程,两个未知量,可求得 A A A B B B的值
A n + B = n 2 A f + B = f 2 ⟹ A = n + f B = − n f \begin{matrix} An +B = n^2\\ Af + B = f^2 \end{matrix} \quad \Longrightarrow \quad \begin{matrix} A = n+f\\ B = -nf \end{matrix} An+B=n2Af+B=f2A=n+fB=nf

终于,所有求解工作完成,得到透视变正交矩阵
M p e r s p → o r t h o = ( n 0 0 0 0 n 0 0 0 0 n + f − n f 0 0 1 0 ) M_{persp\rightarrow ortho} = \left( \begin{matrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & n+f & -nf\\ 0 & 0 & 1 & 0 \end{matrix} \right) Mpersportho=n0000n0000n+f100nf0
所以透视投影矩阵就等于正交投影矩阵乘以透视变正交矩阵
M p e r s p = M o r t h o M p e r s p → o r t h o M_{persp} = M_{ortho}M_{persp\rightarrow ortho} Mpersp=MorthoMpersportho

3. ViewPort Transformation(视口变换)

3.1 什么是视口变换

在我们做完投影变换后所有物体都映射在标准坐标系中,但是屏幕会有各种各样的分辨率,所以视口变换是为了将正常设备坐标映射到屏幕坐标。

3.2 怎么做视口变换

假设屏幕的宽为 w i d t h width width,高度为 h e i g h t height height,那么视口变换就是把 [ − 1 , 1 ] 2 [-1,1]^2 [1,1]2 x y xy xy平面变到 [ 0 , w i d t h ] × [ 0 , h e i g h t ] [0,width]\times[0,height] [0,width]×[0,height],这里为什么没有考虑 z z z轴的变换是因为 z z z轴在之后的其他地方有用。
根据上述可得出视口变换矩阵为:
M v i e w p o r t = ( w i d t h 2 0 0 w i d t h 2 0 h e i g h t 2 0 h e i g h t 2 0 0 1 0 0 0 0 1 ) M_{viewport} = \left( \begin{matrix} \frac{width}{2} & 0 & 0 & \frac{width}{2}\\ 0 & \frac{height}{2} & 0 & \frac{height}{2}\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right) Mviewport=2width00002height0000102width2height01

你可能感兴趣的:(几何学,3d)