test_04:DPCM 压缩实现

一:实验原理

1.DCPM编码原理
DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统。DCPM编码是对模拟信号幅度抽样的差值进行量化编码的调制方式,这种方式是用已经过去的抽样值来预测当前的抽样值,对它们的差值进行编码。在DPCM系统中,需要注意的是预测器的输入是已经解码以后的样本。之所以不用原始样本来做预测,是因为在解码端无法得到原始样本,只能得到存在误差的样本。因此,在DPCM编码器中实际内嵌了一个解码器,下面分别是编码器系统框图和解码器系统框图,可以看出,虚线框中框出的即为编码器中内嵌的解码器。
test_04:DPCM 压缩实现

上图中,xn为输入的信号,通过与预测值相减得到预测误差dn,dn经量化后得到d^n。d^n一方便送到信道进行传输,另一方面用于更新预测值。
在一个DPCM系统中,有两个因素需要设计:预测器和量化器。理想情况下,预测器和量化器应进行联合优化。实际中,采用一种次优的设计方法: 分别进行线性预测器和量化器的优化设计。本次实验中,采用固定预测器和均匀量化器。,预测器采用左侧预测,量化器采用8比特均匀量化,通过对一个256级的灰度图像(或者彩色图像的亮度部分)进行DPCM编码,验证DCPM编码的编码效率。

二:实验流程及代码分析

实验流程框图:

test_04:DPCM 压缩实现

关键代码分析:

本实验工程目录如下:
test_04:DPCM 压缩实现
Huffman编码器工程目录如下:(Huffman编码上一实验已给出,这里不再赘述)
test_04:DPCM 压缩实现
该DCPM编码实验主要包括一个主文件和一个rgb2yuv函数文件,是在实验2的基础上经添加相关代码,添加的代码下面将一一给出,rgb2yuv函数在之前实验2中已给出,这里不再赘述。
main.cpp文件中:
/*初始化变量*/
[cpp] view plain copy
  1. <span style="white-space:pre">      </span>//定义变量  
  2.         char* bmpFileName = NULL;  
  3.         char* yuvFileName = NULL;  
  4.         /*add by yangyulan*/  
  5.         char* yuv1FileName = NULL;//用于存储重建图像的文件  
  6.         char* qFileName = NULL;//用于存储量化误差图像的文件  
  7.         /*end by yangyulan*/  
  8.         bmpFileName = argv[1];  
  9.         yuvFileName = argv[2];  
  10.         /*add by yangyulan*/  
  11.         yuv1FileName = argv[3];  
  12.         qFileName =  argv[4];  
  13.         u_int8_t* q = NULL;//指向量化误差buffer的指针  
  14.         /*end by yangyulan*/  
  15.         u_int8_t* rgbBuf = NULL;  
  16.         u_int8_t* yBuf = NULL;  
  17.         u_int8_t* uBuf = NULL;  
  18.         u_int8_t* vBuf = NULL;  
/*打开文件*/
[cpp] view plain copy
  1. <span style="white-space:pre">      </span>/*add by yangyulan */  
  2.         FILE *yuv1File=  fopen(yuv1FileName, "ab");  
  3.         if (yuv1File  == NULL)   
  4.         {  
  5.             printf("can not find yuv file\n");  
  6.             exit(1);  
  7.         }  
  8.         FILE *qFile=  fopen(qFileName, "ab");  
  9.         if (qFile  == NULL)   
  10.         {  
  11.             printf("can not find q file\n");  
  12.             exit(1);  
  13.         }  
  14.         /*end by yangyulan*/  
/*开辟缓冲区*/
[cpp] view plain copy
  1. /*add by yangyulan*/  
  2.     q = (u_int8_t*)malloc(width*height);  
  3.       
  4.     /*end by yangyulan*/  
/*将原图像进行rgb2yuv处理并输出灰度文件后,进行如下DPCM编码处理*/
[cpp] view plain copy
  1. /*add by yangyulan*/  
  2.             for ( int i = 0; i < height; i++)  
  3.             {  
  4.                 float yp=128;//yp为预测值  
  5.                 for (int j = 0; j < width; j++)  
  6.                 {  
  7.                     float m=(float)*(yBuf+i*width+j)-yp;//差值  
  8.                     m/=2;//量化  
  9.                     *(q+i*width+j)=(u_int8_t)(m+128);//量化误差  
  10.                     //m*=2;//反量化  
  11.                     *(yBuf+i*width+j)=(u_int8_t)(m+yp);//重建后的样本  
  12.                     yp=(float)*(yBuf+i*width+j);//更新预测值  
  13.                 }  
  14.             }  
  15.           
  16.   
  17.                 //将重建后的值写入文件  
  18.                 fwrite(yBuf, 1, width*height, yuv1File);  
  19.   
  20.                 ++videoFramesWritten;  
  21.                 //将量化误差写入文件  
  22.                 fwrite(q,1,width*height,qFile);  
  23.             /*end by yangyulan*/  

三:实验结果

本实验经DCPM编码后共生成两个yuv文件:原图像文件,经DPCM编码后重建图像文件和量化误差文件。
原图像 预测误差图像 重建图像
test_04:DPCM 压缩实现 test_04:DPCM 压缩实现 test_04:DPCM 压缩实现
test_04:DPCM 压缩实现 test_04:DPCM 压缩实现 test_04:DPCM 压缩实现
     

从上图可以看出,经过DPCM编码之后的重建图像比未经编码的原图像质量有所下降,原因在于在对预测误差的8比特量化引起了量化误差。



图像文件(包括原图像和DPCM编码后的预测误差图像)经Huffman编码后的概率分布图和压缩比:
原图像 预测误差图像 原图像概率分布 预测误差图像概率分布 原图像压缩比 预测误差图像压缩比
test_04:DPCM 压缩实现 test_04:DPCM 压缩实现 test_04:DPCM 压缩实现 test_04:DPCM 压缩实现 2.220                               1.107                    
test_04:DPCM 压缩实现 test_04:DPCM 压缩实现 test_04:DPCM 压缩实现 test_04:DPCM 压缩实现 1.103 1.524
           
从上表可以看出,将经过DPCM编码的预测误差图像送入Huffman编码器,相对于未经DPCM编码的图像,其符号的概率分布更加集中,这表示可以用更加少的码字来进行编码,降低了平均码长,从而提高了压缩效率。

四:实验结论

1、经过DPCM编码,可以提高数据所占的比特数,降低所占内存,从而提高传输效率。但因为DPCM编码为有损编码,在进行量化的过程中会引入量化误差,因此相较于原图像,其图像质量会有所下降。
2、将图像进行DPCM有损编码后,送入到Huffman无损编码器,可以很大程度上降低平均码长,提高压缩效率。