实验目的
掌握DPCM编解码系统的基本原理。初步掌握实验用C/C++/Python等语言编程实现DPCM编码器,并分析其压缩效率。
实验内容
- DPCM编解码原理
- DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统。在DPCM系统中,需要注意的是预测器的输入是已经解码以后的样本。之所以不用原始样本来做预测,是因为在解码端无法得到原始样本,只能得到存在误差的样本。因此,在DPCM编码器中实际内嵌了一个解码器,如编码器中虚线框中所示。
- 在一个DPCM系统中,有两个因素需要设计:预测器和量化器。理想情况下,预测器和量化器应进行联合优化。实际中,采用一种次优的设计方法:分别进行线性预测器和量化器的优化设计。
- DPCM编码系统的设计
- 在本次实验中,我们采用固定预测器和均匀量化器。预测器采用左侧、上方预测均可。量化器采用8比特均匀量化。本实验的目标是验证DPCM编码的编码效率。首先读取一个256级的灰度图像,采用自己设定的预测方法计算预测误差,并对预测误差进行8比特均匀量化(基本要求)。还可对预测误差进行1比特、2比特和4比特的量化设计(提高要求)。
- 在DPCM编码器实现的过程中可同时输出预测误差图像和重建图像。将预测误差图像写入文件并将该文件输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比。将原始图像文件输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比。最后比较两种系统(1.DPCM+熵编码和2.仅进行熵编码)之间的编码效率(压缩比和图像质量)。压缩质量以PSNR进行计算。
实验步骤
核心代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
#include <string.h>
#include"DPCM.h"
//向左
void DPCMLeft(int Width,int Height,void *yBuff,void *recBuff,void *errBuff)
{
unsigned char *yB=NULL;
yB = (unsigned char *)yBuff;
unsigned char *recB=NULL;
recB = (unsigned char *)recBuff;
unsigned char *errB=NULL;
errB = (unsigned char *)errBuff;
int P1,P2;
unsigned char P3;
for(int i=0;i<Height;i++)
{
for(int j=0;j<Width;j++)
{
if(j == 0)
{
*(recB+j+i*Width)=*(yB+j+i*Width);
*(errB+j+i*Width)=0;
}
else
{
P1=*(yB+j+i*Width)-*(recB+(j-1)+i*Width);
if(P1%2==0)
P2=P1/2+128;
else
P2=(P1-1)/2+128;
*(errB+j+i*Width)=unsigned char(P2);
P3=unsigned char(P2*2);
*(recB+j+i*Width)=*(recB+(j-1)+i*Width)+P3;
}
}
}
}
int simplest_yuv420_psnr(void *yBuff1,void *yBuff2, int w, int h, int num)
{
unsigned char *yB1=NULL;
yB1 = (unsigned char *)yBuff1;
unsigned char *yB2=NULL;
yB2 = (unsigned char *)yBuff2;
for (int i = 0; i < num; i++)
{
double mse_sum = 0, mse = 0, psnr = 0;
for (int j = 0; j < h ; j++)
{
for (int k = 0; k < w; k++)
{
mse_sum += pow((double)(*(yB1+k+j*w) - *(yB2+k+j*w)), 2);
}
}
mse = mse_sum / (w * h);
psnr = 10 * log10(255.0 * 255.0 / mse);
printf("%5.3f\n", psnr);
}
system("pause");
return 0;
}
结果截图