DPCM压缩实现

xiaoxiao2021-02-28  64

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阶时,对预测误差图像编码所需码长较短,但重建图像与原图像在部分区域出现较大误差。

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

转载请注明原文地址: https://www.6miu.com/read-83102.html

最新回复(0)