数据压缩实验四:DPCM编码
2017-05-10 21:42
288 查看
一、基本原理
DPCM是典型的预测编码系统,采用负反馈的方式进行,由于解码端无法得到原始值,因此要用量化编码后的重建值来生成预测值,编码器中要内嵌解码器。DPCM编码框图如下:
Q为量化器,由于整个系统由预测+量化+熵编码构成,熵编码对形如Laplace分布的信源,有很好的压缩效果,因此量化部分采用均匀量化,能够保持预测误差的Laplace分布特性,在熵编码获得较高的编码效率,非均匀量化会把原本呈现Laplace分布特性的预测误差编程均匀分布,而熵编码所做的就是将非均匀分布的信源符号,变成均匀分布的码元符号,本身均匀分布的信源输入,不能得到好的压缩效果,而且非均匀分布实现更为复杂,所以对于预测+量化+熵编码的系统而言,均匀分布最为合适。
Laplace 分布
P为预测器,预测编码中,用几个样点的重建值的线性组合作为预测值,就是线性预测,用一个样点的重建值作为预测值就是DPCM,所以上图只用到前一个编码的像素的重建值。
xn:当前输入的像素值
4000
pn:当前像素值的预测值,由已经编码的某些像素的重建值经过一定的计算生成
dn:预测误差,当前像素值减去预测值
d^n:量化后的预测误差
x^n:当前像素的重建值=量化后的预测误差+当前像素的预测值
二、实验流程分析
1. 差分编码流程预测值:最左一列像素以128作为预测值,其他像素以左侧像素值作为预测值
量化:对原始值与预测值的差进行8bit量化
判断是否最左一列像素,若是,把像素值减去固定预测值128,否则减去预测值,得到范围在-255~255的预测误差
预测误差进行量化,8bit量化即用预测误差除以2,存入数据类型为float的qn,范围在-127.5~127.5
将qn抬高128,强制类型转换成无符号整数,存入输出预测误差图像的qBuf,范围在0~255
将刚存入的qBuf反量化,即减去128再乘以2,范围在-256~254,再加上第一步中减去的预测值,生成重建值,也即下一像素的预测值,存入输出重建图像的dBuf
2. 代码实现步骤
调用实验二BMP2YUV的程序,将BMP文件转成YUV格式
对YUV分量进行预测和量化,输出预测误差图像和重建图像,由于编码器中包含解码器,所以不需要单独做解码器来生成重建图像
把预测误差图像输入到实验三中的huffman代码中,进行熵编码
把原始图像输入到实验三中的huffman代码中,直接进行熵编码
将上两步编码的结果进行对比分析
三、关键代码分析
BMP2YUV及huffman编码的代码参考实验二和实验三,这里只给出差分编码的代码。1.定义相关变量
/**********定义bcpm变量及缓存***************/ FILE* qFile = NULL;//输出的预测误差图 FILE* dFile = NULL;//输出的重建图 char* qFileName = NULL;//预测误差图文件名 char* dFileName = NULL;//重建图文件名 float qn;//差值 u_int8_t*qBuf=NULL;//预测误差 u_int8_t*dBuf=NULL;//解码值
2.打开相关文件
/** open the quantizer outfile **/ qFile = fopen(qFileName, "wb"); if (qFile == NULL) { printf("cannot find quantizer outfile\n"); exit(1); } else { printf("The output quantizer outfile is %s\n", qFileName); } /** open the decode file **/ dFile = fopen(dFileName, "wb"); if (dFile == NULL) { printf("cannot find decode file\n"); exit(1); } else { printf("The output decode file is %s\n", dFileName); }
3.DPCM 编码
由于在调用的BMP2YUV的程序中已经将YUV文件的Y值和UV值分别压缩到16~235和16~240的范围,所以以下程序不会出现溢出。
8bit量化
for(i=0;i<frameWidth;i++)//对Y的预测编码 { for(j=0;j<frameHeight;j++) { if(j==0)//最左侧像素没有左侧像素,用128作为预测值 { qn=(yBuf[i*frameHeight+j]-128)/2;//当前像素值减去预测值128,进行8bit量化,即除以2 qBuf[i*frameHeight+j]=(u_int8_t)(qn+128);//qn的值在-127.5~127.5之间,将其抬高128,变成一字节无符号0~255,存入预测误差图像 dBuf[i*frameHeight+j]=((int)qBuf[i*frameHeight+j]-128)*2+128;//重建值等于量化后再反量化的值加上之前减去的预测值128,结果存入重建图像,反量化的值等于量化后的值减去128再乘以2,会出现负数,不会出现小数,所以先强制转换成int } else { qn=(yBuf[i*frameHeight+j]-dBuf[i*frameHeight+j-1])/2;//当前像素值减去预测值(左侧像素得重建值),进行8bit量化,即除以2 qBuf[i*frameHeight+j]=(u_int8_t)(qn+128);//qn的值在-127.5~127.5之间,将其抬高128,变成一字节无符号0~255,存入预测误差图像 dBuf[i*frameHeight+j]=((float)qBuf[i*frameHeight+j]-128)*2+dBuf[i*frameHeight+j-1];//重建值等于量化后再反量化的值加上之前减去的预测值128,结果存入重建图像,反量化的值等于量化后的值减去128再乘以2,会出现负数,不会出现小数,所以先强制转换成int } } } for (i = 0; i < frameWidth/2; i++)//对U的预测编码 { for(j = 0; j < frameHeight/2; j++) { if(j==0) { qn=(uBuf[i*frameHeight/2+j]-128)/2; qBuf[frameWidth * frameHeight+i*frameHeight/2+j]=(u_int8_t)(qn+128); dBuf[frameWidth * frameHeight+i*frameHeight/2+j]=((int)qBuf[frameWidth * frameHeight+i*frameHeight/2+j]-128)*2+128; } else { qn=(uBuf[i*frameHeight/2+j]-dBuf[frameWidth * frameHeight+i*frameHeight/2+j-1])/2; qBuf[frameWidth * frameHeight+i*frameHeight/2+j]=(u_int8_t)(qn+128); dBuf[frameWidth * frameHeight+i*frameHeight/2+j]=((float)qBuf[frameWidth * frameHeight+i*frameHeight/2+j]-128)*2+dBuf[frameWidth * frameHeight+i*frameHeight/2+j-1]; } } } for (i = 0; i < frameWidth/2; i++)//对V的预测编码 { for(j = 0; j < frameHeight/2; j++) { dfc2 if(j==0) { qn=(vBuf[i*frameHeight/2+j]-128)/2; qBuf[frameWidth * frameHeight*5/4+i*frameHeight/2+j]=(u_int8_t)(qn+128); dBuf[frameWidth * frameHeight*5/4+i*frameHeight/2+j]=((int)qBuf[frameWidth * frameHeight*5/4+i*frameHeight/2+j]-128)*2+128; } else { qn=(vBuf[i*frameHeight/2+j]-dBuf[frameWidth * frameHeight*5/4+i*frameHeight/2+j-1])/2; qBuf[frameWidth * frameHeight*5/4+i*frameHeight/2+j]=(u_int8_t)(qn+128); dBuf[frameWidth * frameHeight*5/4+i*frameHeight/2+j]=((float)qBuf[frameWidth * frameHeight*5/4+i*frameHeight/2+j]-128)*2+dBuf[frameWidth * frameHeight*5/4+i*frameHeight/2+j-1]; } } } fwrite(qBuf, 1, frameWidth * frameHeight *1.5, qFile); fwrite(dBuf, 1, frameWidth * frameHeight *1.5, dFile);
四、实验结果及分析
1.为了一致性,本实验用了BMP文件转换成的YUV文件作为原文件,来与重建图像和预测误差图像进行对比,表中xxxq.yuv为预测误差图像。表1
理论上,空间上相邻的像素值相差不大,因此预测误差的动态范围小,其概率分布呈现出离0(抬高后的128)越近越大的规律,这样的分布用huffman编码能得到很好的压缩比,上表显示Noise和Zone 原始文件的压缩比大于差分编码后的压缩比,与理论相悖,通过下面表二的概率分布和表三的图像,可以看到Noise和Zone,预测误差动态范围很宽,图像中黑白相间,0和255这样的极端值出现概率大,所以不易压缩。
2.原文件和预测误差图像的概率分布
原图像 | 预测误差图像 |
---|---|
从上表可以看出,右边一列的分布,基本是中间多两边少,动态范围小,说明了预测编码的效果。
3.重建图片与原始图片对比
原始图片 | 重建图片 | 预测误差图 |
---|---|---|
实验中采用左侧像素重建值作为预测值,因此上表最右列预测误差图像的灰色区域对应原图的平坦区域,即预测误差基本在0左右,抬高128后,在128左右呈现灰色,垂直边缘较明显,左黑右白的垂直边缘,会呈现出白色边缘,因为右侧白色减左侧黑色是一个比较大的正值,抬高128后也是128以上的一个比较大的值,同理,左白右黑的垂直边缘,会呈现出黑色边缘。
对-255~255范围的9bit预测误差做8bit量化,量化误差很小,因此中间一列的重建图像与左边一列的原始图像没有明显差别,量化误差可忽略不计。
五、总结
预测+均匀量化+熵编码的系统,通过预测得到近似Laplace分布预测误差,这是非常适合于熵编码的概率分布类型,对预测误差进行均匀量化可以降低编码的信源的符号种类,并且保持这样的概率分布,通过熵编码后达到较好的压缩效果。实验中,对运算过程中数据的动态范围要考虑,以便选择合适的数据类型,防止越界的情况出现。相关文章推荐
- 数据压缩实验4-DPCM编码
- 数据压缩实验一实验报告
- 数据压缩实验一:yuv转rgb
- 数据压缩实验2
- 数据压缩原理 实验四 DPCM压缩系统的实现和分析
- 数据压缩实验5-JEPG解码
- 李春葆数据结构上机实验指导书中矩阵压缩存储的一处错误
- 数据压缩原理实验2_实验报告
- 数据压缩实验二:bmp2yuv
- 数据压缩原理 实验三 Huffman编解码算法实现与压缩效率分析
- 数据压缩原理实验1_彩色空间转换实验YUVtoRGB
- 数据压缩原理与应用 图像文件的读写和转换(BMP2YUV)实验报告
- 数据压缩原理实验1_实验报告
- 数据压缩实验二:BMP2YUV文件转换
- 数据压缩实验二 图像文件的读写和转换(bmp转yuv)
- 数据压缩实验一——彩色空间转换
- 数据压缩实验1
- 数据压缩原理实验2_BMP2YUV文件转换
- 数据压缩原理实验3_Huffman编解码算法实现与压缩效率分析
- 数据压缩第二次实验报告——用C语言实现bmp to yuv的图片格式转化