第3章
图形和图像的数据表现
现本章介绍图像及其数据表现形式。我们将依次介绍1位图像、8位灰度图像,以及绘制它们的方法,最后介绍24位彩色图和8位彩色图。此外还会讨论一些用于存储这种图像的文件格式的细节。
本章内容涉及如下主题:
●图形/图像的数据类型。
●常用的文件格式。
3.1 图形/图像的数据类型
多媒体的文件格式数量处于不断增长之中[1]。比如,表3.1列举了Adobe Premiere中可以使用的文件格式。本章将介绍一部分常见的文件格式,并阐述它们的工作方式。我们将重点关注GIF和JPG文件格式,GIF文件格式比较简单且包含了一些基本的特征,JPG则是最重要的一种文件格式。
接下来,我们将大致了解一下文件格式的特性。
3.1.1 1位图像
图像由像素(pixel)组成,像素是数字图像中的图片元素。一幅1位图像仅仅由“开”位和“关”位组成,这就是最简单的图像格式。图像的每个像素由内存空间中的一个位来存储(0或1)。因此,这样一幅图像称为二值图像。
二值图像又被称为1位单色(monochrome)图像,因为它不包含其他颜色。图3.1显示了一幅1位单色图像(多媒体科学家称之为“Lena”,这是一幅标准图像,用来说明许多算法)。一幅分辨率为640×480的单色图像需要38.4KB(即640×480/8)的存储空间。1位单色图像适用于仅含有简单图形和文本的图片。此外,传真机也使用1位图像。尽管现在存储性能已大幅提升,可以存储携带更多信息的图像,但1位图像仍然非常重要。
3.1.2 8位灰度图像
8位图像是指图像的每个像素有一个0~255之间的灰度值(gray value),每个像素由一个字节表示。例如,一个暗的像素的灰度值可能为10,而一个亮的像素的灰度值可能为230。
8位图像可以看作由像素值组成的二维数组。这样一个二维数组称为一幅位图(bitmap),作为图形或图像的数据表现,它与图形或图像在视频内存中的存储方法相似。
图像分辨率(image resolution)指的是数字图像中的像素数目(分辨率越高则图像质量越好)。对一幅图像而言,较高的分辨率可能是1600×1200,而稍低的分辨率可能是640×480。注意,这里使用4∶3的屏幕长宽比,我们不一定要使用这个比例,但是这个比例看起来更自然,因此早期的电视和笔记本电脑屏幕都是4∶3(见第5章)。后来的显示设备大多使用16∶9的长宽比以更好地与高清视频相匹配。
我们称存储二维数组的硬件设备为帧缓存(frame buffer),帧缓存封装在被称为“视频”卡(实际上是图形卡)的相对昂贵的特殊硬件中。视频卡的分辨率不必达到图像要求的分辨率,但是如果视频卡没有足够的存储空间,数据为了显示就不得不在RAM中置换。
我们可以把8位图图像看作一组1位位平面(bitplane),其中每个平面由图像的1位表示组成,如果图像的像素在某个位的值不为0,则这个值被置为1。
图3.2显示了位平面的概念。每个位平面的每个像素具有值0或1。所有的位平面的对应像素的位组成一个字节,用来存储0~255之间(8位情形下)的某个值。对于最低有效位,在二进制的最终数字和中,该位的值变为0或1。位置算法隐含着对于下一个(即第二个)位,该位的0或1对最终和的贡献是0或2。接下去的位代表0或4、0或8等,直到最高有效位贡献值为0或128。视频卡能够以视频速率刷新位平面的数据,但是不像RAM那样能很好地保存数据。在北美,光栅场以每秒60个周期的速度刷新,在欧洲刷新速率为50。
每个像素通常用一个字节存储(值从0~255),所以一幅640×480的灰度图像需要300KB的存储空间(640×480=307200)。图3.3再次显示了Lena图像,这次是一幅灰度图。
如果我们想打印(print)这样一幅图,可能会遇到一些困难。假设我们有一个600dpi的激光打印机。这样的设备通常只能打印一个点或者不打印一个点。然而,将一幅600×600的图像打印在一平方英寸的空间内,最终的效果并不是很好。此时采用抖动(dithering,也称为抖色)方法。它的基本策略是以亮度分辨率换取空间分辨率。59(文献[2]详细介绍抖动)。
抖动
在1位打印机上打印时,抖动用于计算较大的点图案,这样,0到255之间的值可以对应于正确表示明暗像素值的图案。主要的策略是用较大的图案(例如2×2或4×4)替换像素值,这样打印的点的数量就接近于用网版打印(halftone printing)的不同大小的圆盘字图案。网板打印是一种用于报纸印刷的模拟过程,使用较小或较大的黑油墨实心圆来表示阴影。
如果我们用n×n的开关1位点矩阵来代替,就能表现n2+1级亮度分辨率。比如,矩阵中任意三点被打印成黑色可算作一个亮度级。点模式用试探法创建。比如,用一个2×2的“抖动矩阵”:
我们可以先用除数是2565的整数除法把0~255间的图像的值映射到一个新的范围0~4。接下来,如果像素值是0,那么在打印机的一个2×2输出区域不进行打印;但如果像素值是4,则在4个点都填涂。所以规则如下:
如果像素亮度比抖动矩阵的某个元素的编号大,则在该元素填涂,即用一个n×n的点矩阵替代每个像素。
然而,我们注意到上述这种打印方式的亮度级数量还是太小。如果我们通过增加抖动矩阵的大小来增加亮度级数量,那么也会增加输出图像的大小。这就降低了图像在任何局部的清晰度,同时降低了图像的空间分辨率。
注意,对于一个经过抖动方法处理的图像,其尺寸可能太大,比如使用4×4矩阵替代每个像素点,会使图像变为原来的16倍。利用“有序抖动”的方法可以解决这个问题。假设我们用一个更大的4×4的抖动矩阵,如
然后假设我们把这个抖动矩阵在同一时刻移动到图像在水平和垂直方向的四个像素上(这里的图像值已经被降低到0~16这个区间中),如果某个像素的亮度值大于覆盖它的矩阵元素的编号,则填涂在打印机的相应元素输出位。图3.4a展示了Lena的灰度图。有序抖动版本在图3.4b中显示。其中,Lena右眼的详细情况在3.4c中显示。
一个使用n×n抖动矩阵的用于有序抖动的算法如下:
Foley等[2]对有序抖动进行了更详细的讨论。
3.1.3 图像数据类型
本节介绍图形和图像文件格式的一些最常见的数据类型:24位色和8位色。然后我们将讨论文件格式。一些文件格式只能用于特殊的硬件和操作系统平台(如Linux中的X-windows),而另一些是平台无关(platform-independent)或者跨平台(cross-platform)的文件格式。即使有些格式不是跨平台的,但转换程序能识别这些格式并将其转换成其他格式。
由于图像文件需要较大的存储空间,因此大多数图像格式都结合了某种压缩技术。压缩技术可划分为无损(lossless)压缩和有损(lossy)压缩。我们将在第7~14章学习各种图像、视频和音频压缩技术。
3.1.4 24位彩色图像
在一个24位彩色图像中,每个像素用三个字节表示,通常表示为RGB。因为每个值的范围是0~255,这种格式支持256×256×256(总共16777216)种可能的颜色组合。然而,这种灵活性会导致存储问题。例如,一幅640×480的24位彩色图像如果不经压缩,需要921.6KB的存储空间。
需要注意的一个重点是:许多24位彩色图像通常存储为32位图像,每个像素多余的数据字节存储一个α(alpha)值来表示特殊信息。(详见文献[2],使用α通道在图形图像中合成一些重叠物体,简单地用作一个透明标签)。
图3.5显示了图像forestfire.bmp,一幅用Microsoft Windows BMP格式(本章后面部分讨论)显示的24位图像。这幅图像的R、G、B通道的灰度图分别如图中显示。每个颜色通道的0~255的字节值表示亮度,我们就能够用每种颜色分别显示灰度图。
3.1.5 高位深度图像
在图像格式中,为了最大程度地忠于实际情况,一些格式是不压缩的。例如,在医学领域,患者的肝脏图像需要能够精确地展示各种细节信息。
在一些特殊的场景中,需要识别更多的图像信息。这些信息通常通过特殊的摄像头获得,可以查看超过三种颜色(即RGB)。比如,利用使用不可见光(如红外线、紫外线)的安全摄像机获取皮肤的医学图像,通过利用额外的颜色信息,这些图像可以更好地诊断皮肤疾病,如皮肤癌。另外,卫星影像使用高位深度图像,获取的信息用于指示庄稼生长的类型。将相机送入高空或太空可以帮助人们获取更多的信息,但可能我们现在还无法充分利用这些信息。
这类图像称为多光谱(超过三种颜色)或高光谱(许多图像平面,比如卫星影像的224色)。
在本章中,我们主要介绍灰度图和RGB彩色图。
3.1.6 8位彩色图像
如果空间相关(实际基本如此),通过量化颜色信息就可以得到足够精确的彩色图像。许多系统只能利用8位颜色信息(也称作256色)来生成屏幕图像,即使有些系统具备能真正使用24位颜色信息的硬件设备,但由于向后兼容的特性,我们必须理解8位彩色图像文件。我们将会发现有些技巧只适用于这类图像。
8位彩色图像文件使用了查找表(lookup table)来存储颜色信息。基本上,图像存储的不是颜色而仅仅是字节的集合,每个字节是指向一个表的索引。该表表项具有三字节值,指明了像素(带有查找表索引)的24位颜色。从某种程度上讲,它有点像小孩的按序号画图的绘画册,数字1可能代表橙色,数字2代表绿色等——真正的颜色集不一定是这个模式。
在一幅图中使用哪些颜色是具有最佳表现力和最有意义的?如果一幅图像描绘的是日落场景,那么合理的做法是精确地表现红色、存储少量的绿色。
假设一幅24位图像中所有的颜色都放在一个256×256×256的格子集里,同时还要在格子中存储每种颜色对应的像素数目。比如,如果23个像素具有RGB值(45,200,91),那么把23存储在一个三维数组中,元素下标值为[45,200,91]。这种数据结构称为颜色直方图(color histogram)。(详见文献[3,4])。颜色直方图是在图像处理中进行图像转换和操作的有用工具。
图3.6显示了forestfire.bmp中像素的RGB值的三维直方图。直方图有16×16×16个小格,并用亮度和伪彩色的形式显示了每个小格中的像素数目。我们能够看到一些颜色信息的重要聚类,对应forestfire图像的红色、绿色、黄色等。这样的聚类方法让我们能够选出最重要的256种颜色。
基本上,三维直方图小格中的大数据量能够由分割合并(split-and-merge)算法解决,以便选取最好的256种颜色。图3.7显示了作为结果的GIF格式(本章后面部分讨论)的8位图像。注意,很难区分图3.5a显示的24位图像和图3.7显示的8位图像的差别。不过这并不符合所有情况,比如在医学图像上:对用于激光外科手术的大脑图像,你是否满足于图像仅仅是“合理精确”呢?可能不会吧,这就是为什么要在医学应用中考虑使用64位图像的原因。
请注意,8位图像比24位图像大大节省空间,一幅640×480的8位彩色图像只需要300KB的容量,而在没有任何压缩的情况下,一幅彩色图像需要921.6KB的空间。
3.1.7 颜色查找表
回顾一下,在8位彩色图像中,仅仅是为每个像素存储下标或编号值。那么,如果一个像素存储的值是25,就表示颜色查找表(LookingUp Table,LUT)中的第25行。因为图像使用二维数组值显示,故它们通常按照行列顺序存储为一长串的值。对一幅8位图像而言,图像文件可以在文件头信息中存储每个下标对应的8位RGB值。图3.8显示了这种方法。颜色查找表通常称为调色板(palette)。
一个颜色选择器(color picker)由比较大的颜色块(或者说是断断续续的颜色空间)的数组组成,这样鼠标点击就能选中指定的颜色。实际上,一个颜色选择器显示其下标值为0~255的颜色板颜色。图3.9为颜色选择器的示意图。如果用户选择了下标值为2的颜色块,那么该颜色为青色,RGB值为(0,255,255)。
通过修改颜色表就可能制作简单的动画,这称为色彩循环(color cycling)或调色板动画(palette animation)。因为颜色表更新非常快,这样会获得简单但令人满意的效果,比如带颜色的文字跑马灯。因为更改小面板数据较为简单,这个技巧可能只适用于8位彩色图像。
抖动技术同样可以用来进行彩色打印。每个颜色通道用1位,同时用RGB点把颜色隔开。或者,如果打印机或者屏幕只能打印有限数量的颜色,比如用8位而不是24位,那么即使在颜色查找表中无法找到的颜色也是可以打印的。通过平均相邻像素点的亮度,显示的颜色分辨率可以明显增加而不用降低空间分辨率。这样我们就能通过采用空间混色来欺骗眼睛,让它感觉能看到不可获得的颜色。图3.10a显示了一幅24位彩色Lena图像;图3.10b显示了同一幅图通过抖动技术减少到5位的情况;图3.10c显示了左眼的细节。
怎样设计颜色查找表
在3.1.6节中,我们简单讨论了聚类(clustering)的思想,用于从一幅24位彩色图像中产生最重要的256种颜色。然而一般来说,聚类是昂贵又费时的办法,但我们的确需要设计颜色查找表,那么应该怎么做呢?
最直接的办法是在每一维把RGB立方体分成大小相等的块,然后将每个结果立方体中央的颜色作为颜色查找表的表项,只需要把RGB从0~255区间变为合适的区间就可以产生8位编号。
比起B,人们对R、G更敏感,所以我们可以分别将R值和G值的范围从0~255缩小到3位(0~7),而B值的范围缩小到2位(0~3),总共8位。为了缩小R值和G值区间,我们只需要用322568除R或是G字节值,并截取结果的小数部分。这样图像中每个像素用8位下标代替,而颜色查找表提供了24位颜色。
然而,应用这种简单方案的后果是图像中会出现边缘效果。这是因为RGB中的轻微变化会导致移动到一个新的编号,从而产生边缘,这看起来很不舒服。
解决这种色彩减退问题的一个简单方法是采用中值区分算法(median-cutalgorithm),一些其他方法也具有同样或更好的效果。这种方法是从计算机图形学[5]衍生而来的,这里我们只介绍一个精简的版本。这个方法是自适应分区方案的一种,它试图表达最多的位、具有最强的识别能力,而且颜色也是最聚集的。
该算法思想是将R字节值排序,并找到其中值。然后,比中值小的值标记为0位,比中值大的值标记为1位。中值是一半像素值比其小、一半像素值比其大的点。
假设我们把一些苹果画成图,大多数像素都是红色的,那么R的中值可能落在0~255范围内的较高部分。下一步,我们仅仅考虑第一步后被标记为0的像素,并将它们的G值排序。接着,我们用另一位标记图像像素,0标记比中值小的像素,1标记比中值大的像素。然后,把同样的规则用于第一步后被标记为1的像素,这样我们给所有的像素点加上了2位标签。
继续在B分量上执行上述步骤,我们就得到了3位的方案。重复前面所有步骤,得到6位方案,再重复R、G步骤,得到了8位方案。这些位形成了像素的8位颜色下标值,相应的24位颜色是最终小颜色立方体的中心。
可以看到,事实上这种方案关注那些最需要与大量颜色位区别的位。利用显示0~255数目的直方图,我们可以很容易找到中值。图3.11显示了图forestfire.bmp的R字节值的直方图以及这些值的中值,用竖线表示。
用相应的颜色查找表中的24位颜色替代每个像素得到的24位彩色图像仅是原图的一个近似。不过,上述算法的意义是在最需要的地方(最需要注意的小的色差)赋予了最大的识别能力。还需要提到的是,有一些方法可用来把近似误差平均到每个像素上,这具有平滑8位近似图像的效果。
中值区分算法的更精确的版本如下所示:
1) 找出最小的方形区域,它包含图像中的所有颜色。
2) 沿方形区域的长边排序它所包含的颜色。
3) 在排序链表的中间处把该方形区域划分为两个区域。
4) 重复上面步骤2和3,直到初始的颜色空间被分割成256个区域为止。
5) 对每个方形区域,把该方形区域中R、G、B的平均值作为其代表(中心)颜色。
6) 根据一个像素的RGB值与每个方形区域的中心值的欧氏距离,给每个像素分配一个代表颜色。在指向代表颜色的查找表中(其中,每种代表颜色是24位的,R、G、B均为8位)用编号替代像素。
这样,我们就有了一个256行的表,每行含有3个8位值。行的下标是查找表的编号,这些下标正是存储在新的量化颜色(调色板)图像中的像素值。
3.2 常见的文件格式
下面介绍一些流行的文件格式。其中最简单的一种是8位GIF格式,我们学习它是因为它容易理解,而且它与万维网和HTML标记语言有着历史渊源,它是能被网络浏览器识别的第一种图像类型。然而,目前最重要和常用的文件格式是JPEG,我们将在第9章中详细介绍它。
3.2.1 GIF
图形交换格式(Graphics Interchange Format,GIF)是由UNISYS公司和Compuserve公司开发的,最初通过调制解调器在电话线上传送图形图像。GIF标准采用了Lempel-Ziv-Welch算法(一种压缩格式,详见第7章),但对图像扫描线数据包稍加修改,以有效地使用像素的行分组。
GIF标准仅适用于8位(256)彩色图像。因为这能够生成可接受的颜色,它最适合用于具有少量独特色彩的图像(如图形和绘画)。
GIF图像格式具有一些有趣的特点,尽管它在很多地方已经被取代了。该标准支持隔行扫描——通过套色(four-pass)显示方法处理,相隔的像素可以连续显示。
事实上,GIF有两个版本,最初的规范是GIF87a。后一个版本GIF89a通过数据中的图形控制扩展(Graphics Control Extension)块支持简单的动画。它对延时、透明索引等提供了简单的控制。像Corel Draw这样的软件支持对GIF图像的访问和修改。
GIF87文件格式的一些细节是有意义的,因为许多这样的格式与其有共同之处;不过与这个“简单”标准相比,已经变得复杂很多。对于标准规范而言,常用的文件格式如图3.12所示。其中签名是6个字节:GIF87a;屏幕描述符是7字节标志位。一个GIF87文件可以包含不止一种图像定义,通常与屏幕中不同的部分匹配。因此每个图像可以有自己的颜色查找表,即局部色图(Local Color Map),用于把8位映射成24位RGB值。然而,局部色图不是必需的,可以定义一个全局的色图替代它。
屏幕描述符包含了属于文件中每个图像的属性。根据GIF87标准,如图3.13所示。屏幕宽度在前两个字节中给出。因为一些机器可能会转换MSB/LSB(最高有效字节/最低有效字节)顺序,这个顺序就被指定了。屏幕高度在后两个字节给出。如果没有给出全局色图,则将第5个字节的“m”置0。颜色分辨率“cr”为3位,范围从0~7。因为这是一个老的标准,通常在一些低端硬件上操作,“cr”需要很高的颜色分辨率。
下一位显示为0,在该标准中没有用到。“pixel”为另外3位,指明图像文件中每个像素的位数。但是通常“cr”等于“pixel”,故“pixel”不是必需的。第6字节给出背景颜色在颜色表中的下标,第7字节填0。在现在的用法中,使用小的颜色分辨率比较好,因为我们可能会对非常低端的设备感兴趣,比如支持上网功能的手表。
可以用一个简单的方法建立色图(color map),如图3.14所示。然而,正如屏幕描述符指出的,表的真实长度等于2pixel+1。
文件中的每幅图像都有自己的图像描述符,在图3.15中定义。有趣的是,标准的定制者们为了将来的扩展,忽略了一幅图像末尾和另一幅图像开始的一些字节,用逗号来识别。这样,在将来需要扩展时,就非常容易做到向后兼容。
如果设置了局部图像描述符中的隔行位,则图像的行以套色顺序显示,如图3.16所示。这里,第一个通道显示第0行和第8行,第二个通道显示第4行和第12行,以此类推。这样,当一个Web浏览器显示图像时,就能让图像概略迅速显示,进而再详细展示细节。下面的JPEG标准具有相似的显示方式,这种方式称为渐进式方式。
真实光栅数据(actual raster data)本身在存储前先用LZW压缩方案(详见第7章)压缩。
为了将来的使用,GIF87标准也设定了扩展块该怎样定义。即使在GIF87中,也可以实现简单的动画,但是没有定义图像间的延迟。多幅图像之间只能被覆盖,而不会清屏。
GIF89引进了许多扩展块定义,特别是那些和动画相关的定义,如透明和图像间延迟。GIF89中引入的一个相当有用的特性是排序颜色表。最重要的颜色率先出现,这样,如果解码器只能使用较少的颜色,则最重要的颜色就会被选中。也就是说,仅使用颜色查找表中的一部分,72邻近的颜色尽可能映射到可利用的颜色。
通过看一个GIF图像,就可了解文件头是怎样工作的。图3.7是一幅8位彩色GIF图像。为了了解文件头,我们可以使用UNIX/Linux/Max OS操作系统中比较常用的命令:od(octal dump)。在UNIX下,我们使用命令:
这样,我们就可以看到前32个字节被解释为如下字符:
为了解释文件头的剩余部分(GIF87a之后的部分),我们使用十六进制:
得到结果:
其中,签名后的d002和bc01是屏幕宽度和高度。它们以低位字节在前的顺序表示,所以对这个文件,屏幕宽度用十六进制表示是0+13×16+2×162=720,屏幕高度是11×16+12+1×162=444。f7(十进制的247)为屏幕描述符的第5个字节,之后是背景色索引00和分隔符00。标识符f7以位形式表示为1,111,0,111。换句话说,采用全局色图、8位颜色分辨率、0分隔符、8位像素数据。
3.2.2 JPEG
目前最重要的图像压缩标准是JPEG[6]。该标准由国际标准化组织(International Organization for Standardization,ISO)的一个工作组制定,该工作组的一个非正式称呼为联合图像专家组(Joint Photographic Experts Group),JPEG也因此得名。我们将在第9章详细学习JPEG,不过这里先介绍它的一些主要特点。
JPEG利用了人类视觉系统一些特定的局限,从而获得很高的压缩率。眼脑系统看不到一些极其精准的细节。如果一些像素发生了许多变化,我们称图像的那个部分具有高空间频率,即在(x,y)空间发生了许多变化。和灰度图相比,这个局限对于彩色图更为明显。因此,JPEG中的颜色信息被大量丢掉并且图像中的小块用空间频率域(u,v)来表现,而不是(x,y),即从低到高对x和y的改变速度进行估计。通过将这些速度的系数或权值进行分组,可以形成一个新的“图像”。
人们偏好缓慢变化的权值。这里有一个简单的方法:值被大的整数除并截尾,这样小的值就变成了零,然后采用能够有效表示一长串0的方案。瞧!图像就被极大地压缩了。
因为在除和截断步骤中扔掉了许多信息,所以这种压缩方案是有损的(尽管也有无损的方式)。而且,因为让用户直接选择使用多大的分母,也就是决定了将丢失多少信息,JPEG允许用户设定需要的质量等级,或者说是压缩率(输入除以输出)。
作为例子,图3.17展示了forestfire图像,质量因数Q=10(通常默认的质量因数为Q=75)。
这幅图仅是原图大小的1.5%。在压缩时,一幅Q=75的JPEG图像的大小为原图的5.6%,而这幅图的GIF版本大小压缩到原图的23.0%。
3.2.3 PNG
随着因特网的流行,研究人员花费大量的精力研究更多与系统无关的图像格式。这就是便携式网络图形(Portable Network Graphics,PNG)。这个标准有望取代GIF标准并做了重要扩展。提出一个新标准的原因部分在于UNISYS和Compuserve在LZW压缩方法上的专利。(有趣的是,该专利仅仅有压缩,而没有解压缩,这也是为什么UNIX的gunzip功能可以将LZW压缩文件解压缩的原因)。
PNG的独特和优势之处是最多可支持48位的色彩信息——这是非常大的进步。文件可能还包含用于正确显示彩色图像的伽马(gamma)校正信息(见4.1.6节)以及用于透明控制的Alpha通道信息(最多16位)。与GIF图像中基于行隔行扫描的逐行显示不同,PNG在7个通道上对图像的每8×8块在二维空间内逐步显示一些像素。相对于GIF,它能更好地支持有损和无损压缩。多数网页浏览器和图像软件都支持PNG。
3.2.4 TIFF
标记图像文件格式(Tagged Image File Format,TIFF)是另一种常用的文件格式。它由Aldus公司在20世纪80年代开发,后来受到Microsoft的支持。它支持附带额外信息(称为标记),这提供了极大的灵活性。最重要的标记就是格式表示(format signifier),即在存储图像时用了哪些压缩类型等。比如,TIFF可以存储不同的图像类型,包括1位、灰度、8位、24位RGB等。TIFF最初是无损格式。但是新的标记能让你选择使用JPEG、JBIG,甚至JPEG 2000格式压缩。因为TIFF不像JPEG那样是用户可控的,所以它不具有后者的主要优点。TIFF文件普遍用于存储未压缩的数据。TIFF文件分为几部分,每部分可以存储位图图像、向量式或基于图元的图像(见下面的补充说明)或其他类型的数据。每部分的数据类型都在它的标签中指定。
3.2.5 Windows BMP
位图(BitMap,BMP)是Microsoft Windows主要的系统标准图形文件格式。它使用光栅图形技术。BMP支持很多像素格式,包括索引颜色(每像素8位)和16、24、32位彩色图像。它利用行程编码(Run-Length Encoding,RLE)压缩(详见第7章),并且可以有效地压缩24位彩色图像(利用24位RLE算法)。位图图像也可以不压缩存储。需要指明的是,16位和32位彩色图像(带有α通道)总是不压缩的。
3.2.6 Windows WMF
Windows元文件(Windows MetaFile,WMF)是用于Microsoft Windows操作环境的本地向量文件格式。WMF文件实际上由一系列图形设备接口(Graphics Device Interface,GDI)函数调用组成,它对Windows环境而言也是本地的。当“播放”一个WMF文件时(通常使用Windows的PlayMetaFile()函数),以便呈现出所描述的图形。WMF文件表面上是设备无关和大小无限制的。增强型图元文件格式和扩展(Enhanced Metafile Format Plus Extensions,EMF+)格式是与设备无关的。
3.2.7 Netpbm Format
PPM(Portable PixelMap)、PGM(Portable GrayMap)和PBM(Portable BitMap)属于开源项目Netpbm Format。这些格式在Linux/UNIX环境中很常见。它们也称为PNM或PAM(Portable AnyMap)。这些都是ASCII文件或原始二进制文件,并且带有ASCII头。它们很简单且可以方便地用于跨平台应用。很多软件都支持它们,比如X-windows的xv、Linux系统上的GIMP,也可以用于Mac OS以及Windows。
3.2.8 EXIF
可交换图像文件(Exchangeable Image File,EXIF)是用于数码相机的图像格式。它使记录的图像元数据(曝光、光源/闪光、白平衡、场景类型等)按照图像标准交换。一系列标签(比TIFF标签多很多)使高质量的打印更容易,因为关于相机和照片拍摄场景的信息很容易保存并使用,比如打印机的色彩校正算法。在大多数数码相机中EXIF格式附加在JPEG软件中。它还包括音频的文件格式规范,附加在数字图像中。
3.2.9 PS和PDF
PostScript是一种用于排版的重要语言,许多高端的打印机有内置的PostScript解释器,PostScript是基于向量的(而不是基于像素的)图片语言,其页元素本质上用向量定义。有了以这种方式定义的字体,PostScript包含文本,也包含向量/结构化图形,位映射图像也可以包含在输出图像中。封装的PostScript文件加上一些信息就可以将PostScript文件包含在另一个文档中。
一些流行的图形程序(如Illustrator和FreeHand)都会用到PostScript,然而PostScript页描述语言本身并没有提供压缩。实际上,PostScript文件就是用ASCII保存的。因此,文件通常都很大,从理论上说,这种文件通常只有在利用UNIX的工具(如compress或者是gzip)压缩之后才能够使用。
因此,另一种文本+图的语言已经开始取代PostScript,Adobe System公司在它的便携式文档格式(Portable Document Format,PDF)中包含了LZW(见第7章)压缩。其结果是,不包含图像的PDF文件拥有几乎相同的压缩比(2∶1或者3∶1),就像用其他基于LZW压缩工具的文件一样,比如UNIX的compress或gzip、基于PC的winzip(pkzip的变体)或WinRAR。对于包含图像的文件,PDF通过对图像内容使用单独的JPEG压缩(与创建原始图和压缩版本的工具有关),可以获得更高的压缩比。Adobe Acrobat PDF阅读器也可以用于阅读构建为超链接元素的文档,这种文档提供可点击的内容和方便的树状结构的总结的链接图表。
对计算机科学与工程的学生来说,了解PostScript这个名字出现的原因是很有意思的,因为这个语言基于堆栈结构的后缀表示法,即运算符在操作数之后的形式。基于图元的图像在PostScript上的特征意味着带有清晰线条的图表应该可以在任何输出设备上输出,更重要的是可以产生任何缩放级别的输出(低分辨率的打印机也应该产生低分辨率的输出)。PostScript引擎输出设备(比如屏幕)使行程命令尽可能整洁。比如,我们运行命令100 200 moveto,PostScript翻译程序会把x和y的位置放入堆栈;如果我们继续输入250 75 lineto和stroke,会把一行写入下一个点。
3.2.10 PTM
多项式纹理映射(Polynomial Texture Mapping,PTM)是一项存储相机场景表示的技术,其中包含了一系列在不同光照下拍摄的照片的信息,每个都有相同的光谱,并放不同的场景位置[7]。
假设我们已经得到了通过定位相机拍摄的一个场景的n幅图像,但是光照方向ei=(ui,vi,wi)T不同用。比如,可以使用40或50个半球形灯架,每个放在穹顶顶端。PTM的一部分目的是为了发现被拍摄对象的表面性质,这已经用在了拍摄博物馆文物与绘画方面。PTM的主要任务是插入照明方向,以便生成之前没有看到的新图像。通过将多重插值系数修改为整数的方法来保持PTM图像集合的文件大小在较小的水平。
图3.18a展示了输入图像的标准集合,这里显示了50个输入图像。图3.18b展示了插值图像,其中不包含光照方向[8]:其中光照系数为θ=42.6°,代表垂直于该轴平面的x,y角。
PTM的工作原理是:假定一个生成亮度的多项式模型L=R+G+B(或R、G、B分别计算),并通过亮度方向ei(其中i=1,…,n)来计算回归模型Li[7]。径向基函数(RBF)多余的插值用于非光滑现象插值,比如阴影和镜面反射[8]。
3.3 练习
1.简要解释为什么我们需要少于24位的颜色,而且这样为什么会带来麻烦?一般而言,我们需要怎么做才能把24位颜色值转换为8位颜色值?
2.假设我们需要量化8位的灰度图像到仅仅2位精度。最简单的办法是什么?原图像中字节值的哪个范围映射到哪个量化值?
3.假设我们有5位灰度图像。我们需要多大的抖动矩阵来在1位打印机上显示这幅图?
4.假设对一幅彩色图像的每一个像素,我们有24位可以利用。然而我们发现,比起蓝色(B)来,人们对红色和绿色更为敏感,实际上,人们对红色(R)和绿色(G)的敏感度是蓝色的1.5倍。我们怎样才能更好地使用可以利用的位?
5.在你的工作中,你决定通过用更多的磁盘空间来存储公司的灰度图像,以给你的老板留下深刻的印象。你喜欢用RGB,每个像素48位,而不是每个像素使用8位。那么,你怎样用新的格式存储原来的灰度图像以使它们在视觉上看起来和原来一样呢?
6.如图3.19a所示的8位灰度图,从左至右从0到255线性阴影,如图3.19b所示。这幅图像的大小是100×100。对于最重要的位平面,请画一幅图像显示1和0,这里有多少1?对于次重要的位平面,请画一幅图像显示1和0,这里有多少1?
7.对于颜色查找表的问题,在一幅图像上试试中值区分算法。简要解释该算法:若用在一幅红苹果图像上,在红色中,为什么把更多的颜色等级放在那些需要24位彩色图像的地方?
8.关于无序抖动,一本标准的图形教材[2]讲到:“甚至可以用更大的模式,但是空间分辨率与亮度分辨率的折中受到我们视觉敏锐程度(普通光中大约1′的弧)的限制。”
(a) 这句话是什么意思?
(b) 如果拿着一张纸站在一英尺开外的地方,点之间的大致线性距离是多少?(提示:1′的弧是1°角的1/60。一个圆上的弧长等于角(用弧度)乘以半径。)我们能够看到用300dpi打印机打印出的点的间隙吗?
9.写一个算法(伪代码)来计算RGB数据的颜色直方图。
10.详细描述怎样使用单一的图像和一些颜色查找表来实现简单的动画——一个旋转色轮,其中一个序列的四个快照会重复出现,轮子每次旋转90°。