CG透视变换推导汇总
- 格式:doc
- 大小:587.00 KB
- 文档页数:14
透视投影的原理和实现透视投影的原理和实现摘要:透视投影是3D渲染的基本概念,也是3D程序设计的基础。
掌握透视投影的原理对于深⼊理解其他3D渲染管线具有重要作⽤。
本⽂详细介绍了透视投影的原理和算法实现,包括透视投影的标准模型、⼀般模型和屏幕坐标变换等,并通过VC实现了⼀个演⽰程序。
1 概述在计算机三维图像中,投影可以看作是⼀种将三维坐标变换为⼆维坐标的⽅法,常⽤到的有正交投影和透视投影。
正交投影多⽤于三维健模,透视投影则由于和⼈的视觉系统相似,多⽤于在⼆维平⾯中对三维世界的呈现。
透视投影(Perspective Projection)是为了获得接近真实三维物体的视觉效果⽽在⼆维的纸或者画布平⾯上绘图或者渲染的⼀种⽅法,也称为透视图[1]。
它具有消失感、距离感、相同⼤⼩的形体呈现出有规律的变化等⼀系列的透视特性,能逼真地反映形体的空间形象。
透视投影通常⽤于动画、视觉仿真以及其它许多具有真实性反映的⽅⾯。
2 透视投影的原理基本的透视投影模型由视点E和视平⾯P两部分构成(要求 E不在平⾯P上)。
视点可以认为是观察者的位置,也是观察三维世界的⾓度。
视平⾯就是渲染三维对象透视图的⼆维平⾯。
如图1所⽰。
对于世界中的任⼀点X,构造⼀条起点为E并经过X点的射线R,R与平⾯P的交点Xp即是X点的透视投影结果。
三维世界的物体可以看作是由点集合 { Xi} 构成的,这样依次构造起点为E,并经过点Xi的射线Ri,这些射线与视平⾯P的交点集合便是三维世界在当前视点的透视图,如图2所⽰。
图1 透视投影的基本模型图2 透视图成像原理基本透视投影模型对视点E的位置和视平⾯P的⼤⼩都没有限制,只要视点不在视平⾯上即可。
P⽆限⼤只适⽤于理论分析,实际情况总是限定P为⼀定⼤⼩的矩形平⾯,透视结果位于P之外的透视结果将被裁减。
可以想象视平⾯为透明的玻璃窗,视点为玻璃窗前的观察者,观察者透过玻璃窗看到的外部世界,便等同于外部世界在玻璃窗上的透视投影(总感觉不是很恰当,但想不出更好的⽐喻了)。
透视和透视投影变换——论图形变换和投影的若干问题之三何援军(上海交通大学计算机科学与工程系,上海,200030)摘要:讨论了透视变换的基本原理:由于与画面成一角度的平行线簇经透视变换后交于灭点,可采用两种不同的方法来获得透视图:一是保持画面铅垂而通过旋转物体使之与画面构成角度达到透视变换效果,得到了3种最佳透视变换矩阵;二是通过倾斜投影画面而达到透视变换效果,给出了通过倾斜画面得到三灭点透视图的齐次透视变换矩阵。
两种方法的灭点都是可预先控制(即可先决定灭点再决定变换矩阵),比较彻底的解决了透视变换的生成理论。
给出了“对一个空间物体,一定存在另一个空间物体,使前者在画面上的透视投影与后者的平行投影是一样的,且保留了深度方向的对应关系”的一个证明。
这个性质可使复杂的透视投影转化成简单的平行投影,使得立体图形的处理大为简化。
关键词:透视变换,齐次变换矩阵,CG中图法分类号:TP391Perspective and its Projection TransformationHe Yuanjun(Department of Computer Science and Engineering,Shanghai Jiaotong University, Shanghai 200030,China)Abstract: Basic principles of perspective transformation are discussed. Based on the fact that parallel-lines in some angle with view plane intersect at vanishing-point, two methods are presented to get perspective view: one is to keep the view plane vertical while rotating objects to some angle, thus to achieve perspective transformation effect, and three best perspective transformation matrixes is presented. The other is to incline projective view to get the effect. Homogenous perspective transformation matrix are present, which can generate 3-vanishing-point drawing through inclining view. Both methods are beforehand controllable (that’s to say vanishing-point is first decided, then comes out the transformation matrix), thus generating theory of perspective transformation is thoroughly solved. Prove that for each 3D object there must be another 3D object, which parallel projection is the same as the former’s perspective projection, and the corresponding depth relation is well preserved. With this useful property, a complicated perspective projection can be converted to a simple parallel projection, so the complication of 3D graphics processing becomes sharply reduced.Keywords: perspective transformation, homogenous transformation matrix, CG1.引言现实生活中的景物,由于观察距离及方位不同在视觉上会引起不同的反映,这种现象就是透视现象。
透视投影变换的推导过程-3D基础知识感觉很多书上都没讲清楚透视投影变换的推导过程,自己推导了下,以前一直含糊的关于方形/非方形的视平面和屏幕的宽高比的问题也有了答案.本文组织如下:1.相机空间到视平面的变换2.视平面到屏幕的变换3.综合4.一般情形1.相机空间到视平面的变换* p (xc,0, zc)/ |/ |/ |X |/ |^ *p |(xp,0,zp)| / | || / | || / | |C(cam) |/ | |--------*----|----*------------->Z0 dx zc(X-Z平面的投影示图)a.透视投影一般的视景体为棱台,相机空间的物体会投影到视平面z=d,这里考虑左手坐标系,矩阵使用行优先方式。
如图所示,由相似三角形知识可知相机空间中的物体投影到视平面上的坐标为:xp = xc*(dx/zc)yp = yc*(dy/zc)其中,xc,yc,zc为相机空间坐标,xp,yp,zp为视平面坐标,dx,dy为x,y轴向的视距view distance,视平面到camera的距离,故相机空间投影到视平面上的矩阵Tcp为:|dx 0 0 0 ||0 dy 0 0 ||0 0 1 1 ||0 0 0 0 |(验证:T cp右乘点p(xc,yc,zc,1)得点p (xc*dx, yc*dy, zc, zc),转换为3D坐标为(xc*dx/zc, yc*dy/zc, 1),正确。
)*************************************************************** *****注:因为转换过程中点使用的是4D齐次坐标,所以最后需转换为3D坐标。
4D齐次坐标(x,y,z,w)转换为3D坐标的方法为除以w分量,即对应3D坐标为(x/w,y/w,z/w)。
*************************************************************** *****考虑dx/zc和dy/zc项,如果dx != dy,则投影后x,y的比例会发生变化(原因:投影前坐标比例为xc/yc,投影后为xp/yp = xc*(dx/zc)/yc*(dy/zc) = xc*dx/yc*dy),从而投影后的图像的x,y比例会发生变形。
成像的过程实质上是几个坐标系的转换。
首先空间中的一点由世界坐标系转换到摄像机坐标系,然后再将其投影到成像平面(图像物理坐标系),最后再将成像平面上的数据转换到图像平面(图像像素坐标系)。
1透视投影公式
1.1世界坐标系转摄像机坐标系
公式如下:
其中,R为旋转矩阵,T为平移矩阵,右侧矩阵是世界坐标系坐标点,左侧是摄像机坐标系坐标点。
R旋转矩阵表示的是摄像机在世界坐标系中绕X,Y,Z旋转的程度,平移矩阵表示的是摄像机在世界坐标系中里世界坐标原点的程度。
R矩阵为3*3的正交矩阵,T为3*1的矩阵。
绕x,y, z轴旋转的矩阵分别如下:
1.2 摄像机坐标系转图像物理坐标系公式如下:
f是焦距
1.3图像物理坐标系转图像像素坐标系
公式如下:
每个像素沿x轴的实际物理尺寸大小是dx,沿y轴的实际物理尺寸大小是dy,单位值毫米。
图像物理坐标系原点在图像像素坐标系中记为(u0,v0)
2.代码
3.逆映射相关
逆映射是将图像像素坐标系坐标点,提供已知的内外参数逆映射到真实世界坐标点。
3.1 像素坐标系到物理坐标系
internalMatrix是相机内参数,取其逆矩阵与像素坐标点相乘,得物理坐标点。
3.2 物理坐标到摄像机坐标
先求得焦距的矩阵,取其逆矩阵与物理坐标点相乘,再乘以缩放因子即可得摄像机坐标点(缩放因子目前不知,暂时全部设为250)3.3 摄像机坐标到真实坐标点
先求得旋转矩阵和平移矩阵,合并两个矩阵之后,取其逆矩阵,让该
逆矩阵与摄像机坐标点相乘,即可得真实世界坐标点。
透视变换公式
透视变换公式是一种数学变换,它可以将一个三维空间中的图像转换为一个二维平面上的图像。
这种变换可以用于计算机视觉和计算机图形学中,它可以用于实现图像纠正、图像增强、图像变形等应用。
在透视变换中,我们需要定义四个点来确定变换的基本形状。
这四个点通常被称为映射点,它们可以确定源图像中的四个角落,并将它们映射到输出图像中的四个角落。
这种映射可以使用矩阵运算来实现,其中矩阵的值根据输入和输出图像的坐标系而定。
透视变换公式常常用于计算机视觉中的摄影测量和三维重建。
在摄影测量中,透视变换可以用于校正图像中的透视畸变,从而更准确地测量物体的尺寸和位置。
在三维重建中,透视变换可以用于将多个视角下的图像组合成一个三维模型。
总之,透视变换公式是一种非常有用的工具,它可以帮助我们将三维的图像转换为更易于处理的二维图像,并在计算机视觉和计算机图形学中发挥重要作用。
透视投影是3D固定流水线的重要组成部分,是将相机空间中的点从视锥体(frustum)变换到规则观察体(Canonical View Volume)中,待裁剪完毕后进行透视除法的行为。
在算法中它是通过透视矩阵乘法和透视除法两步完成的。
透视投影变换是令很多刚刚进入3D图形领域的开发人员感到迷惑乃至神秘的一个图形技术。
其中的理解困难在于步骤繁琐,对一些基础知识过分依赖,一旦对它们中的任何地方感到陌生,立刻导致理解停止不前。
没错,主流的3D APIs如OpenGL、D3D的确把具体的透视投影细节封装起来,比如gluPerspective(…) 就可以根据输入生成一个透视投影矩阵。
而且在大多数情况下不需要了解具体的内幕算法也可以完成任务。
但是你不觉得,如果想要成为一个职业的图形程序员或游戏开发者,就应该真正降伏透视投影这个家伙么?我们先从必需的基础知识着手,一步一步深入下去(这些知识在很多地方可以单独找到,但我从来没有在同一个地方全部找到,但是你现在找到了)。
我们首先介绍两个必须掌握的知识。
有了它们,我们才不至于在理解透视投影变换的过程中迷失方向(这里会使用到向量几何、矩阵的部分知识,如果你对此不是很熟悉,可以参考可以找到一组坐标(v1,v2,v3),使得v = v1 a + v2 b + v3 c (1)而对于一个点p,则可以找到一组坐标(p1,p2,p3),使得p – o = p1 a + p2 b + p3 c (2)从上面对向量和点的表达,我们可以看出为了在坐标系中表示一个点(如p),我们把点的位置看作是对这个基的原点o所进行的一个位移,即一个向量——p – o(有的书中把这样的向量叫做位置向量——起始于坐标原点的特殊向量),我们在表达这个向量的同时用等价的方式表达出了点p:p = o + p1 a + p2 b + p3 c (3)(1)(3)是坐标系下表达一个向量和点的不同表达方式。
这里可以看出,虽然都是用代数分量的形式表达向量和点,但表达一个点比一个向量需要额外的信息。
如果我写出一个代数分量表达(1, 4, 7),谁知道它是个向量还是个点!我们现在把(1)(3)写成矩阵的形式:这里(a,b,c,o)是坐标基矩阵,右边的列向量分别是向量v和点p在基下的坐标。
这样,向量和点在同一个基下就有了不同的表达:3D向量的第4个代数分量是0,而3D 点的第4个代数分量是1。
像这种这种用4个代数分量表示3D几何概念的方式是一种齐次坐标表示。
“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。
”—— F.S. Hill, JR这样,上面的(1, 4, 7)如果写成(1,4,7,0),它就是个向量;如果是(1,4,7,1),它就是个点。
下面是如何在普通坐标 (Ordinary Coordinate)和齐次坐标(Homogeneous Coordinate)之间进行转换:从普通坐标转换成齐次坐标时,如果(x,y,z)是个点,则变为(x,y,z,1);如果(x,y,z)是个向量,则变为 (x,y,z,0)从齐次坐标转换成普通坐标时,如果是(x,y,z,1),则知道它是个点,变成(x,y,z);如果是(x,y,z,0),则知道它是个向量,仍然变成(x,y,z)以上是通过齐次坐标来区分向量和点的方式。
从中可以思考得知,对于平移T、旋转R、缩放S这3个最常见的仿射变换,平移变换只对于点才有意义,因为普通向量没有位置概念,只有大小和方向,这可以通过下面的式子清楚地看出:而旋转和缩放对于向量和点都有意义,你可以用类似上面齐次表示来检测。
从中可以看出,齐次坐标用于仿射变换非常方便。
此外,对于一个普通坐标的点P=(Px, Py, Pz),有对应的一族齐次坐标(wPx, wPy, wPz, w),其中w不等于零。
比如,P(1, 4, 7)的齐次坐标有(1, 4, 7, 1)、(2, 8, 14, 2)、(-0.1, -0.4, -0.7, -0.1)等等。
因此,如果把一个点从普通坐标变成齐次坐标,给x,y,z乘上同一个非零数w,然后增加第4个分量w;如果把一个齐次坐标转换成普通坐标,把前三个坐标同时除以第4个坐标,然后去掉第4个分量。
由于齐次坐标使用了4个分量来表达3D概念,使得平移变换可以使用矩阵进行,从而如F.S. Hill, JR所说,仿射(线性)变换的进行更加方便。
由于图形硬件已经普遍地支持齐次坐标与矩阵乘法,因此更加促进了齐次坐标使用,使得它似乎成为图形学中的一个标准。
简单的线性插值这是在图形学中普遍使用的基本技巧,我们在很多地方都会用到,比如2D位图的放大、缩小,Tweening变换,以及我们即将看到的透视投影变换等等。
基本思想是:给一个x属于[a, b],找到y属于[c, d],使得x与a的距离比上ab长度所得到的比例,等于y与c的距离比上cd长度所得到的比例,用数学表达式描述很容易理解:这样,从a到b的每一个点都与c到d上的唯一一个点对应。
有一个x,就可以求得一个y。
此外,如果x不在[a, b]内,比如x < a或者x > b,则得到的y也是符合y < c或者y > d,比例仍然不变,插值同样适用。
透视投影变换好,有了上面两个理论知识,我们开始分析这次的主角——透视投影变换。
这里我们选择OpenGL的透视投影变换进行分析,其他的 APIs会存在一些差异,但主体思想是相似的,可以类似地推导。
经过相机矩阵的变换,顶点被变换到了相机空间。
这个时候的多边形也许会被视锥体裁剪,但在这个不规则的体中进行裁剪并非那么容易的事情,所以经过图形学前辈们的精心分析,裁剪被安排到规则观察体(Canonical View Volume, CVV)中进行,CVV是一个正方体,x, y, z的范围都是[-1,1],多边形裁剪就是用这个规则体完成的。
所以,事实上是透视投影变换由两步组成:1)用透视变换矩阵把顶点从视锥体中变换到裁剪空间的CVV中。
2)CVV裁剪完成后进行透视除法(一会进行解释)。
我们一步一步来,我们先从一个方向考察投影关系。
上图是右手坐标系中顶点在相机空间中的情形。
设P(x,z)是经过相机变换之后的点,视锥体由eye——眼睛位置,np——近裁剪平面,fp——远裁剪平面组成。
N是眼睛到近裁剪平面的距离,F是眼睛到远裁剪平面的距离。
投影面可以选择任何平行于近裁剪平面的平面,这里我们选择近裁剪平面作为投影平面。
设P’(x’,z’)是投影之后的点,则有z’ = -N。
通过相似三角形性质,我们有关系:同理,有这样,我们便得到了P投影后的点P’从上面可以看出,投影的结果z’始终等于-N,在投影面上。
实际上,z’对于投影后的P’已经没有意义了,这个信息点已经没用了。
但对于3D图形管线来说,为了便于进行后面的片元操作,例如z缓冲消隐算法,有必要把投影之前的z保存下来,方便后面使用。
因此,我们利用这个没用的信息点存储z,处理成:这个形式最大化地使用了3个信息点,达到了最原始的投影变换的目的,但是它太直白了,有一点蛮干的意味,我感觉我们最终的结果不应该是它,你说呢?我们开始结合CVV进行思考,把它写得在数学上更优雅一致,更易于程序处理。
假入能够把上面写成这个形式:那么我们就可以非常方便的用矩阵以及齐次坐标理论来表达投影变换:其中哈,看到了齐次坐标的使用,这对于你来说已经不陌生了吧?这个新的形式不仅达到了上面原始投影变换的目的,而且使用了齐次坐标理论,使得处理更加规范化。
注意在把变成的一步我们是使用齐次坐标变普通坐标的规则完成的。
这一步在透视投影过程中称为透视除法(Perspective Division),这是透视投影变换的第2步,经过这一步,就丢弃了原始的z值(得到了CVV中对应的z值,后面解释),顶点才算完成了投影。
而在这两步之间的就是CVV裁剪过程,所以裁剪空间使用的是齐次坐标,主要原因在于透视除法会损失一些必要的信息(如原始z,第4个-z保留的)从而使裁剪变得更加难以处理,这里我们不讨论CVV裁剪的细节,只关注透视投影变换的两步。
矩阵就是我们投影矩阵的第一个版本。
你一定会问为什么要把z写成有两个原因:1)P’的3个代数分量统一地除以分母-z,易于使用齐次坐标变为普通坐标来完成,使得处理更加一致、高效。
2)后面的CVV是一个x,y,z的范围都为[-1,1]的规则体,便于进行多边形裁剪。
而我们可以适当的选择系数a和b,使得这个式子在z = -N的时候值为-1,而在z = -F的时候值为1,从而在z方向上构建CVV。
接下来我们就求出a和b:这样我们就得到了透视投影矩阵的第一个版本:使用这个版本的透视投影矩阵可以从z方向上构建CVV,但是x和y方向仍然没有限制在[-1,1]中,我们的透视投影矩阵的下一个版本就要解决这个问题。
为了能在x和y方向把顶点从Frustum情形变成CVV情形,我们开始对x和y进行处理。
先来观察我们目前得到的最终变换结果:我们知道-Nx / z的有效范围是投影平面的左边界值(记为left)和右边界值(记为right),即[left, right],-Ny / z则为[bottom, top]。
而现在我们想把-Nx / z 属于[left, right]映射到x属于[-1, 1]中,-Ny / z属于[bottom, top]映射到y属于[-1, 1]中。
你想到了什么?哈,就是我们简单的线性插值,你都已经掌握了!我们解决掉它:则我们得到了最终的投影点:下面要做的就是从这个新形式出发反推出下一个版本的透视投影矩阵。
注意到是经过透视除法的形式,而P’只变化了x和y分量的形式,az+b和-z是不变的,则我们做透视除法的逆处理——给P’每个分量乘上-z,得到而这个结果又是这么来的:则我们最终得到:M 就是最终的透视变换矩阵。
相机空间中的顶点,如果在视锥体中,则变换后就在CVV中。
如果在视锥体外,变换后就在CVV外。
而CVV本身的规则性对于多边形的裁剪很有利。
OpenGL在构建透视投影矩阵的时候就使用了M的形式。
注意到M的最后一行不是(0 0 0 1)而是(0 0 -1 0),因此可以看出透视变换不是一种仿射变换,它是非线性的。
另外一点你可能已经想到,对于投影面来说,它的宽和高大多数情况下不同,即宽高比不为1,比如640/480。
而CVV的宽高是相同的,即宽高比永远是1。
这就造成了多边形的失真现象,比如一个投影面上的正方形在CVV的面上可能变成了一个长方形。
解决这个问题的方法就是在对多变形进行透视变换、裁剪、透视除法之后,在归一化的设备坐标(Normalized Device Coordinates)上进行的视口(viewport)变换中进行校正,它会把归一化的顶点之间按照和投影面上相同的比例变换到视口中,从而解除透视投影变换带来的失真现象。