JPEG标准的工作原理和实现技术朱志婷2010.4.161.位图文件格式简介位图(BMP)文件是Windows系统下最常用的独立于设备的位图文件。BMP格式是基于RGB颜色模式,且一般不压缩原始图像。BMP位图文件默认的文件扩展名是BMP或bmp。读取BMP文件中每个像素点的R、G、B值是非常重要的,它是之后整个图像压缩编码的基础。首先需要清楚地知道BMP文件的详细结构。BMP文件大体上分成四个部分,如下图所示:位图文件头BITMAPFILEHEADER位图信息头BITMAPINFOHEADER调色板Palette实际的位图数据ImageData1.1位图文件头BITMAPFILEHEADER是一个结构,定义如下:typedefstructtagBITMAPFILEHEADER{WORDbfType;DWORDbfSize;WORDbfReserved1;WORDbfReserved2;DWORDbfOffBits;}BITMAPFILEHEADER;该结构的长度固定,为14个字节(WORD为无符号16位整数,DWORD为无符号32位整数),各个域的说明如下:bfType:指定文件类型,必须是0x424D,即字符串“BM”,所有.bmp文件的头两个字节都是“BM”。bfSize:文件大小,包括位图文件头的14个字节。bfReserved1,bfReserved2:为保留字,不用考虑。bfOffBits:从文件头到实际的位图数据的偏移字节数,即表2中前三个部分的长度之和。1.2位图信息头BITMAPINFOHEADER也是一个结构,定义如下:typedefstructtagBITMAPINFOHEADER{DWORDbiSize;LONGbiWidth;LONGbiHeight;WORDbiPlanes;WORDbiBitCount;DWORDbiCompression;DWORDbiSizeImage;LONGbiXPelsPerMeter;LONGbiYPelsPerMeter;DWORDbiClrUsed;DWORDbiClrImportant;}BITMAPINFOHEADER;该结构长度固定为40个字节(LONG为32位整数),各个域的说明如下:biSize:指定这个结构的长度,为40。biWidth:指定图像的宽度,单位是像素。biHeight:指定图像的高度,单位是像素。biPlanes:必须是1,不用考虑。biBitCount:指定表示颜色时要用到的位数。常用的位数值有:1(黑白两色图),4(16色图),8(256色图),24(真彩色图)。biCompression:指定位图是否压缩。一般为BI_RGB,表示不压缩。biSizeImage:指定实际的位图数据占用的字节数。biXPelsPerMeter:指定目标设备的水平分辨率,单位是每米的像素个数。biYPelsPerMeter:指定目标设备的垂直分辨率,单位是每米的像素个数。biClrUsed:指定本图像实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次方。biClrImportant:重要的颜色数,如果该值为零,则认为所有的颜色都重要。1.3调色板调色板是对那些需要调色板的位图文件而言的。有些位图,如真彩色图,是不需要调色板的,BITMAPINFOHEADER之后直接是位图数据。调色板实际上是一个数组,共有biClrUsed个元素,若biClrUsed为零,则有2的biBitCount次方个元素。数组中每个元素的类型是一个RGBQUAD结构,占4个字节,其定义如下:typedefstructtagRGBQUAD{BYTErgbBlue;//该颜色的蓝色分量BYTErgbGreen;//该颜色的绿色分量BYTErgbRed;//该颜色的红色分量BYTErgbReserved;//保留值}RGBQUAD;1.4实际的图像数据对于用到调色板的位图,图像数据是该像素颜色在调色板中的索引值,对于真彩色图,图像数据是实际的B,G,R值。256色图,一个字节恰好可以表示1个像素。真彩色图:三个字节表示一个像素。1.5BMP文件读取和显示的过程可以概括为以下几步:在BMP文件的相应位置读出文件的有关信息,如文件类型(bfType)、图像的宽度(biWidth)、图像的高度(biHeight)、表示颜色时要用到的位数(biBitCount)。Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充。所以要根据biWidth和biBitCount计算补齐的字节数。计算补齐的字节数externWidth的代码为:externWidth=biWidth*(biBitCount/8)%4;if(externWidth!=0)externWidth=4-externWidth;若是8位图,需要先读取调色板的数据,再根据像素点颜色在调色板中的索引值获得每个像素点的R、G、B值;若是24位图,直接读取每个像素点的值即可。根据每个像素点的值显示图片。需要注意一点,BMP文件的数据是从下到上、从左到右的。从文件中最先读到的是图像最下面一行的左边第一个像素,然后是左边第二个像素……接下来是倒数第二行左边第一个像素,然后是左边第二个像素……依次类推,最后得到的是最上面一行的最右边的一个像素。2.静态图像压缩标准JPEG2.1JPEG简介JPEG(JointPhotographicExpertsGroup)是联合图像专家小组的英文缩写,这个专家组开发的算法称为JPEG算法,并且成为国际上的彩色、灰度、静止图像的第一个国际标准,因此又称为JPEG标准。JPEG是一个适用范围很广的静态图像数据压缩标准,不仅适用于静止图像的压缩,也常常被用于电视图像序列的帧内图像压缩编码。目前JPEG专家组开发了两种基本的压缩算法:一种是采用以离散余弦变换DCT为基础的有损压缩算法;另一种是采用以预测技术为基础的无损压缩算法。使用有损压缩算法时,在压缩比为25:1的情况下,压缩后还原得到的图像和原始图像相比较,非图像专家难以找到它们之间的区别,因此得到了广泛的应用。例如在V-CD和DVD-Video电视图像压缩技术中,就使用JPEG的有损压缩算法来取消空间方向上的冗余数据。基于DCT的JPEG压缩算法是有损压缩,它利用了人的视角系统的特性,使用量化和无损压缩编码相结合来去掉视角的冗余信息和数据本身的冗余信息。JPEG算法框图如图1所示,压缩编码大致分成三个步骤:(1)使用正向离散余弦变换(ForwardDiscreteCosineTransform,FDCT)把空间域表示的图变换成频率域表示的图。(2)使用加权函数对DCT系数进行量化,这个加权函数对于人的视觉系统是最佳的。(3)使用哈夫曼可变字长编码器对量化系数进行编码。译码或者叫做解压缩的过程与压缩编码过程正好相反。2.2JPEG压缩的基本原理基于DCT编码的JPEG压缩算法可由如下的几个步骤实现:颜色模式转换及采样;正向离散余弦变换(FDCT);量化(Quantization);编码:(1)Z字形编码(ZigzagScan);(2)使用差分脉冲编码调制(DPCM)对直流系数(DC)进行编码;(3)使用行程长度编码(RLE)对交流系数(AC)进行编码;(4)熵编码;2.2.1颜色模式转换及采样JPEG的图片使用的是YCrCb颜色模型,而不是计算机上最常用的RGB.YCrCb模型更适合图形压缩.因为人眼对图片上的亮度Y的变化远比色度C的变化敏感.从RGB转换成YCrCb:Y=0.299R+0.587G+0.114BCr=(0.500R-0.4187G-0.0813B)+128Cb=(-0.1687R-0.3313G+0.500B)+128常用的采样格式有4:1:1和1:1:11:1:1采样就是保留所有的YCrCb值,相当于每个像素点用1个Y样本、1个Cr样本、1个Cb样本表示。而4:1:1采样是指对于一个2×2像素的数据块,取4个亮度Y样本、1个红色差Cr样本、1个蓝色差Cb样本。2.2.2正向离散余弦变换(FDCT)(1)DCT要求输入数据是一个8×8的矩阵,且每个矩阵元素具有8bit精度,分为从-128到127,故DCT变换前,每个像素值的分量先要减去128。(2)把一幅图像划分成一系列的图像块,每个图像块包含8×8个像素。若图像的高或宽不是8的整数倍,必须扩展其下边或右边到8的整数倍。如果原始图像有640×480个像素,则图片将包含80列60行的方块。如果图像是彩色的,那么每个像素可以用24比特、相当于三个8位比特的组合来表示。因此,可以用三个8行8列的二维数组表示这个8×8的像素方块。每一个数组表示其中一个八位比特组合的像素值。离散余弦变换作用于每个数组。DCT变换是做什么的?简单的说,是用一个8行8列的二维数组产生另一个同样包含8行8列二维数组的函数,也就是说,把一个数组通过一个变换,变成另一个数组。如图下图所示,对每个图像块做离散余弦变换。通过DCT变换可以把能量集中在矩阵左上角少数几个系数上。f(i,j)经DCT变换之后得到F(i,j),其中F(0,0)是直流系数,称为DC系数,其他为交流系数,称为AC系数。图2离散余弦变换(3)用f表示像素值的数组,f(i,j)表示i行j列的值,则离散余弦变换后定义一个新的数组F(u,v),表示u行v列的值。DCT变换使用公式(1)计算:77001(21)(21),(,)coscos]41616ijiujvuvuvfijF()=C()C()[(1)它的逆变换使用公式(2)计算:77001(21)(21),(,)coscos]41616uviujvfijuvFuv()=C()C()[(2)上面两式中,C(u),C(v)=,当u,v=0;C(u),C(v)=1,其他。1/2图3显示了对源图像的8×8的图像样本的原始数组应用离散余弦变换的结果。在对源数组f进行变换之前首先对源图像中的每个样本数据减去128。然后再按公式(1)分别计算出结果数组F中每个数组元素的值。比如说,计算F(0,0)的值过程如下:]16)12(cos16)12(cos),()[()(41)0,0(7070ijvjuijifvCuCF]),()[0()0(417070ijjifCC1885212141=235.6(因为cos(0)=1)这样再继续计算出数组中其余元素的值,得到数组F。图3离散余弦变换的数组f(i,j)经DCT变换之后得到F(i,j),其中F(0,0)是直流系数,称为DC系数,其他为交流系数,称为AC系数。(4)在计算二维的DCT变换时,也可使用下面的计算式(3)、(4)进行简化,把二维的DCT变换变成一维的DCT变换,如图4所示为二维DCT变换方法。701(21),(,)cos]216iiuuvuGivF()=C()[(3)701(21)(,)(,)cos]216ijvGivvfij=C()[(4)图4两维DCT变换方法2.2.3量化为了达到压缩数据的目的,DCT系数需做量化。量化是对经过FDCT变换后的频率系数进行量化,这是一个多到一映射的过程。量化的目的是减小非0系数的幅度以及增加0值系数的数目,在一定的主观保真的前提下,丢掉那些对视觉效果影响不大的信息,量化是图像质量下降的最主要原因。对于有损压缩算法,JPEG算法使用如图5所示的均匀量化器进行量化,量化步距是量化表的元素,它由系数所在的位置和每种颜色分量的色调值来确定。因为人眼对亮度信号比对色差信号更敏感,因此使用了两种量化表:如表1所示的色度量化值(针对Cr,Cb)和表2所示的亮度量化值(针对Y)。此外,由于人眼对低频分量的图像比对高频分量的图像更敏感,因此图中左上角的量化步距要比右下角的量化步距小。表1和表2中的数值对CCIR601标准(国际无线电咨询委员会CCIR[InternationalRadioConsultati