《Fundamentals of Computer Graphics》5th(计算机图形学基础/虎书),中文翻译。
第 3 章 Raster Images 光栅图像
大多数计算机图形图像都以某种光栅显示器向用户呈现。光栅显示器将图像显示为像素的矩形数组。常见的例子是平板电脑显示器或电视,它们具有小型发光像素的矩形阵列,可以分别设置为不同的颜色,创建任何所需的图像。通过混合红、绿、蓝三种光的不同强度来实现不同的颜色。大多数打印机,如激光打印机和喷墨打印机,也是光栅设备。它们基于扫描:没有物理像素网格,但图像是通过在网格上选择的点上依次沉积油墨而布置的。
Pixel 是“picture x element”的缩写。
光栅在图像输入设备中也广泛存在。数码相机包含一个图像传感器,其中包括一个灵敏的像素网格,每个像素记录其上落下的光的颜色和强度。桌面扫描仪包含一个线性像素阵列,该阵列在扫描的页面上横跨,在每秒进行多次测量,以生成像素网格。
打印机中的颜色更加复杂,涉及至少四种颜色的混合。
由于光栅在设备中非常普遍,因此光栅图像是存储和处理图像的最常见方式。光栅图像只是存储每个像素的像素值的二维数组 - 通常是存储为三个数字(红色,绿色和蓝色)的颜色。存储在内存中的光栅图像可以使用存储图像中的每个像素来控制显示器的一个像素的颜色来显示。
或者,可能是因为光栅图像非常方便,所以光栅设备很普遍。
但我们并不总是想以这种方式显示图像。我们可能想改变图像的大小或方向,校正颜色,甚至将图像显示在移动的三维表面上。即使在电视中,显示器的像素数量也很少与显示的图像相同。考虑到这些因素,打破了图像像素和显示像素之间的直接联系。最好将光栅图像视为独立于设备的图像描述,并将显示设备视为近似理想图像的一种方法。
除了使用像素数组之外,还有其他描述图像的方法。矢量图像通过存储形状的描述来描述 - 由线条或曲线界定的颜色区域,没有参考任何特定的像素网格。本质上,这相当于存储显示图像所需的指令,而不是显示它所需的像素。矢量图像的主要优点是它们是分辨率无关的,可以在非常高分辨率的设备上良好地显示。相应的缺点是它们必须在显示之前进行光栅化。矢量图像通常用于文本、图表、机械绘图和其他需要清晰度和精度的应用程序,而不需要摄影图像和复杂阴影。
在本章中,我们讨论了光栅图像和显示器的基础知识,特别注意标准显示器的非线性特性。当我们在后面的章节中讨论计算图像时,必须记住像素值与光强度之间的关系。
换句话说:你必须知道图像中那些数字实际上意味着什么。
在抽象讨论光栅图像之前,看一下使用这些图像的某些特定设备的基本操作是有益的。一些熟悉的光栅设备可以按以下简单层次结构分类:
当前的显示器,包括电视、数字电影投影机以及计算机的显示器和投影仪,几乎普遍基于固定的像素阵列。它们可以分为发光式显示器和透射式显示器两种类型。发光式显示器使用像素直接发出可控量的光,而透射式显示器中像素本身不会发出光,而是会改变它们允许通过的光的数量。透射式显示器需要光源来照明:在直接观看的显示器中,这是阵列后面的背光;在投影仪中,这是通过阵列之后投射在屏幕上的发光灯。发光式显示器是自己的光源。
发光二极管(LED)显示器是发光式显示器的一种例子。每个像素由一个或多个 LED 组成,这些是半导体器件(基于无机或有机半导体),通过它们的电流强度发出光(见图 3.1)。
彩色显示器中的像素被分为三个独立控制的亚像素 - 一个红色、一个绿色和一个蓝色 - 每个亚像素都有自己的 LED,使用不同材料制成,从而发出不同颜色的光(图 3.2)。当从远处观看显示器时,眼睛无法分离单个亚像素,所感知的颜色是红、绿和蓝的混合。
液晶显示器(LCD)是透射式显示器的一种例子。液晶是一种材料,其分子结构使它能够旋转通过它的光的极化方向,并且旋转角度可以通过施加电压进行调整。一个液晶像素(图 3.3)有一个偏振膜层在其后面,因此它被偏振光照亮 - 假设是水平偏振的。
像素前面的第二层偏振膜是垂直偏振的。如果施加的电压使液晶层不改变偏振方向,所有光都被阻挡,像素处于“关”(最小亮度)状态。如果施加的电压使液晶层旋转了 90 度偏振方向,那么从像素后面进入的所有光线都会通过前面逃逸出来,像素就完全“开启”——它具有最大亮度。中间电压会部分旋转偏振方向,以使前置偏振器部分阻挡光线,产生介于最小和最大亮度之间的强度(图 3.4)。与彩色 LED 显示器一样,彩色 LCDs 每个像素内有红、绿和蓝三个独立像素,带有相应颜色的滤镜。
任何带有固定像素网格的显示器,包括这些和其他技术,都具有基本的固定分辨率,由网格大小确定。对于显示器和图像,分辨率仅仅意味着像素网格的尺寸:如果桌面显示器的分辨率为 1920 x 1200 像素,则表示它具有 1920 列和 1200 行排列的 2,304,000 个像素。
显示器的分辨率有时被称为它的“本机分辨率”,因为大多数显示器可以通过内置的转换处理其他分辨率的图像。
为了填满屏幕,不同分辨率的图像必须使用第 10 章中介绍的方法转换为 1920×1200 的图像。
将图像永久地记录在纸张上的过程与在显示器上短暂地展示图像有非常不同的限制。在打印中,颜料被分布在纸张或其他介质上,以便当光线从纸张反射时形成所需的图像。打印机与显示器一样是栅格设备,但许多打印机只能打印二进制图像——颜料仅在每个网格位置上沉积或未沉积,没有中间量。
喷墨打印机(图 3.5)是一种通过扫描来形成栅格图像的设备。喷墨打印头包含携带颜色颜料的液体墨水,可以通过电子控制喷出非常小的滴。打印头在纸张上移动,随着它经过应该接收油墨的网格位置,滴落物被释放;在意图保持空白的区域不会释放墨水。在每次扫描后,纸张稍微向前移动,然后放置下一行网格。彩色打印品是通过使用几个打印头制作的,每个打印头喷出不同颜色颜料的墨水,因此每个网格位置都可以接收任何组合的不同颜色滴落物。由于所有滴落物都是相同的,喷墨打印机打印二进制图像:每个网格点都有一个滴落物或没有滴落物;没有中间阴影。
喷墨打印机没有物理的像素阵列;分辨率是由滴落物可以缩小多少和每次扫描后纸张前进多少来确定的。许多喷墨打印机在打印头中拥有多个喷嘴,使得可以在一次通行中进行几次扫描,但最终决定行距的是纸张前进,而不是喷嘴间距。
也有连续墨水喷射打印机,它们在包裹在旋转滚筒上的纸张上以连续的螺旋路径进行打印,而不是来回移动打印头。
热转印染料过程是一种连续色调印刷过程的例子,这意味着每个像素可以沉积不同数量的染料——它不像喷墨打印机那样只有完全沉积或完全未沉积(图 3.6)。一个含有彩色染料的供体带被夹在纸张或染料接收器和一个打印头之间,打印头包含一个线性的加热元件数组,每个元件对应于图像中每列像素的一个。当纸张和带子经过打印头时,加热元件会开关,以在需要染料的区域加热带子,导致染料从带子扩散到纸张。这个过程针对数种染料颜色进行了重复。由于更高的温度会导致更多的染料转移,因此可以控制在每个网格位置沉积的每种染料的数量,从而产生连续的颜色范围。打印头中的加热元件数量在页面方向上建立了一个固定的分辨率,但沿页面的分辨率由加热和冷却速度与纸张速度的比较确定。
与显示器不同,打印机的分辨率是用像素密度而不是总像素数来描述的。因此,一个热转印染料打印机,在其打印头上距离每英寸 300 个元件之间有空隙时,每英寸横向具有 300 像素的分辨率(ppi)。如果页面沿着相同的方向选择相同的分辨率,我们可以简单地说打印机的分辨率是 300 ppi。将点放置在每英寸网格中有 1200 个网格点的喷墨打印机被描述为具有 1200 点每英寸(dpi)的分辨率。由于喷墨打印机是二进制设备,它需要更细的网格至少有两个原因。由于边缘是突然的黑 / 白边界,因此需要非常高的分辨率来避免出现阶梯状或叠影现象(请参见第 9.3 节)。在打印连续色调图像时,高分辨率要求通过打印称为半色调的变密度点图案来模拟中间颜色。
术语“dpi”经常被用来表示“每英寸像素”,但是 dpi 应该用于二进制设备,并且 ppi 应该用于连续色调设备。
光栅图像必须来源于某个设备,而任何没有通过算法计算的图像都必须由某个光栅输入设备进行测量,其中最常见的是相机或扫描仪。即使在渲染 3D 场景的图像中,照片也经常被用作纹理贴图(参见第 11 章)。光栅输入设备必须为每个像素进行光测量,并且(类似于输出设备)通常基于传感器阵列。
数字相机是二维阵列输入设备的一个例子。相机中的图像传感器是一种带有光敏像素网格的半导体设备。两种常见的阵列类型称为 CCD(电荷耦合器件)和 CMOS(互补金属氧化物半导体)图像传感器。相机的镜头将要拍摄的场景投影到传感器上,然后每个像素测量落在其上的光能量,最终产生一个数字,进入输出图像(图 3.7)。与彩色显示器使用红、绿和蓝色子像素的方式非常相似,大多数彩色相机通过使用颜色滤波器阵列或马赛克,使每个像素只能看到红、绿或蓝光,留下图像处理软件填补缺失值的过程,即所谓的去马赛克(图 3.8)。
其他相机使用三个独立的阵列或阵列中的三个独立层,以测量每个像素的独立的红、绿和蓝色值,产生可用的彩色图像,无需进一步处理。相机的分辨率由阵列固定的像素数量确定,并通常使用总像素数进行报价:具有 3000 列和 2000 行阵列的相机可以产生 3000×2000 的分辨率的图像,其具有 600 万个像素,称为 6 百万像素(MP)相机。需要记住的是,马赛克传感器不能测量完整的彩色图像,因此,测量相同数量的像素但使用独立的红、绿和蓝色测量的相机记录比使用马赛克传感器的相机更多的图像信息。
销售相机的人使用“兆”表示 106,而不是像兆字节一样表示 220。
平板扫描仪也会为每个像素网格测量红、绿和蓝色值,但是与热升华打印机一样,它使用一个 1D 阵列横跨扫描的页面,每秒进行多次测量(图 3.9)。页面上的分辨率由阵列的大小固定,沿页面的分辨率则由测量频率与扫描头移动速度相比决定。彩色扫描仪具有 3×nx 阵列,其中 nx 是页面上像素的数量,三行被红、绿和蓝滤波器覆盖。通过在测量这三种颜色的时间之间适当地延迟,这允许在每个网格点进行三个独立的颜色测量。与连续调节打印机一样,扫描仪的分辨率以每英寸像素数(ppi)报告。
扫描仪的分辨率有时被称为其“光学分辨率”,因为大多数扫描仪可以通过内置转换产生其他分辨率的图像。
现在我们已经了解了图像的来源和去向的具体信息,接下来我们将更抽象地讨论图像,即我们将在图形算法中使用它们的方式。
“像素不是一个小正方形!”——阿尔维·雷·史密斯(1995 年)
我们知道,光栅图像是由许多像素组成的大数组,每个像素存储着其网格点处图像的颜色信息。我们已经了解了各种输出设备如何处理我们发送给它们的图像以及输入设备如何从物理世界中的光形成的图像中获取信息。但是,在计算机中进行计算时,我们需要一种方便的抽象,它与任何设备的具体细节无关,可以用来推断如何生成或解释存储在图像中的值。
当我们测量或再现图像时,它们采取光能的二维分布形式:显示器上发射的光随着表面位置的变化而变化;相机的图像传感器上落下的光随着平面上的位置变化而变化;纸张上的反射率(反射而不是被吸收的光的分数)随着位置在一个矩形区域内的变化而变化。因此,在物理世界中,图像是定义在二维区域上的函数,几乎总是矩形。因此,我们可以将图像抽象为一个函数:
其中 是一个矩形区域, 是可能的像素值集合。最简单的情况是理想化的灰度图像,每个矩形中的点只有亮度(没有颜色),我们可以说 (非负实数)。理想化的彩色图像,每个像素具有红、绿、蓝值,。我们将在下一节中讨论 的其他可能性。
是否存在任何不是矩形的光栅设备?
栅格图像与连续图像的抽象概念有何关联?从具体的例子来看,相机或扫描仪中的一个像素是图像在该像素周围一小区域内平均颜色的测量值。显示像素由红、绿、蓝三个子像素组成,其平均颜色取决于栅格图像中相应像素值在像素面上的位置。在这两种情况下,像素值是图像颜色的局部平均值,并被称为图像的点样本。换句话说,当我们在一个像素中找到值 x 时,它意味着“该网格点附近的图像值为 ”。图像作为函数采样表示的概念在第 10 章中进一步探讨。
图 3.10:四像素×三像素屏幕的坐标。请注意,在某些 API 中,y 轴会指向下方。
一个普通但重要的问题是像素在二维空间中的位置。这仅仅是一种约定俗成的问题,但确立一个一致的约定是很重要的!在本书中,栅格图像由 索引对表示,该对表示像素的列 和行 ,从左下角开始计数。如果一个图像有 列和 行像素,则左下像素为 ,右上像素为 。我们需要 2D 实际屏幕坐标来指定像素位置。我们将像素的采样点放置在整数坐标处,如图 3.10 所示的 4x3 屏幕。
在某些 API 和许多文件格式中,图像的行是从上到下组织的,以便 位于左上角。这是出于历史原因:模拟电视传输中的行是从顶部开始的。
图像的矩形域具有宽度 和高度 ,并且在此网格上居中,这意味着它在每侧都延伸半个像素长度。因此, 图像的矩形域为
一些系统将坐标移动半个像素,以将采样点放置在整数之间,但将图像的边缘放置在整数位置。
再次强调,这些坐标仅仅是约定俗成的,但在实现相机和查看变换时记住这些约定将非常重要。
到目前为止,我们已经用实数描述了像素的值,表示图像中某一点的强度(可能是红色、绿色和蓝色分开表示)。这表明图像应该是浮点数数组,每个像素存储一个或三个 32 位浮点数,用于灰度或黑白图像,或 RGB 彩色图像。当需要其精度和值范围时,有时会使用这种格式,但是由于图像具有大量像素,存储和传输图像所需的内存和带宽往往稀缺。只有一张 1000 万像素的照片就会占用约 115 MB 的内存。
为什么是 115 MB 而不是 120 MB?
对于直接显示的图像,不需要那么高的范围。虽然在原则上,可能的光亮度范围是无限的,但任何给定设备都有一个明显有限的最大亮度,因此在许多情况下,像素具有有界范围通常足够,通常取 以简化问题。例如,8 位图像中的可能值为 。存储浮点数的图像允许广泛的值范围,通常称为高动态范围(HDR)图像,以区别于存储整数的固定范围或低动态范围(LDR)图像。请参见第 20 章,深入讨论高动态范围图像的技术和应用。
255 的分母比 256 更难处理,但能够准确地表示 0 和 1 是很重要的。
以下是一些具有典型应用程序的像素格式:
减少用于存储每个像素的位数会导致图像出现两种明显的人工瑕疵,或称为人为引入的缺陷。首先,使用固定范围值对图像进行编码会产生剪切 (clipping),当本应比最大值亮的像素被设为最大可表示值时,就会发生剪切。例如,阳光明媚的场景的照片可能包含比白色表面更亮的反射;当图像转换为固定范围以显示时,它们将被剪切(即使它们是由相机测量得到的)。其次,使用有限的精度对图像进行编码会导致量化伪影 (quantization) 或条纹 (banding),在需要将像素值四舍五入为最接近的可表示值时,引入可见的强度或颜色跳跃。在动画和视频中,条纹可能不会在静止图像中产生问题,但当它们来回移动时,就会变得非常明显。
所有现代显示器都接受数字输入来表示像素的“值”,并将其转换为强度级别。真实的显示器在关闭时也有一定强度,因为屏幕会反射一些光线。对于我们的目的,我们可以认为这是“黑色”,而完全开启的显示器是“白色”。我们假设像素颜色的数字描述范围为 0 到 1。黑色为零,白色为一,介于黑色和白色之间的灰色为 0.5。请注意,“一半”指的是从像素发出的物理光量,而不是外观。人类对强度的感知是非线性的,在本章中不会讨论;有关更多信息,请参见第 19 章。
要正确地在显示器上显示图像,必须了解两个关键问题。第一个问题是显示器相对于输入是非线性的。例如,如果您给三个像素提供 0、0.5 和 1.0 作为输入,则显示的强度可能为 0、0.25 和 1.0(关闭、四分之一全亮和全亮)。显示器通常用 (“伽马”)值作为其非线性特征的近似表征。该值是公式
其中 是位于零和一之间的输入像素值。例如,如果显示器的伽马值为 2.0,并且我们输入 的值,则显示的强度将是可能强度的四分之一,因为 。请注意,无论γ的取值如何, 都对应零强度,而 则对应最大强度。使用 来描述显示器的非线性仅是一个近似;我们不需要在估计设备的 时过于精确。一种很好的视觉方法来衡量非线性是找到哪个 值可以给出黑色和白色之间强度的一半。这个 将是
如果我们能找到那个 ,我们就可以通过两边取对数来推导出 :
我们可以通过一种标准技术找到这个 ,其中我们显示一个黑白像素的棋盘图案,旁边有一个输入为 的灰色像素方块(图 3.11),然后要求用户调整 (例如使用滑块),直到两边的平均亮度匹配。当您从远处观察此图像(或者如果您近视,则不戴眼镜),当 产生介于黑色和白色之间强度时,图像的两侧看起来大约相同。这是因为模糊的棋盘图形混合了偶数个白色和黑色像素,因此整体效果是介于白色和黑色之间的均匀颜色。
一旦我们知道 ,我们就可以进行伽马校正,使得 的值以介于黑色和白色之间的强度显示。这是通过以下转换完成的:
图 3.11。从远处观察的交替黑白像素在黑色和白色之间。可以通过找到具有与黑白图案相同强度的灰度值来推断显示器的伽马值。
对于具有模拟接口的显示器,在水平方向快速更改强度存在困难,水平黑白条纹比棋盘图更有效。
将此公式代入方程(3.1)中,我们得到
实际显示器的另一个重要特性是它们采用量化输入值。因此,虽然我们可以在浮点范围 内操作强度,但向显示器提供的详细输入是固定大小的整数。这个整数的最常见范围是 0-255,可以保存在 8 位存储器中。这意味着 a 的可能值不是 中的任何数字,而是
这意味着可能的显示强度值大约为
其中 是最大强度。在需要精确控制强度的应用程序中,我们必须实际测量 256 种可能的强度,而这些强度可能在屏幕的不同位置不同,尤其是对于 CRT 来说。它们也可能随着观看角度的变化而变化。幸运的是,很少有应用程序需要如此准确的校准。
计算机图形学中大多数图像都是以 red-green-blue (RGB) 颜色空间定义的。 RGB 颜色是一种简单的颜色空间,转换后可以直接被大多数计算机控制屏幕的显示。本节从用户的角度讨论 RGB 颜色,目的是为了更方便的使用他们。第 18 章中将更详细地讨论颜色,但是 RGB 颜色空间的机制将使我们能够编写大多数图形程序。RGB 颜色空间的基本思想是通过混合三种原始光来显示其他颜色:红、绿、蓝。
在小学时,我们可能学过主要颜色是红色、黄色和蓝色,并且,例如,黄色+蓝色=绿色。这是减色混合 (subtractive) ,与在显示器中发生的更熟悉的加色混合 (additive) 不同。
在 RGB 加色混合中,我们有(图 3.12)
颜色“青色”是一种蓝绿色,颜色“品红色”是一种紫色。
如果我们可以将原始光从完全关闭(用像素值 0 表示)调暗到完全打开(用 1 表示),我们就可以创建在 RGB 显示器上显示的所有颜色。红、绿和蓝像素值创建了一个三维 RGB 颜色立方体,具有红色、绿色和蓝色轴。轴的可允许坐标范围从零到一。颜色立方体在图 3.13 中以图形方式显示。
立方体顶点的颜色为:
实际的 RGB 级别通常以量化形式给出,就像第 3.2.2 节讨论的灰度一样。每个分量都由整数指定。这些整数的最常见大小都是一个字节,因此每个 RGB 分量都是介于 0 和 255 之间的整数。三个整数一起占用三个字节,即 24 位。因此,具有“24 位颜色”的系统对于每个三原色都有 256 个可能的级别。第 3.2.2 节讨论的伽马校正问题也适用于每个 RGB 分量。
通常,我们希望只部分覆盖像素的内容。一个常见的例子是在合成中,我们有一个背景并想要将前景图像插入其中。对于前景不透明的像素,我们只需替换背景像素。对于完全透明的前景像素,我们不会更改背景像素。对于部分透明的像素,必须特别注意。当前景对象具有部分透明区域(如玻璃)时,可能会出现部分透明的像素。但是,前景和背景必须混合的最频繁情况是前景对象仅部分覆盖像素,无论是在前景对象的边缘还是在子像素孔中,例如在远处树叶之间。
混合前景对象和背景对象所需的最重要信息是像素覆盖度,它告诉我们前景层覆盖像素的分数。我们可以将这个分数称为α。如果我们想将前景颜色 合成到背景颜色 上,并且前景覆盖像素的分数为 ,则我们可以使用以下公式:
对于不透明的前景层,解释是前景对象覆盖像素矩形内的面积 ,而背景对象覆盖剩余区域(即 )。对于透明图层(可以想象在玻璃上或用半透明涂料在追踪纸上绘制的图像),解释是前景图层阻止了来自背景的光的()部分,并贡献了其自己颜色的 部分以替换已被移除的颜色。使用公式 (3.2) 的示例如图 3.14 所示。
图像中所有像素的 值可以存储在单独的灰度图像中,然后称为 alpha 掩码 (transparency mask) 或透明度掩码 (transparency mask)。或者,信息可以作为 RGB 图像中的第四个通道存储,在这种情况下,它称为 alpha 通道,图像称为 RGBA 图像。对于 8 位图像,每个像素占用 32 位,这在许多计算机架构中是一个方便的大小块。
由于前景和背景层的权重之和为 1,如果前景和背景层具有相同的颜色,则颜色不会改变。
尽管公式 (3.2) 通常被使用,但在一些情况下, 被使用方式有所不同 (Porter&Duff,1984)。
大多数 RGB 图像格式为每个红色、绿色和蓝色通道使用八位。这导致单个百万像素图像的原始信息约为三兆字节。为了减少存储需求,大多数图像格式允许某种形式的压缩。在高层次上,这种压缩要么是无损的,要么是有损的。无损压缩不会丢失任何信息,而在有损系统中某些信息将无法恢复地丢失。流行的图像存储格式包括:
由于压缩和变体,编写图像输入/输出例程可能会涉及到。幸运的是,可以依靠库例程来读取和写入标准文件格式。对于重要性在于简单而不是效率的快速应用程序,简单的选择是使用原始的 PPM 文件,这样可以通过仅将存储图像的数组转储到文件中,并添加适当的头来编写文件。
为什么不直接制造线性显示器 (monitors linear),避免所有这些伽马业务 (gamma business) 呢?
理想情况下,显示器的 256 个可能强度应该看起来均匀分布,而不是在能量上线性分布。由于人类对强度的感知本身是非线性的,在视觉上大约使用 1.5 至 3 之间的伽马(取决于观看条件)可以使强度在主观意义上近似均匀。因此,伽马就是一种特性。否则,制造商会制造线性显示器。
通过获取自然图像(最好是扫描照片而不是已经应用了贝尔模式的数码照片)并创建一个由交替的红/绿/蓝通道组成的灰度图像来模拟从贝尔模式中获取的图像。这模拟了数字相机的原始输出。现在从该输出创建真实的 RGB 图像并与原始图像进行比较。
本文作者:青波
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!