第十章 投影
目前,我们已经在三维空间中描述了物体(objects)和视点(eye)。我们下一步的目标,是要理解如何将这些描述信息,转换为一张从视点处观察看到的二维图像。为此,我们需要建立一个简单的摄影机模型。通篇我们假设摄影机位于视点坐标系()的原点,并且看向视点的负轴方向。我们使用记号来表示视点坐标系下的一点。
10.1 针孔相机
最简单的摄影机形式是针孔相机(图10.1)。光线朝着摄影机的成像面运动,大部分会被一个位于的不透光平面所阻挡。但是,我们在该平面的中心设置一个非常小的孔洞,它位于视点坐标系的处。

在真实的物理世界中,任何真实的相机都需要具有一个有限大小的光圈,从而定量的可被测量的光能够从光圈中通过,并抵达摄影机成像面。并且,一旦光圈是有限大小的量,就需要一个镜头来辅助更好的将入射光“组织”并聚焦。不过,这些问题现在并不对我们造成困扰,因为我们不是要依据物理法则制造真实的相机。第 21 章有关于此话题更详细的内容。
在针孔相机中,摄影机成像面上的数据需要进行翻转,才能得到我们想要的照片。从数学角度看,通过将针孔相机与摄影机成像面置于针孔的前方,例如平面(图10.2),我们可以省略掉翻转图像这个步骤。在真实世界中,这是不现实的,但对于针孔相机的数学模型来说,这样做完全可行。

当创建好图像之后,如果我们将它固定在平面,并且在原点处观察(图10.3),对我们来说观察到的结果会与直接观察原始场景相同。我们精确再现了从原点处观察场景时,抵达我们眼部的数据。如果在空间中移动这幅图像,例如离眼睛近一点或远一点,我们就不再精确再现原始场景的视觉刺激信息了,但是它仍旧会看起来是一个视觉上可信的原始场景。

10.2 基础数学模型
针孔相机在数学上非常容易建模。我们使用坐标系来表示摄影机成像面上的点。目前,我们在摄影机成像面上选定了一个二维坐标系统,它恰好与视点坐标系相匹配(也就是, 且 ),但是我们很快会放宽这一设定。
给定空间中一点 在视点坐标系下的坐标 ,可以轻易看出(根据相似三角形定理)从点 射向原点的射线,与成像面相交的位置为:
我们可以将其用矩阵运算表达为:
其中横线(—)意味着“我们不关心此处的值”。这个矩阵称作投影矩阵(projection matrix)。矩阵相乘的原始输出,,称作点 的裁切坐标系向量(clip coordinates)。(如此命名,是因为这个原始数据随后会在裁切阶段使用,是第12.1节的内容)。 是一个新的变量,称作分量(-coordinate)。在这样的裁切坐标空间里,第四个分量不一定必须为 0 或 1。
我们说 ,并且 。如果想要单独提取 ,必须进行除法 ,(对 也是这样)。当这么做的时候,我们恢复了等式 10.1 中的计算,即简单摄影机模型使用的计算。(译者注:因为此时 )
我们得到的附有脚标 的输出坐标系向量,称作归一化设备坐标系(normalized device coordinates),因为它用与具体像素数无关的抽象单位,表达了图像上的点。在计算机图形学中,我们将所有的图像数据都维持在正则正方形内(canonical square) ,并最终将其映射到屏幕上的一个窗口中。这个正方形之外的数据,不会被记录或显示。这正是我们在附录 A 中用来描述 2D OpenGL 绘制的模型。
10.3 变体
通过改变投影矩阵中的项,我们可以对摄影机的几何变换进行微调。
10.3.1 缩放
如果我们将摄影机成像面移动到 处,其中 是一个负数(图10.4),我们可以将该摄影机建模为

这样做类似于镜头上的变焦。用矩阵来表达则是
这样实际上相当于,在原先成像面位于 的相机的基础上,将记录到的图像以 为系数进行缩放,并最终只保留图像位于正则正方形内的部分(如图10.5)。因此,后面我们最好不再将归一化设备坐标系向量(normalized device coordinates),看作位于成像面上、与某一视点坐标系相吻合的坐标系,而是简单的认为它是图像平面上固有的一个坐标系。

控制缩放系数的一个好方法是,通过给定目标摄影机的垂直视场角度(field of view)来决定 。尤其是当我们想要让摄影机的视场角为 度的时候。这时我们就可以设定 (如图10.6),由此我们得到投影矩阵为

