JPEG压缩学习笔记
来源:互联网 发布:微信电子书制作软件 编辑:程序博客网 时间:2024/06/06 01:20
JPEG压缩学习及其C语言实现笔记
JPEG压缩流程
1.颜色转换(RGB->YUV)
2.DCT变换 (分块8*8进行DCT变换)
3.量化(-996, 19, 0, 2,0, 0, 0, 0…)
4.编码 (游程编码,哈夫曼编码)
DCT变换(离散余弦变换)空间域到频率域的变换
“变换”的基本思想是,找一组基,让图像在这组基下能量集中(少量系数值较大,其余系数接近于0)。为了达到分离能量的目的,“变换”一般应是正交的。变换必须是可逆的(否则无法解码),因此变换本身不能压缩信息。不过随后的“量化”步骤将影响不大的系数略去,即可达到压缩的目的。
适合图像压缩的变换有很多种,如Karhunen-Loeve变换(KLT,即主成分分析)、离散傅立叶变换(DFT)、离散余弦变换(DCT)、Walsh-Hadamard变换(WHT)等。
JPEG采用8x8的2-D DCT作为其核心,该变换的定义是:
其中当u,v=0时,C(u),C(v)=1/root(2),否则C(u),C(v)=1。
在计算DCT之前,要把输入图像的像素值减去128,让它的取值范围从[0,255]移到[-128,127]。
每个8x8的分块经过DCT运算得到64个系数。其中,F(0,0)称为直流系数,其余的63个系数称为交流系数。在典型的连续色调图像中,相邻像素之间的差别往往不大。这意味着空间频率的幅值集中在低频部分。对典型的8x8图像分块而言,大多数空间频率的幅值是0或者接近于0,在编码时可以忽略。DCT本身并不会降低图像的质量,最多由于整数运算的舍入误差导致重构的图像与原始图像略有差别。
如果直接采用前面的公式进行计算,则每个DCT系数F(u,v)需要64次乘法,计算全部64个DCT系数则需要64x64=4096次乘法。计算DCT是整个JPEG压缩过程中最耗时的一步,很多人研究快速算法,也有人往CPU增加新指令,使之便于DCT运算。基本思路是把2-D DCT分解为1-D DCT,再利用余弦函数的对称性来减少计算量。每个分块的计算复杂度为O(1)。对于NxM的图像,共有[N/8]x[M/8]个分块,因此,DCT这一步的计算复杂度为O(MxN)。
系数量化
量化(quantization)是JPEG压缩过程中唯一会大幅损失信息的步骤。64个DCT系数会用8x8的量化表进行均匀量化,量化表中的每个元素是1到255之间的整数,表示对应的DCT系数的量化步长。量化的作用在于降低DCT系数的精度,从而达到更好的压缩率。量化是多对一映射,因此是有损的,它是基于变换的编码器中导致信息损失的主要步骤,也是用户唯一能参与控制压缩质量的步骤。
量化的过程是将每个DCT系数除以对应的量化步长,并四舍五入为整数:
反量化(dequantization)是把量化后的系数乘以对应的量化步长:
量化表理论上应该根据输入图像确定,目标是在基本不影响图像的视觉效果的前提下,尽量提高压缩率。量化步长越大,压缩率越大,图像质量越低。JPEG标准的正文中并没有规定或推荐使用哪个量化表,不过在Annex K中有一份量化表的例子(如下图所示),适用于大多数中等质量的图片。对于超高质量和超低质量的图片,这份量化表不是最优的。通常亮度分量和色差分量各有一张量化表,而且对色差分量的将忽略更多的高频成份。实际的JPEG实现都采用这一份量化表,因此后的数据中无须包含量化表。如果把下表中的量化步长除以2,那么图像质量就接近完美了。
每个分块有64个系数需要量化,需用64次除法和取整操作,因此每个分块的计算复杂度为O(1)。对于NxM的图像,共有[N/8]x[M/8]个分块,因此量化这一步的计算复杂度为O(MxN)。
Hoffman编码
JPEG文件的格式及组织形式
参见JPEG标准的 Annex BCompressed data formats
JPEG是JointPhotographic Experts Group的缩写,正是这个专家组制定了JPEG标准以及其他静态图片编解码标准。Joint(联合)是指ISO TC97 WG8(计算机与信息处理技术委员会第8工作组)和CCITT SGVIII两个工作组的联合.这个专家组在1992年颁布了第一个JPEG标准, ITU在1992年命名为ITU-T Recommendation T.81, ISO/IEC在1994年命名为10918-1
注意JPEG标准仅仅说明定义了codec部分,也就是图片如何压缩为字节流以及重新解码为图片的过程.标准没有涉及到文件的存储格式.
JPEG标准的附录B定义了文件格式"JPEG Interchage Format"(JIF),不过这个文件格式很少被用到,主要是因为Encoders和Decoders完整实现JIF很困难,此外这个标准还缺少以下几个方面:
- Color space定义
- Component sub-sampling 限制
- 像素宽高比
因此其他的JPEG文件格式标准陆续出现了.1992年颁布了JPEG FileInterchange Format(JFIF),紧接着出现了Exchange imagefile format(Exif)和ICC color profiles. 这些格式都符合JIF的字节layout,但是又增加了一些不同的markers.在某种程度上说,JFIF是JIF标准的精简版本.
Exif JPEG文件格式主要用在摄像设备上,摄像产业把Exif作为行业的元数据交换格式.由于Exif标准不支持color profiles,所以大部分软件图像编辑软件使用JFIF格式存储JPEG码流.
不论是Exif还是JFIF格式,都遵守JPEG interchangeformat(JIF),他们都是由JPEG marker和compressed data组成的.下面列出了JPEG的所有marker
表1 JPEG的marker定义
短名
字节码
Payload
名称
Comments
SOI
0xFF, 0xD8
None
Start Of Image
SOF0
0xFF, 0xC0
Variable size
Start Of Frame 0
Baseline DCT-based JPEG, and specifies the width, height, number of components
SOF2
0xFF, 0xC2
Variable size
Start of Frame 2
Progressive DCT-based JPEG
DHT
0xFF, 0xC4
variable size
Define Huffman Table(s)
Specifies one or more Huffman tables
DQT
0xFF, 0xDB
variable size
Define Quantization Table(s)
Specifies one or more quantization tables
DRI
0xFF, 0xDD
2 bytes
Define Restart Interval
Specifies the interval between RSTn markers, in macroblocks.This marker is followed by two bytes indicating the fixed size
SOS
0xFF, 0xDA
variable size
Start of Scan
Start of Scan
RSTn
0xFF, 0xDn
None
Restart
Insert every r macroblocks. where r is the restart interval set by a DRI marker.
APPn
0xFF, 0xEn
variable size
Application-sepcific
An Exif JPEG file uses an APP1 marker to store metadata; JFIF JPEG file uses an APP0 marker to store JFIF metadata
COM
0xFF, 0xFE
variable
Comment
Contains a text comment
EOI
0xFF, 0xD9
none
End of Image
表2 JPEG Start ofFrame marker结构
字段名称
长度
Comments
标记代码
2 bytes
固定值0xFFC0
数据长度
2 bytes
SOF marker长度,包括长度自身但不包含标记代码
精度
1 bytes
每个样本数据的位数,通常是8位,一般软件都不支持12位和16位
图像高度
2 bytes
图像高度,单位:像素
图像宽度
2 bytes
图像宽度,单位:像素
颜色分量数
1 bytes
灰度级1,YCbCr或YIQ 3,CMYK 4
颜色分量信息
颜色分量数x3
每个颜色分量:1byte分量ID;1 byte水平垂直采样因子;1 byte 当前分量使用的量化表ID
表3 JPEG Start of Scan
字段名成
长度
Comments
标记代码
2 bytes
固定值0xFFDA
数据长度
2 bytes
SOS marker长度,包括长度自身
颜色分量数
1 bytes
灰度级1, YCbCr或者YIQ 3, CMDK 4
颜色分量信息
颜色分量数x3
每个样色分量:1 byte颜色分量ID;1 byte直流/交流系数表号
压缩图像数据
3bytes
1 byte
谱选择开始固定为0x00
1 byte
谱选择结束固定为0x3f
1 byte
谱选择 在basic JPEG中总为00
表4 JEPG APP0应用程序保留标记0
字段名称
字段长度
Comments
标记代码 marker
2 bytes
固定值0xFF, 0xE0
数据长度 length
2 bytes
APP0总长度,不过括marker,但是包括length
标识符 identifier
5 bytes
固定的字符串"JFIF\0"
版本号 version
2 bytes
一般为0x0101或者0x0102
像素单位 unit
1 bytes
坐标单位,0没有单位; 1 pixel/inch;2 pixel/cm
水平像素数目 Xdensity
2 bytes
垂直像素数目 YDensity
2 bytes
缩略图水平像素数目
1 byte
缩略图垂直像素数目
1 byte
缩略图RGB位图
3n bytes
n = Xthumbnail * Ythumbnail, 这是一个24bits/piexl的RGB位图
表5 APPn应用程序保留标记
字段名称
字段长度
Comments
标记代码 marker
2 bytes
固定值0xFFE1 ~ 0xFFEF, n=1~15
数据长度 length
2 bytes
APPn的总长度,不包括marker的2bytes
详细信息
(length - 2) bytes
内容是应用特定的,比如Exif使用APP1来存放图片的metadata,Adobe Photoshop用APP1和APP13两个标记段分别存储了一副图像的副本。
表6 DQT DefineQuantization Table
字段名称
子字段
字段长度
Comments
标记代码 marker
2 bytes
固定值0xFF, 0xDB
量化表长度 length
2 bytes
DQT的总长度,不包括marker的2bytes
量化表
(length-2)bytes
精度及量化表ID
1 bytes
高4位:精度,只有两个可选值,0 8bits,1 16bits;
低4位:量化表ID,取值范围为0~3
表项
64*(精度+1) bytes
EOI marker
End of Image, 图像结束marker,一般来说EOI在JPEG文件的末尾处,但是有的JPEG会在EOI之后添加一些内容。
0xFF在JPEG文件中具有标记性的含义,后一个字节则根据不同意义有不同数值,在每个标记码之前还可以添加书目不限的无意义的0xFF填充,也就是说连续的多个0xFF可以理解为一个0xFF,并表示一个标记码的开始。
注意由于compressed data(jpeg压缩数据流)中可能出现0xFF的,为了和marker区分开,就需要特殊处理。具体的做法是在0xFF后添加一个没有意义的0x00。如果在图像数据流中遇到0xFF,检测紧接着的字符,处理规则如下:
1) 0x00,则表示0xFF是图像流的组成部分。
2) 0xD9,则与0xFF共同组成EOI标记,图像流结束,同时图像文件结束。
3) 0xD0~0xD7,则组成RSTn标记,则要忽视真个RSTn标记,即不对当强的0xFF和紧接着的0xDn两个字节进行译码,并按照RST标记的规则调整译码变量。
4) 0xFF,忽视当前的0xFF,对后一个0xFF在做判断
5) 其他数值,则忽视当前的0xFF,并把紧接着的数值用于译码
JFIF - JPEG FILE Interchange Format
JFIF是为了使得JPEG码流能够在广泛的平台和应用见进行交换的最小文件格式.这个最小文件格式不包括TIFF JPEG标准任何高级特性,以及任何应用特定的文件格式.这种简化格式的初衷就是为了方便JPEG压缩图像的交换.
JFIF语法符合ISO DIS 10918-1附录B中关于交换文件语法的定义.此外,JFIF使用APP0 marker来实现JFIF特定于JIF的部分
JFIF格式文件的 layout:
[cpp] view plaincopy
1. 0xFF,0xD8 SOI,Start of Image
2. 0xFF,0xE0 APP0, length, identifies, version,units, Xdensity, YDensity, Xthumbnail Ythunbnail, (RGB)n
3. length 2 bytes: 这个APP0域的长度,包括长度字段本身的2 bytes,但是不包括APP0 marker自身
4. identifier 5 bytes: 0x4A, 0x46, 0x49, 0x46, 0x00. 字符串"JFIF"
5. version 2 bytes: 版本号,一般为0x0102 或者0x0101,也就是1.01或者1.02
6. units 1 bytes: 坐标的单位,units=0: 没有单位;units=1: 每英寸一个点;units=2 每厘米一个点
7. Xdensity 2 bytes: 水平像素数
8. Ydensity 2 bytes: 垂直像素数
9. Xthumbnail 1 bytes: Thumbnail水平像素数
10. Ythumbnail 1 bytes: Thumbnail垂直像素数
11. (RGB)n 3n bytes: 打包的24bits RGB thumbnail像素 n = Xthumbnail*Ythumbnail
12. [可选的JFIF扩展APP0 marker段]
13. ...
14. ...
15. 0xFF, 0xCn SOFn(Start of Frame), length, frame paramters
16. ...
17. ...
18. 0xFF, 0xD9 EOI (End of Image)
由此刻见, APP0是JFIF特有的部分
Exif - Exchange Image File Format
这个标准是Camera产业联合会发布的,主要目的就是设计一种文件格式,方便交换照片文件的metadata
Exif文件的layout
[cpp] view plaincopy
1. SOI 0xFF, 0xD8 Start of frame
2. APP1 0xFF, 0xE1 Exif Attribute Information
3. APP2 0xFF, 0xE2 Flashpix Externsion data
4. ...
5. APPz 0xFF, 0xEn
6. DQT 0xFF, 0xDB
7. DHT 0xFF, 0xC4
8. DRI 0xFF, 0xDD
9. SOF 0xFF, 0xC0(0xFF, 0xC2)
10. SOS 0xFF, 0xDA
11. Compressed Data
12. EOI 0xFF, 0xD9
利用matlab进行测试和优化
可以利用matlab对同一幅图像生成不同质量因子的一系列图像,然后提取所获得的jpg图像当中的量化表信息做为自己C语言代码当中的量化表。不过,从jpg图像中获取的量化表要人工将其重新按照zig-zag的顺序进行排列。方法如下:
lena = imread('lena_752x480.bmp','bmp');
lena_gray = rgb2gray(lena);
imwrite(lena_gray,'F:\VS\JPEG\jpeg_debug\Doc\lena_gra752x480.jpg','jpeg','Quality',22);
lena_gray_jpg = imread('F:\VS\JPEG\jpeg_debug\Doc\lena_gra752x480.jpg','jpg');
subplot(1,2,1); imshow(lena_gray);
subplot(1,2,2); imshow(lena_gray_jpg);
- JPEG压缩学习笔记
- JPEG 压缩学习
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- JPEG 学习笔记
- jpeg入门学习笔记
- jpeg编码学习笔记
- 第三章第二十一题
- Samung LCD接口原理
- 素数
- 批处理中for调用call而不是goto
- 编写基于XML的配置元数据
- JPEG压缩学习笔记
- WebService学习笔记系列(三)
- Reverse Bits
- 固有的不可移植的特性
- iptables的备份、恢复及防火墙脚本的基本使用
- iOS --- Objective-C中类的成员变量与属性
- 百度地图 ip查询 service
- drawable对应表
- jxl 读取excel日期格式