DPCM压缩系统的实现和分析
文章目录
一、实验原理
DPCM是差分预测编码调制的缩写,本次实验采用固定预测器和均匀量化器,预测器采用前向预测。其中xn为输入信号,Q为量化器,dn=pn+xn为预测误差,P为延时器。
大致算法步骤如下:
读取一个256级的灰度图像,与前一个像素作差得到预测误差,范围为[-255,255]。
需要将其范围转变为计算机可以表示的范围,先转变为单极性,即加上255,范围变为[0,510]。
进行8bit均匀量化。
二、实验步骤
1.主函数读写文件
int main(void)
{
int bits_depth = 8;
unsigned char* yBuf, * uBuf, * vBuf;
int w = 256, h = 256;
yBuf = (unsigned char*)malloc(sizeof(unsigned char) * (w * h));
uBuf = (unsigned char*)malloc(sizeof(unsigned char) * (w * h / 4));
vBuf = (unsigned char*)malloc(sizeof(unsigned char) * (w * h / 4));
FILE* src = NULL;
src = fopen("Lena256B.yuv", "rb");
if (src == NULL)
{
printf("error opening source file!\n");
system("pause");
exit(-1);
}
fread(yBuf, sizeof(unsigned char), w * h, src);
fread(uBuf, sizeof(unsigned char), w * h / 4, src);
fread(vBuf, sizeof(unsigned char), w * h / 4, src);
fclose(src);
unsigned char* qBuf, * reBuf;
qBuf = (unsigned char*)malloc(sizeof(unsigned char) * (w * h));//预测误差buffer
reBuf = (unsigned char*)malloc(sizeof(unsigned char) * (w * h));//重构图像buffer
dpcm(yBuf, qBuf, reBuf, w, h, bits_depth);
FILE* obj1 = NULL;
FILE* obj2 = NULL;
obj1 = fopen("q_Lena256B.yuv", "wb");
obj2 = fopen("re_Lena256B.yuv", "wb");
if (obj1 == NULL || obj2 == NULL)
{
printf("error opening objective file!\n");
system("pause");
exit(-1);
}
fwrite(qBuf, sizeof(unsigned char), w * h, obj1);
fwrite(uBuf, sizeof(unsigned char), w * h / 4, obj1);
fwrite(vBuf, sizeof(unsigned char), w * h / 4, obj1);
fwrite(reBuf, sizeof(unsigned char), w * h, obj2);
fwrite(uBuf, sizeof(unsigned char), w * h / 4, obj2);
fwrite(vBuf, sizeof(unsigned char), w * h / 4, obj2);
fclose(obj1);
fclose(obj2);
2.进行DPCM
void dpcm(unsigned char* yBuf, unsigned char* qBuf, unsigned char* reBuf, int w, int h, int depth)
{
int r = pow(2, (double)(9 - depth));
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
{
if (j == 0)//第一列保持原样值不变
{
qBuf[i * w] = ((yBuf[i * w] - 128) + 255) / pow(2, (double)(9 - depth));//预测误差量化
reBuf[i * w] = qBuf[i * w] * pow(2, (double)(9 - depth)) + 255 - 128;//反量化
}
else
{
qBuf[i * w + j] = ((yBuf[i * w + j] - reBuf[i * w + j - 1]) + 255) / pow(2, (double)(9 - depth));//当前预测误差为当前样值与上个重构样值的差值(量化后)
reBuf[i * w + j] = qBuf[i * w + j] * pow(2, (double)(9 - depth)) - 255 + reBuf[i * w + j - 1];//当前重构样值为量化后的当前预测误差与上一个重构样值的和
}
if (qBuf[i * w + j] > 255)
qBuf[i * w + j] = 255;
if (qBuf[i * w + j] < 0)
qBuf[i * w + j] = 0;
if (reBuf[i * w + j] > 255)
reBuf[i * w + j] = 255;
if (reBuf[i * w + j] < 0)
reBuf[i * w + j] = 0;
}
}
3.计算概率分布
//计算分布概率
double fre_q[256] = { 0 };
double fre_org[256] = { 0 };
for (int i = 0; i < 256; i++)
{
int count_q = 0, count_org = 0;
for (int j = 0; j < w * h; j++)
{
if ((int)qBuf[j] == i)
count_q++;
if ((int)yBuf[j] == i)
count_org++;
}
fre_q[i] = (double)count_q / w / h;
fre_org[i] = (double)count_org / w / h;
}
char s[] = "symbol\tfrequency\n";
FILE* data_q = fopen("q_Lena256B.txt", "w");
FILE* data_org = fopen("org_Lena256B.txt", "w");
if (data_q == NULL || data_org == NULL)
{
printf("error opening txt file!\n");
system("pause");
exit(-1);
}
fprintf(data_org, s);
fprintf(data_q, s);
for (int i = 0;i < 256; i++)
{
fprintf(data_q, "%d\t%f\n", i, fre_q[i]);
fprintf(data_org, "%d\t%f\n", i, fre_org[i]);
}
fclose(data_q);
fclose(data_org);
3.计算PSNR
//计算PSNR
int max = 255;
double mse = 0;
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
{
mse += (yBuf[i * w + j] - reBuf[i * w + j]) * (yBuf[i * w + j] - reBuf[i * w + j]);
}
mse = (double)mse / (double)(w * h);
double psnr = 10 * log10((double)(max * max) / mse);
cout << "PSNR = " << psnr;
system("pause");
三、实验结果
1.图像
8bit 量化时,原图像、预测误差图像、重建图像如下:
原图像、2bit、4bit、8bit量化的重建图像
2.PSNR结果
PSNR | 2bit | 4bit | 8bit |
---|---|---|---|
Lena.yuv | 7.66699 | 14.6621 | 50.9301 |
PSNR随量化bit数增加而增大,重建图像质量也越好。
3.概率分布曲线
原图:
量化误差图像概率分布曲线:
8bit
4bit
2bit
4.用huffcode对量化误差图像进行压缩
使用Huffcode.exe处理量化误差图像后,图像被压缩。
图像 | 压缩前(yuv)kb | 压缩后(huff)kb | 压缩比 |
---|---|---|---|
Lena256B.yuv | 96 | 69 | 71.86% |
Lena256B.yuv(8bit) | 96 | 46 | 47.92% |
Lena256B.yuv(4bit) | 96 | 24 | 25.00% |
Lena256B.yuv(2bit) | 96 | 23 | 23.96% |
可见进行DPCM编码后的图像再进行熵编码,比仅熵编码的图像数据量小,且量化比特数越大,压缩比越小。
四、实验总结
1bit 量化时量化误差图像是黑的,量化比特数越低图像质量越差,DPCM编码可以有效地压缩文件。