JPEG原理分析及JPEG解码器的调试

实验目的

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

方法解释

JPEG文件格式

在这里插入图片描述

SOI

在这里插入图片描述

APP0

在这里插入图片描述

DQT

在这里插入图片描述

SOF0

在这里插入图片描述

DHT

在这里插入图片描述

SOS

在这里插入图片描述

EOI

在这里插入图片描述

JPEG编码原理

在这里插入图片描述

零偏置(Level Offset)

        对于灰度级是2n的像素,通过减去2n-1,将无符号的整数值变成有符号数。
                对于n=8,即将0 ~ 255的值域,通过减去128,转换为
                值域在-128~127之间的值。
        目的:使像素的绝对值出现3位10进制的概率大大减少

DCT变换

对每个单独的彩色图像分量,把整个分量图像分成8×8的图像块,如图所示,并作为两维离散余弦变换DCT的输入。
在这里插入图片描述

量化

根据人眼的视觉特性(对低频敏感,对高频不太敏感)对低频分量采取较细的量化,对高频分量采取较粗的量化
在这里插入图片描述

对DC系数编码

DC系数的差分编码

根据这个特点,JPEG算法使用了差分脉冲调制编码(DPCM)技术,对相邻图像块之间量化DC系数的差值DIFF进行编码:
在这里插入图片描述

DC系数的熵编码(huffman编码)

对DIFF用Huffman编码:分成类别,类似指数Golomb编码
➢类别ID:一元码编码
➢ 类内索引:采用定长码
在这里插入图片描述

对AC系数编码

AC系数的Z字扫描

由于经DCT变换后,系数大多数集中在左上角,即低频分量区,因此采用Z字形按频率的高低顺序读出,可以出现很多连零的机会。可以使用游程编码。尤其在最后,如果都是零,给出EOB (End of Block)即可。
在这里插入图片描述

AC系数的游程编码、熵编码(huffman编码)

在这里插入图片描述在这里插入图片描述

实验步骤

1.逐步调试JPEG解码器程序。将输入的JPG文件进行解码,将输出文件保存为可供YUVViewer观看的YUV文件。

参数项目设置
在这里插入图片描述
修改load.jpeg中的write_yuv函数,添加注释代码以输出yuv文件

/**
 * Save a buffer in three files (.Y, .U, .V) useable by yuvsplittoppm
 */
static void write_yuv(const char* filename, int width, int height, unsigned char** components)
{
   
   
    FILE* F;
    char temp[1024];

    snprintf(temp, 1024, "%s.Y", filename);
    fopen_s(&F,temp, "wb");
    fwrite(components[0], width, height, F);
    fclose(F);
    snprintf(temp, 1024, "%s.U", filename);
    fopen_s(&F,temp, "wb");
    fwrite(components[1], width * height / 4, 1, F);
    fclose(F);
    snprintf(temp, 1024, "%s.V", filename);
    fopen_s(&F,temp, "wb");
    fwrite(components[2], width * height / 4, 1, F);
    fclose(F);
    
	//输出yuv文件
    snprintf(temp, 1024, "%s.yuv", filename);
    fopen_s(&F, 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);

}

输入test.jpg如下图
在这里插入图片描述
输出test.yuv,并用YUV viewer打开
在这里插入图片描述
在这里插入图片描述

2. 程序调试过程中,应做到:

理解程序设计的整体框架

理解三个结构体的设计目的

struct huffman_table

存储Huffman码表

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

储存8×8图像块中解码用表的信息

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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值