实验原理
DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统。在DPCM系统中,需要注意的是预测器的输入是已经解码以后的样本。之所以不用原始样本来做预测,是因为在解码端无法得到原始样本,只能得到存在误差的样本。因此,在DPCM编码器中实际内嵌了一个解码器,如编码器中虚线框中所示。
在一个DPCM系统中,有两个因素需要设计:预测器和量化器。理想情况下,预测器和量化器应进行联合优化。实际中,采用一种次优的设计方法:分别进行线性预测器和量化器的优化设计。
实验流程及代码分析
本实验的目标是验证DPCM编码的编码效率。首先读取一个256级的灰度图像,采用左侧预测计算预测误差,并对预测误差进行右移操作。
具体流程
- 使用DPCM编码器输出预测误差图像和重建图像,将预测误差图像写入文件。
- 将该文件输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比。
- 将原始图像文件输入输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比。
- 比较两种系统(DPCM+熵编码和仅进行熵编码)之间的编码效率(压缩比和图像质量)
代码分析
需要三个缓冲区,原始样本xn、差分量化(哈夫曼输入)d^n、重建样本(解码图像)x^n。量化时,如果是第一列的像素,预测值固定为128,如果不是第一列的像素,当前的原始样本xn减去重建样本x^n,量化后存在d^n中,d^n反量化后加上上一个重建样本x^n存为x^n。
为了自定义量化比特数,加入变量Qbit量化比特数和scale差值压缩倍数。
DPCM编码部分代码
/* DPCM encoding */
/* rebuild & diffrential file */
FILE* rebuildFile = NULL;
FILE* diffFile = NULL;
if ((rebuildFile = fopen(argv[], "wb+")) == NULL)
{
printf("yuv rebuild file failed!");
exit();
}
if ((diffFile = fopen(argv[], "wb+")) == NULL)
{
printf("yuv differential file failed!");
exit();
}
/* buffer */
unsigned char* inBuf = NULL;
unsigned char* dBuf = NULL;
unsigned char* reBuf = NULL;
inBuf = (unsigned char *)malloc(height*width);
dBuf = (unsigned char *)malloc(height*width);
reBuf = (unsigned char *)malloc(height*width);
inBuf = yBuff;
// only have to free either one of them
/* quantify setting */
const long Qbit = ;
long scale = / ( << Qbit);
/* avoid overflow */
long temp;
/* differentiate & quantify & rebuild */
for(i=;i<height;i++)
{
for(j=;j<width;j++)
{
if(!j)
{
*(dBuf + i*width + j) = ((*(inBuf + i*width + j) - + ) / scale) ;
temp = (((*(dBuf + i*width + j) - ( / scale)) * scale) + ) ;
if (temp > )
temp = ;
else if (temp < )
temp = ;
*(reBuf + i*width + j) = temp;
}
else
{
*(dBuf + i*width + j) = ((*(inBuf + i*width + j) - *(reBuf + i*width + j - ) + ) / scale) ;
temp = (((*(dBuf + i*width + j) - ( / scale)) * scale) + *(reBuf + i*width + j - ));
if (temp > )
temp = ;
else if (temp < )
temp = ;
*(reBuf + i*width + j) = temp ;
}
*(dBuf + i*width + j) = *(dBuf + i*width + j) * scale / ;
}
}
fwrite(reBuf, , width * height, rebuildFile);
fwrite(dBuf, , width * height, diffFile);
实验结论
原始图像 | 预测误差图像 | 重建图像 | 预测频率分布 |
---|---|---|---|
压缩比计算
图像 | 原始图像大小 | 熵编码图像大小(压缩比) | 预测误差+熵编码图像大小(压缩比) |
---|---|---|---|
Birds | 384 | 347(1.11) | 158(2.43) |
Camman | 64 | 53(1.21) | 33(1.94) |
Lena | 64 | 61(1.05) | 38(1.68) |
Noise | 64 | 55(1.16) | 62(1.03) |
Zone | 64 | 51(1.25) | 61(1.05) |
对前三个正常图像,经DPCM的压缩比较不进行DPCM的压缩比更大,对后两个随机噪声和高频图像,经DPCM的压缩比反而更小,因为它们像素间几乎没有关联,所以DPCM对像素间有关联的正常图像可以进行数据压缩。
改变量化比特数
量化比特数 | 预测误差图像 | 重建图像 | 预测频率分布 |
---|---|---|---|
8 | |||
7 | |||
6 | |||
5 | |||
4 | |||
3 | |||
2 |
对于降低量化比特数后的预测误差图像,采用如下操作使其范围均衡化到0~255的范围,方便观察,若不进行均衡化,4比特以下的预测误差图像像素值很低,将是一片漆黑(颤抖吧)。
*(dBuf + i*width + j) = *(dBuf + i*width + j) * scale / ;
另外在试验中还需要注意,重建图像的像素值有可能溢出(实际是在4bit以下量化是发生溢出)。所以需要对重建图像像素值上下限进行限制,即代码中引入的temp变量。