DPCM压缩实现

来源:互联网 发布:淘宝hd ipad 编辑:程序博客网 时间:2024/06/05 21:53

DPCM:差分脉冲编码,其关键是预测。

预测的基本原理:利用信源符号之间的相关性,用当前样值以前的若干个样值线性组合作为当前样值的预测值。当仅适用前一样值且预测系数为1时,则为DPCM。若样本序列在时间上有较强的相关性,并且预测阶数和量化比特数选择的足够好,则误差信号的幅度将远远小于原始信号,从而得到较好的压缩。
原理框图:

m(k)—输入抽样信号  m’ (k)—预测抽样信号
e(k) —输入信号与预测信号的差值,e(k)= m(k)-m’ (k)
eq(k)—量化后的预测信号差值 
 m~(k)—重建信号, m~(k)=eq(k)+m’ (k)

实验中的主要误差来源于量化。且编码器中嵌套了一个解码器。

代码实现:

变量定义:

unsigned char* pBuf = NULL;//存储重建图像值unsigned char* eBuf_p = NULL;//存储量化后的差值int eBuf ;//存储差值

开辟内存:

pBuf = (unsigned char*)malloc(frameWidth * frameHeight);eBuf_p =(unsigned char*)malloc(frameWidth * frameHeight);

一阶(8比特量化):

for( int j=0;j<frameHeight;j++)//j:行        {//对第一列的像素单独操作            eBuf=yBuf[j*frameWidth]-128;            eBuf_p[j*frameWidth]=(eBuf+255)/2;            yBuf[j*frameWidth]=128+(eBuf_p[j*frameWidth]-127)*2;            pBuf[frameWidth*j]=128+(eBuf_p[frameWidth*j]-127)*2 ;            for(i=1+j*frameWidth;i<frameWidth*(j+1);i++)//每次对一行内的像素做预测。以行为周期循环。            {//i:列,从每一行的第二个像素值开始                eBuf=yBuf[i]-yBuf[i-1];                eBuf_p[i]=(eBuf+255)/2;//预测误差的量化值                yBuf[i] = (eBuf_p[i]-127)*2+yBuf[i-1];//预测值                pBuf[i] = (eBuf_p[i]-127)*2+pBuf[i-1];//重建值                }//        }        

由于第一列的像素无参考重建值,故将其参考值固定地设为128。eBuf表示待预测的样本与预测值的差值,取值有正有负,在-255~255之间,预测误差的量化值要限定在0~255范围内,故需要将其映射成正数,再进行量化。本次实验直接将前一样本的重建值作为待预测样本的预测值。

8bit量化:量化级数为256。将映射成的正数除以2即得量化值。4比特量化时,要将中的127 变为255/32(下取整),此时一共有16个量化级。

一阶,预测系数为0.95:

for( int j=0;j<frameHeight;j++)//j:行        {//对第一列的像素单独操作            eBuf=yBuf[j*frameWidth]-128;            eBuf_p[j*frameWidth]=(eBuf+255)/2;            yBuf[j*frameWidth]=128+(eBuf_p[j*frameWidth]-255/2)*2;            pBuf[frameWidth*j] = (eBuf_p[frameWidth*j] - 255 /2)*2 + 128;            for(i=1+j*frameWidth;i<frameWidth*(j+1);i++)            {//i:列 从每行的第二个元素开始                eBuf=yBuf[i]-0.95*yBuf[i-1];                eBuf_p[i]=(eBuf+255)/2;//预测误差的量化值                yBuf[i] = (eBuf_p[i] - 127)*2 + 0.95*yBuf[i-1];                pBuf[i] = (eBuf_p[i] - 127)*2 + 0.95*pBuf[i-1];                 }//        }

二阶:


for( int j=1;j<frameHeight;j++)//j:行        {            eBuf=yBuf[j*frameWidth]-128;            eBuf_p[j*frameWidth]=(eBuf+255)/2;            yBuf[j*frameWidth]=128+(eBuf_p[j*frameWidth]-127)*2;            pBuf[frameWidth*j] = (eBuf_p[frameWidth*j] - 127)*2 + 128;            for(i=1;i<frameWidth;i++)            {//i:列                eBuf=yBuf[i+j*frameWidth]-0.5*yBuf[i+j*frameWidth-1]-0.25*yBuf[i+(j-1)*frameWidth]-0.25*yBuf[i+1+(j-1)*frameWidth];                eBuf_p[i+j*frameWidth]=(eBuf+255)/2;//预测误差的量化值                yBuf[i+j*frameWidth] = (eBuf_p[i+j*frameWidth] - 127)*2 + 0.5*yBuf[i+j*frameWidth-1]+0.25*yBuf[i+(j-1)*frameWidth]+0.25*yBuf[i+1+(j-1)*frameWidth];                pBuf[i+j*frameWidth] = (eBuf_p[i+j*frameWidth] - 127)*2 + 0.5*pBuf[i+j*frameWidth-1]+0.25*pBuf[i+(j-1)*frameWidth]+0.25*pBuf[i+1+(j-1)*frameWidth];                 }//        }

系数不同:




(从上到下,依次为:8比特预测系数1,8比特预测系数0.95,8比特量化二阶)

量化比特数不同:





(量化比特数依次为:8,4,1)

位深度为8的测试文件:


(量化比特数为8,预测系数依次为:1,0.95,二阶(0.5,0.25,0.25))

阶数对比:



量化比特数依次为:8比特,4比特,1比特

重建后的图像:

对原图像和预测误差图像进行huffman编码,结果对比:


直方图分布:

Bird文件:

实验结论:

预测阶数为2阶时,对预测误差图像编码所需码长较短,但重建图像与原图像在部分区域出现较大误差。

量化比特数越小,对预测误差文件编码需要的码长较短,但重建图像与原图像的误差变大。图像位深度较小时,无法准确重建图像。





0 0