我们可以直接验证,任意以原点为起点,并与负 轴在垂直方向形成的夹角为 度的射线,都会被映射到成像面上正则正方形的边界上,因此,该相机的视场角是 度。 例如,视点坐标系向量 映射到归一化设备坐标系为 。
更通用的处理问题,我们可以用不同的水平和垂直缩放系数 和 来分别缩放原始图像,从而得到如下的摄影机模型:
在计算机图形学中,这种不等比的缩放在处理不为正方形的屏幕窗口时会用到。假设窗口的宽大于高。在摄影机变换中,我们需要在水平方向上挤压物体,以便更宽的水平视场角可以被容纳进我们留存的正则正方形内。当数据随后映射到窗口中时,它会被相应的拉伸从而看起来没有变形。
定义 ,即屏幕的宽高比(aspect ratio)为它的宽度除以高度(例如以像素为单位)。我们可以将投影矩阵设置为
这个相机的垂直方向与等式(10.4)中保持不变,但是在生成图像时,采用了相应更宽的水平视场角。
当窗口的高大于宽,也就是 时,我们依然可以使用等式 10.5 中的矩阵,但我们也许并不满意这样做得到的水平视场角,因为它很狭窄。如果我们希望 为垂直或是水平视场角中最小的那个,那么,当 时,我们需要使用如下的投影矩阵:
这正是在 6.2 小节中我们调用 makeProjection
所产生的矩阵。
在计算机图形学中,选用视场角时常常需要去平衡不同的因素。一方面,更广的视场角,例如在一个游戏环境中,可以让观察者看到四周更多的东西。另一方面,在一个典型的观察环境下(除非有人把脸直接贴在屏幕前面),屏幕只占据了观察者四周环境的很小一部分角度。在这种情况下,观察者看到的几何关系会与图像环境中的不一致(就像图 10.3 中那样),并且图像看起来会有点变形(例如球体可能显示时不是圆形)。
10.3.2 移轴
不太常见的是,也许我们会希望用 来移动 2D 归一化设备坐标系。这可以用投影矩阵建模为
对应到摄影机上,这个矩阵就描述了一个移轴的成像面(shifted film plane)(如图10.7)。它也许看起来很罕见,但实际上,因为制造工艺以及光学的问题,大部分真实的相机内部都确实有一些微量的偏移。

在计算机图形学中,移轴相机的主要用途是平铺显示(如图10.8),我们将多个显示屏并列放置来组成一个更大的屏幕。在这种情况下,这些每一个子图像都以一个适当的移轴相机来建立数学模型。移轴的另一个应用是创建一对图像,用于单屏幕上的立体显示。

通常在计算机图形学中,表示移轴(以及缩放)的相机时,会首先给定一个近切平面 。通过指定一个视点坐标系下,与坐标轴平行的长方形,可以在这个平面上确定一个长方形。(为了得到没有变形的输出结果,这个长方形的宽高比应该与最终的窗口相吻合。)用 的值来表示这个长方形在 坐标轴上的左右边界,并且用 来表示它在 坐标轴上顶和底部的边界。总的来说,这些参数描述了空间中一个 3D 视锥(frustum)的形状。穿过这个长方形并射入原点的射线,会被映射到正则正方形图像内,使用如下投影矩阵描述
(如图 10.9)。

10.3.3 其他
在矩阵式(10.6)左上角 2 乘 2 的区域中,留有两个零在我们的摄影机模型中没有涉及到,这是一个典型的情况。这块 2 乘 2 的区域作为一个整体,可以表示像素网格的旋转与切变。切变在真实摄影机中并不常见,在计算机图形学中也不常用。当然,我们可以围绕着摄影机的光轴来旋转整个摄影机,但是这种旋转,在最初定义视点坐标系 时,就可以用适当的摄影机旋转来表示!
10.4 应用情境(Context)
我们所描述的投影操作是一种映射,它可以在视点坐标系下应用在任何给定的点上,从而得到该点的归一化设备坐标系。尽管在 OpenGL 中,这一映射只被应用于三角形的顶点上。一旦得到了三角形上三个顶点的归一化设备坐标系向量,通过计算图像平面上位于三角形内部的所有像素,就可以简单的得到三角形内部的点。
练习
10.1 假设我们给一个冰做的立方体拍照。将它正面的投影绘制出来,用实线表示靠前的面,用虚线表示背部的面。假设用 40,30 和 20 度的视场角来分别拍摄三张图像。摄影机的其他参数保持不变。那么以下的图像序列哪一个比较可信:

10.2 (发散思考)看以下两张照片: 你能否看出这些照片是如何拍摄的?两张照片使用的视点坐标系和投影矩阵有何不同?(提示:记住我们可以制造出移轴相机。)
(版权信息:图片来自[26],版权属于 Phillip Greenspun)

10.3 (发散思考)设 ,且 是一个摄影机矩阵,是一个任意的 4 乘 4 矩阵,且第三行以"—"填充。给定 6 个点的世界坐标以及它们的归一化设备坐标,如何计算矩阵 中的 12 个未知项?(注意:必须包含未知的缩放系数才能解出这个问题)(提示:用 0 建立一个适当的右手性齐次线性系统)
Last updated
Was this helpful?