一、实验目的
掌握DPCM编解码系统的基本原理。初步掌握实验用C/C++/Python等语言编程实现DPCM编码器,并分析其压缩效率。
二、实验内容
1 读取一个yuv图像文件,进行dpcm编码,对预测误差8bit量化,输出误差图像、重建图像;
2 将预测误差图像写入文件并将该文件输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比。
将原始图像文件输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比;
3 比较两种系统(1.DPCM+熵编码和2.仅进行熵编码)之间的编码效率(压缩比和图像质量)。压缩质量以PSNR进行计算。
三、DPCM基本原理
差分脉冲编码调制(Differential Pulse code modulation,DPCM),先根据前一个抽样值计算出一个预测值,再取当前抽样值和预测值之差作编码用.此差值称为预测误差.
抽样值和预测值非常接近(因为相关性强),预测误差的可能取值范围比抽样值变化范围小.所以可用少几位编码比特来对预测误差编码,从而降低其比特率.这是利用减小冗余度的办法,降低了编码比特率。
四、c++实现
dpcm部分
#include<iostream>
#include <stdio.h>
#include<math.h>
using namespace std;
int main(int argc,char*argv[])
{
FILE*SEED=NULL;
FILE*REBUILDSEED=NULL;
FILE*E_SEED=NULL;
int size;
if((fopen_s(&SEED,"D://00//yuv//seed.yuv", "rb"))!=0)
{
cout<<"打开原文件失败"<<endl;
}
else
{
cout<<"成功打开原文件"<<endl;
}
if((fopen_s(& REBUILDSEED,"D://00//seedrebuild.yuv","wb"))!= 0)
{
cout<<"创建重建文件失败"<<endl;
}
else
{
cout<<"成功创建重建文件"<<endl;
}
if((fopen_s(&E_SEED,"D://00//E_seed.yuv","wb"))!= 0)
{
cout<<"创建误差文件失败"<<endl;
}
else
{
cout<<"成功创建误差文件"<<endl;
}
fseek(SEED,0L,SEEK_END);
size=ftell(SEED);
fseek(SEED,0L,SEEK_SET);//指针送回
unsigned char* SEED_BUFFER=new unsigned char[size];
unsigned char* REBUILDSEED_BUFFER=new unsigned char[size];
unsigned char* E_SEED_BUFFER=new unsigned char[size];
unsigned char* Y_BUFFER=new unsigned char[size/3];
fread(SEED_BUFFER,sizeof(unsigned char),size,SEED);
for(int i=0;i<size/3;i++)
{
Y_BUFFER[i]=SEED_BUFFER[i];
}
unsigned char* Y_REBUILD = new unsigned char[size * 1 / 3];
unsigned char* E_BUFFER = new unsigned char[size * 1 / 3];
for (int i = 0; i < 500; i++)
{
for (int j = 0; j < 500; j++)
{
int k = 0;
if (j == 0)
{
Y_REBUILD[j + i * 500] = Y_BUFFER[j + i * 500];
E_BUFFER[j + i * 500] = 0;
}
if (j != 0)
{
k = Y_BUFFER[j + i * 500] - Y_REBUILD[j + i * 500 - 1];
E_BUFFER[j + i * 500] = (k + 256)/ 2 - 1;
Y_REBUILD[j + i * 500] = 2 * (E_BUFFER[j + i * 500] + 1) + Y_REBUILD[j + i * 500 - 1];
}
if (E_BUFFER[j + i * 500] > 255)
{
E_BUFFER[j + i * 500] = 255;
}
if (E_BUFFER[j + i * 500] < 0)
{
E_BUFFER[j + i * 500] = 0;
}
if (Y_REBUILD[j + i * 500] > 255)
{
Y_REBUILD[j + i * 500] = 255;
}
if (Y_REBUILD[j + i * 500] < 0)
{
Y_REBUILD[j + i *500] = 0;
}
}
}
for(int i=0;i<size/3;i++)
{
REBUILDSEED_BUFFER[i]=Y_REBUILD[i];
REBUILDSEED_BUFFER[size/3+i]=SEED_BUFFER[size/3+i];
REBUILDSEED_BUFFER[size/3+size/3+i]=SEED_BUFFER[size/3+size/3+i];
}
for(int i=0;i<size/3;i++)
{
E_SEED_BUFFER[i]=E_BUFFER[i];
E_SEED_BUFFER[size/3+i]=SEED_BUFFER[size/3+i];
E_SEED_BUFFER[size/3+size/3+i]=SEED_BUFFER[size/3+size/3+i];
}
fwrite(REBUILDSEED_BUFFER,sizeof(unsigned char),size, REBUILDSEED);
fwrite(E_SEED_BUFFER,sizeof(unsigned char),size,E_SEED);
fclose(SEED);
fclose(REBUILDSEED);
fclose(E_SEED);
system("pause");
}
psnr计算部分
在这里插入代码片
五、实验结果
1原始图像、预测误差、重建图像
2概率分布图
3比较两种系统(1.DPCM+熵编码和2.仅进行熵编码)之间的编码效率(压缩比和图像质量)。压缩质量以PSNR进行计算。
(1)压缩比
DPCM+熵编码:733/140=5.23;
仅进行熵编码:733/246=2.97.
(2)压缩质量
六、实验结论