本文主要是介绍数据压缩 JPEG解码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
JPEG解码
实验原理
JPEG压缩编码基本原理
JPEG(Joint Photographic Experts Group)是在国际标准化组织(ISO)领导之下制定静态图像压缩标准的委员会,第一套国际静态图像压缩标准ISO 10918-1(JPEG)就是该委员会制定的。由于JPEG优良的品质,使他在短短几年内获得了成功,被广泛应用于互联网和数码相机领域,网站上80%的图像都采用了JPEG压缩标准。
JPEG编码算法主要有以下一个重要步骤:
(1)对DCT去除图像数据的空间冗余;
(2)用人眼视觉最佳效果的量化表来量化DCT系数F(u,v),去除视觉冗余;
(3)对量化后的DCT系数F(u,v)数据进行熵编码,去除熵冗余。
JPEG编码原理图
- 预处理
- 像块分割
把源图像分割成互相不重叠矩形块,每一个像块作为一个独立的单元进行变化和编解码。JPEG的像块大小为8×8,各像素数据值分布比较均匀,像素件的相关性较强。
- 零偏置(Level Offset)
对于灰度级是2n的像素,通过减去2n-1,将无符号 的整数值变成有符号数。 对于n=8,即将0~255的值域,通过减去128,转换为值 域在-128~127之间的值 目的:使像素的绝对值出现3位10进制的概率大大 减少
- 像块分割
- DCT
性质:
(1)能量守恒
(2)能量集中
(3)去相关
经过DCT变换后,图像中的低频分量会集中在左上角,由于图像低频能量高,故而左上角数值大,右下角有较多的0值。
- 量化
(1)根据人眼的视觉特性(对低频敏感,对高频不太敏感)对 低频分量采取较细的量化,对高频分量采取较粗的量化。
-> 如果原始图象中细节丰富,则去掉的数据较多,量化后的系数与 量化前差别
->反之,细节少的原始图象在压缩时去掉的数据少些
(2)因为人眼对亮度信号比对色差信号更敏感,因此使用了两 种量化表:亮度量化值和色差量化值 。 - 之字形扫描
由于量化之后右下角高频系数大部分为0,在编码是为了制造更长的0游程提高编码效率,采用之字形扫描读取法。经过之字形扫描读出后把二维系数矩阵转换为一维数据序列。在最后, 如果都是零,给出 EOB (End of Block) 即可。
zig-zag序
- DC系数的差分编码
由于直流系数F(0,0)代表了该像块中包含的直流成分,数值较大,又由于两个相邻像块的直流系数通常具有较大的相关性,所以对DC系数采用差分编码(DPCM),传送当前快与前一个块之间的DC系数差值。
码字=类别ID+类内索引
类别ID同时也是解码类内索引时,还需读几位的码流,存在DC系数Huffman码表的权值中。
例:DC=8,上一DC=5,则DIFF=8-5=3 类别ID=2,类内索引=3,则码流=10011 - AC系数的游程编码
编码规则:(run,level)
表示连续run个0,后面跟着值为level的AC系数。
- run:最多15个,故用4位表示。
- level:类似DC系数,分为类别ID与类内索引。用4位表示类别ID。
(run,level的类别ID)合成1字节存在AC系数码表的权值中。
JPEG文件格式
英文缩写 | 英文全称 | 说明 | 标志代码 |
---|---|---|---|
SOI | Start of Image | 图像开始 | 0xFFD8 |
APPn | Application | 应用程序保留标记n | 0xFFEn |
DQT | Define Quantization Table | 定义量化表 | 0XFFDB |
SOF0 | Start of Frame | 帧图像开始 | 0xFFC0 |
DHT | Define Huffman Table | 定义哈夫曼表 | 0xFFC4 |
SOS | Start of Scan | 扫描开始,12字节 | 0xFFDA |
EOI | End of Image | 图像结束,2字节 | 0xFFD9 |
1.DQT量化表
(1)标记代码:0xFFDB
(2)数据长度:2字节 包括字段(2)和多个字段(3)总长度。
(3)量化表:
① 精度及量化表ID 1字节
高4位:精度,只有两个可选值 0:8位;1:16位
②表项 (64×(精度+1))字节
2.DHT哈夫曼表
(1)标记代码:0xFFC4
(2)数据长度:2字节
(3)huffman表
- 表ID和表类型:1字节
高4位:类型,只有两个值可选( 0:DC直流;1:AC交流 )
低4位:哈夫曼表ID(注意,DC表和AC表分开编码)
- 不同位数的码字数量:16字节
- 编码内容
16个不同位数的码字数量之和(字节)本标记段中,字段(3)可以重复出现(一般4次),也可以只出现1次。
在DC系数码表中,此项为权值,其权值就是解码时再需要 读入的bit位数。这个再次读入的位数通过查表得到真正的 码值。
在AC系数码表,权值的高4位表示当前数值前面有多少个连续的零,低4 位表示该交流分量数值的二进制位数,也就是接下来需要 读入的位数。
JPEG解码是编码的逆过程。
实验流程
1.逐步调试JPEG解码器程序。将输入的JPG文件进行解码,将输出文件保存为可供
YUVViewer观看的YUV文件。
2. 程序调试过程中,应做到:
- 理解程序设计的整体框架
- 理解三个结构体的设计目的
struct huffman_table
struct component
struct jdec_private
- 理解在视音频编解码调试中TRACE的目的和含义
- 会打开和关闭TRACE
- 会根据自己的要求修改TRACE
3. 以txt文件输出所有的量化矩阵和所有的HUFFMAN码表。
4. 输出DC图像并经过huffman统计其概率分布(使用第三个实验中的Huffman编码器)。
5. 输出某一个AC值图像并统计其概率分布(使用第三个实验中的Huffman编码器)。
代码分析
1.理解三个结构体
struct jdec_private处在最上层,支配整个图像,其中包含了struct huffman_table和 struct component。其中struct huffman_table用来存放DC系数、AC系数的哈夫曼码表;struct component 用来存放8*8数据块组成的MCU(Minimum Data Unit,最小数据单元)数据值,相当于移动的像块,每次访问下一个像块就给该结构体更新值。
struct huffman_table
{/* Fast look up table, using HUFFMAN_HASH_NBITS bits we can have directly the symbol,* if the symbol is <0, then we need to look into the tree table */short int lookup[HUFFMAN_HASH_SIZE];/* code size: give the number of bits of a symbol is encoded */unsigned char code_size[HUFFMAN_HASH_SIZE];/* some place to store value that is not encoded in the lookup table * FIXME: Calculate if 256 value is enough to store all values*/uint16_t slowtable[16-HUFFMAN_HASH_NBITS][256];
};struct component
{unsigned int Hfactor;//水平采样因子unsigned int Vfactor;//垂直采样因子float *Q_table; /* Pointer to the quantisation table to use */struct huffman_table *AC_table;struct huffman_table *DC_table;short int previous_DC; /* Previous DC coefficient */short int DCT[64]; /* DCT coef */
#if SANITY_CHECKunsigned int cid;
#endif
};//Frage stellen von susu
这篇关于数据压缩 JPEG解码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!