数据压缩实验JPEG

实验目的

  1. 掌握JPEG编解码系统的基本原理。
  2. 初步掌握复杂的数据压缩算法实现,并能根据理论分析需要实现所对应数据的输出。

实验原理

1.编码原理

基本流程:
1.亮度信号零偏置电平下移,对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成是有符号数。这样做的目的是使像素的绝对值出现3位10进制的概率大大减少。
2.DCT变换
对每个单独的彩色图像分量,把整个分量图像分成8×8的图像块,并进行8×8DCT变换,目的是去除图像数据的相关性,便于量化过程去除图像数据的空间冗余。
3.量化
利用人眼视觉特性设计而成的矩阵量化DCT系数,减小视觉冗余。因为人眼对亮度信号比色差信号更敏感,因此使用了两种量化表:亮度量化值和色差量化值;根据人眼对低频敏感,对高频不太敏感,对低频分量采取较细的量化,对高频分量采取较粗的量化。
4.熵编码
(1)对量化后的DC系数进行差分编码
8×8图像块经过DCT变换之后得到的DC直流系数有两个特点:系数的数值较大;相邻8×8图像块的DC系数值变化不大。根据这个特点,JPEG算法使用了差分脉冲调制编码(DPCM)技术对相邻图像块之间量化DC系数的差值进行编码。
(2)AC系数进行Z字扫描和游程编码后,再分别进行VLC编码
Z字扫描:由于DCT变换后,系数大多数集中在左上角,即低频分量区,因此采用Z字形按频率的高低顺序读出,可以出现很多连零的机会,可以使用游程编码。
游程编码:在JPEG和MPEG编码中规定为(run,level):表示连续run个0,后面跟值为level的系数。
2.JPEG文件格式
JPEG 在文件中以 Segment 的形式组织,它具有以下特点:
均以 0xFF 开始,后跟 1 byte 的 Marker 和 2 byte 的 Segment length(包含表示 Length 本身所占用的 2 byte,不含“0xFF” + “Marker” 所占用的 2 byte);
采用 Motorola 序(相对于 Intel 序),即保存时高位在前,低位在后;
Data 部分中,0xFF 后若为 0x00,则跳过此字节不予处理;

3.量化表DQT
一般为两个量化表,即亮度和色度各一张
以0xFFDB开始
➢量化表长度,一般为00 43(或00 84)
➢量化表信息(1字节)
◼ Bit 0~3 QT号(只能取值为0~3,否则错误)
◼ Bit 4~7 QT精度(0为8比特,否则表示16比特)
量化表的实际数据
◼ 量化表中的数据按照Z字形保存量化表内8x8的数
4.帧图像开始SOF0

 5.一个或多个Huffman表,数值0xFF C4

实验步骤

1.调试JPEG编码器,解码输入的JPEG文件并将文件输出至YUV格式
对解码器输入参数 test1.jpg yuv420p test1.yuv
将文件保存至YUV格式
原始程序中文件会分别保存为.Y .U .V三个独立文件,在函数write_yuv(const char *filename, int width, int height, unsigned char **components)中添加如下代码:
 

snprintf(temp, 1024, “%s.YUV”, filename); //输出一个完整的YUV文件
F = fopen(temp, “wb”);
fwrite(components[0], width, height, F);
fwrite(components[1], width * height / 4, 1, F);
fwrite(components[2], width * height / 4, 1, F);
fclose(F);

2.理解三个结构体的含义

struct huffman_table
目的:储存解码所用的Huffman码表,codesize储存码长


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
目的:存储每个88系数块信息,用于该系数块的解码,包含DC、AC Huffman码表,量化表,色度采样格式和88DCT系数。其中DC系数采用差分编码。

struct component 
{
  unsigned int Hfactor;  /* Horizontal factor */
  unsigned int Vfactor;  /* Vertical factor */
  /** 每个component 的Hfactor 和 Vfactor共同决定色度采样格式 **/

  float *Q_table;		/* Pointer to the quantisation table to use */
  struct huffman_table *AC_table;  /* Pointer to the AC table to use */
  struct huffman_table *DC_table;  /* Pointer to the DC table to use */
  /* 量化表、Huffman表均为指针,指向结构体jdec_private中实际数据 */

  short int previous_DC;	/* Previous DC coefficient */
  short int DCT[64];		/* DCT coef */
#if SANITY_CHECK
  unsigned int cid;
#endif
};

 struct jdec_private
目的:存储Jpeg图片的基本尺寸信息、数据、量化表、Huffman表

struct jdec_private
{
  /* Public variables */
  uint8_t *components[COMPONENTS];  
  /* 指针数组,指向3个分量数据 */

  unsigned int width, height;	/* 图片尺寸 */
  unsigned int flags;  

  /* Private variables */
  const unsigned char *stream_begin, *stream_end;  
  unsigned int stream_length;
  /* stream_begin指示文件在内存中起始地址,stream_end指示结束地址, stream_length 指示除去0xFF和0xD8(SOI)两字节文件长度 */

  const unsigned char *stream;	/* Pointer to the current stream */
  unsigned int reservoir, nbits_in_reservoir;

  struct component component_infos[COMPONENTS];
  float Q_tables[COMPONENTS][64];		/* quantization tables */
  struct huffman_table HTDC[HUFFMAN_TABLES];	/* DC huffman tables   */
  struct huffman_table HTAC[HUFFMAN_TABLES];	/* AC huffman tables   */
  int default_huffman_table_initialized;
  int restart_interval;
  int restarts_to_go;				/* MCUs left in this restart interval */
  int last_rst_marker_seen;			/* Rst marker is incremented each time */

  /* Temp space used after the IDCT to store each components */
  uint8_t Y[64*4], Cr[64], Cb[64];

  jmp_buf jump_state;
  /* Internal Pointer use for colorspace conversion, do not modify it !!! */
  uint8_t *plane[COMPONENTS];
};

3.以txt文件输出所有的量化矩阵和所有的HUFFMAN码表
4.输出DC图像并统计其概率分布;输出某一个AC值图像并统计其概率分布
选取DCT系数矩阵中(4,4)位置进行统计,结果如下:

原图像 

  

原图灰度直方图

由结果可以看出,由每个8*8DCT块中直流分量组成的图像分布近似于原图灰度直方图分布,而某一交流分量分布近似于拉普拉斯分布。其结果与理论相符 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值