实验原理
1.预测编码
利用信源相邻符合之间的相关性,根据某一模型利用以往的样本值对新样本进行 预测,然后将样本的实际值与其预测值相减得到一个误差值,最后对这一误差值进行编码。如果模型足够好,且样本序列在时间上相关性 较强,则误差信号的幅度将远远小于原始信号 ,从而得到较大的数据压缩。
2.DPCM
DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统。
在本次DPCM中,只将前一个像素的值当作预测值,再取当前的像素值和预测值之差进行编码。由于当前值和预测值之间有较强的相关性,所以预测误差的可能取值范围比抽样值的范围小,因此对预测误差进行编码,可以减少编码的比特率。
DPCM是一种负反馈的系统,采用后向自适应的框架进行设计。在DPCM系统中,需要注意的是预测器的输入是已经解码以后的重建样本。之所以不用原始样本来做预测,是因为在解码端无法得到原始样本,只能得到存在误差的样本。因此,在DPCM编码器中实际内嵌了一个解码器,如编码器中虚线框中所示。
x(n)为当前像素的原始值,d(n)为预测误差,p(n)为当前像素的预测值,d*(n)为经过量化后的误差值。
在一个DPCM系统中,有两个因素需要设计:预测器和量化器。理想情况下,预测器和量化器应进行联合优化。实际中,采用一种次优的设计方法:分别进行线性预测器和量化器的优化设计。
实验流程
本实验的目标是验证DPCM编码的编码效率。在本次实验中,我们采用固定预测器和均匀量化器。
1.首先读取一个256级的灰度图像
2.采用自己设定的预测方法计算预测误差,本实验中预测器采用左侧预测。
3.对预测误差进行8比特均匀量化
关键代码
读取256级的灰度图像
该步骤与第二次试验的bmp2yuv相同,在此不再赘述。只是本次实验中,仅读出yuv文件中的亮度值即y的值。
开辟三个缓冲区
1.yBuf用于存储原始样本
yBuffer用于给指针指向的内容赋值
u_int8_t* yBuf = NULL;
u_int8_t* yBuffer = NULL;
yBuf = (u_int8_t*)malloc(frameWidth * frameHeight);
yBuffer = yBuf;
2.buildBuf用于存储重建样本
buildBuffer用于给指针指向的内容赋值
u_int8_t* buildBuf = NULL;
u_int8_t* buildBuffer = NULL;
buildBuf = (u_int8_t*)malloc(frameWidth * frameHeight);
buildBuffer = buildBuf;
3.errorBuf用于存储预测误差
errorBuffer用于给指针指向的内容赋值
u_int8_t* errorBuf = NULL;
u_int8_t* errorBuffer = NULL;
errorBuf = (u_int8_t*)malloc(frameWidth * frameHeight);
errorBuffer = errorBuf;
DPCM编码及量化过程的实现
在本程序中取所有像素的左侧像素作为预测,将整幅画面第一列的预测值均设置为128,得到的预测误差范围为-255~+255,为9比特。首先对其进行8比特量化,及对其进行除2并且下取整,因此量化后其误差范围变为-127~127,为了存储预测误差,将其范围变为0~255,因此在量化的基础上+128。将量化后的误差进行反量化,在加上预测值,得到对应像素的重建值。而这一重建值应作为下一像素的预测值进行新一轮的预测编码。
具体程序实现如下:
for (i = 0; i < frameHeight; i++)
{
for (j = 0; j < frameWidth; j++)
{
if (j == 0)
{
*errorBuffer = ((*yBuffer - 128)/ 2 + 128);
*buildBuffer = 128 + (*errorBuffer - 128) * 2;
errorBuffer++;
yBuffer++;
buildBuffer++;
}
else
{
*errorBuffer = (*yBuffer - *(buildBuffer - 1)) / 2 + 128;
*buildBuffer = *(yBuffer - 1) + (*errorBuffer - 128) * 2;
errorBuffer++;
yBuffer++;
buildBuffer++;
}
}
}
实验结果
build*.yuv为重建后的图像,.yuv为原始图像,error.yuv为预测误差生成的图像。
将预测误差图像写入文件并将该文件输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比。
预测误差图像 | 概率分布 | 压缩比 |
---|---|---|
自定义1 | 2.37 | |
自定义2 | 2.37 | |
birds | 2.49 | |
Camman256B | 1.94 | |
Clown256B | 1.94 | |
Fruit256B | 1.88 | |
Lena256B | 1.68 | |
Noise256B | 1.03 | |
Odie | 6.4 | |
errorZone256B | 1.03 |
当文件的预测误差集中在0附近时,进行DPCM编码和熵编码后,图像的压缩率就会越高。而当遇到噪声分布这一类相邻亮度值相差都很大的图像时,预测误差的范围很大,因此对其进行预测误差编码并不能起到很好的压缩的作用。
将原始图像文件输入输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比
原始图像文件 | 概率分布 | 压缩比 |
---|---|---|
自定义1 | 1.73 | |
自定义2 | 1.56 | |
birds | 1.11 | |
Camman256B | 1.21 | |
Clown256B | 1.03 | |
Fruit256B | 1.05 | |
Lena256B | 1.05 | |
Noise256B | 1.16 | |
Odie | 6.4 | |
errorZone256B | 1.25 |
通过比较比较两种系统(DPCM+熵编码和仅进行熵编码)之间的编码效率可以看出,一幅图像相邻像素的相关性越大,预测误差的值就越集中在0附近,压缩比就越大,压缩效率就越高,此时经过Dpcm编码再进行熵编码,其压缩效率就高于仅进行熵编码的压缩效率,而当图像相邻像素的相关性越小,预测误差的范围越大,此时经过Dpcm编码再进行熵编码,其压缩效率就低于仅进行熵编码的压缩效率。