一、实验原理
1. JPEG编码原理
- DCT变换:能量守恒,能量集中,去相关
从框图可以看出先进行电平偏移再进行8x8块的DCT变换。level offset的原因在于Y的范围为(0,255),而U、V的范围为(-128,128),所以Y的电平应该减去128,再分为8x8的块进行DCT变换。
DCT变换的基本思路是将图像分解为8×8的子块或16×16的子块,并对每一个子块进行单独的DCT变换,然后对变换结果进行量化、编码。随着子块尺寸的增加,算法的复杂度急剧上升,因此,实用中通常采用8×8的子块进行变换。
对每个单独的彩色图像分量,把整个分量图像分成8×8的图像块,如图所示,并作为两维离散余弦变换。
- 基于人眼特性量化DCT系数
选择的是中平型均匀量化器,因为人眼对亮度信号比对色差信号更敏感,因此使用了两种量化表:亮度量化值和色差量化值。
根据人眼的视觉特性(对低频敏感,对高频不太敏感)对低频分量采取较细的量化,对高频分量采取较粗的量化。如果原始图象中细节丰富,则去掉的数据较多,量化后的系数与量化前差别较大。
- 对量化后的DCT系数F(u,v)数据进行熵编码
DC系数编码
由于直流系数 F(0,0)反映了该子图像中包含的直流成分,通常较大,又由于两个相邻的子图像的直流系数通常具有较大的相关性,所以对 DC 系数采用差值脉冲编码(DPCM),即对本像素块直流系数与前一像素块直流系数的差值进行无损编码。
AC系数编码
AC编码进行了之字形扫描:由于经DCT变换后,系数大多数集中在左上角,即低频分量区,因此采用Z字形按频率的高低顺序读出,可以出现很多连零的机会。可以使用游程编码。尤其在最后,如果都是零,给出EOB (End of Block)即可。
游程编码:系数序列分组,将非零系数和它前面的相邻的全部零系数分在一组内;每组用两个符号表示[(Run,Size),(Amplitude)],Amplitude:表示非零系数的幅度值;Run:表示零的游程即零的个数;Size:表示非零系数的幅度值的编码位数;
2. JPEG解码
与编码相反
过程 |
---|
解码Huffman数据 |
解码DC差值 |
重构量化后的系数 |
DCT逆变换 |
丢弃填充的行/列 |
反0偏置 |
对丢失的CbCr分量差值(下采样的逆过程) |
YCbCr→RGB |
3. JPEG文件格式
格式 | 全称 | 说明 | 标记代码 | 固定值 |
---|---|---|---|---|
SOI | Start of Image | 图像开始 | 2字节 | 0xFFD8 |
APP0 | Application | 应用程序保留标记0 | 2字节 | 0xFFE0 |
DQT | Define Quantization Table | 定义量化表 | 2字节 | 0xFFDB |
SOF0 | Start of Frame | 帧图像开始 | 2字节 | 0xFFC0 |
DHT | Define Huffman Table | 定义哈夫曼表 | 2字节 | 0xFFC4 |
SOS | Start of Scan | 扫描开始 12字节 | 2字节 | 0xFFDA |
EOI | End of Image | 图像结束 | 2字节 | 0xFFD9 |
DQT 定义量化表
具体字段 | 字节数 | 说明 |
---|---|---|
数据长度 | 2字节 | 字段①和多个字段②的总长度 |
量化表 | 数据长度-2字节 | 具体内容包括以下两项 |
精度及量化表ID | 1字节 | 高4位:精度,只有两个可选值(0:8位;1:16位) 低4位:量化表ID,取值范围为0~3 |
表项 | (64×(精度+1))字节 | 例如8位精度的量化表,其表项长度为64×(0+1)=64字节 |
DHT,定义哈夫曼表
具体字段 | 字节数 | 说明 |
---|---|---|
数据长度 | 2字节 | |
huffman表 | 数据长度-2字节 | 具体内容包括以下内容 |
表ID和表类型 | 1字节 | 高4位:类型,只有两个值可选(0:DC直流;1:AC交流) 低4位:哈夫曼表ID,注意,DC表和AC表分开编码 |
不同位数的码字数量 | 16字节 | |
编码内容 | 16个不同位数的码字数量之和(字节) |
二、实验流程
实验流程 |
---|
逐步调试JPEG解码器程序。将输入的JPG文件进行解码,将输出文件保存为可供YUVViewer观看的YUV文件。 |
理解程序设计的整体框架。 |
理解三个结构体的设计目的。 struct huffman_table、struct component、struct jdec_private |
理解在视音频编解码调试中TRACE的目的和含义:会打开和关闭TRACE、会根据自己的要求修改TRACE。 |
以txt文件输出所有的量化矩阵和所有的HUFFMAN码表。 |
输出DC图像并经过huffman统计其概率分布。 |
输出某一个AC值图像并统计其概率分布。 |
三、关键代码分析
- 将输出文件保存为可供YUVViewer观看的YUV文件
tinyjpeg.h
enum tinyjpeg_fmt {
TINYJPEG_FMT_GREY = 1,
TINYJPEG_FMT_BGR24,
TINYJPEG_FMT_RGB24,
TINYJPEG_FMT_YUV420P,
TINYJPEG_FMT_YUV420ALL,//////////