【数据压缩(六)】DPCM 压缩系统的实现和分析

一、实验目的

掌握DPCM编解码系统的基本原理。初步掌握实验用C/C++/Python等语言编程实现DPCM 编码器,并分析其压缩效率

二、实验内容

1、DPCM编解码原理

在DPCM系统中, 预测器的输入是已经解码以后的样本。之所以不用原始样本来做预测,是因为在解码端无法得到原始样本,只能得到存在误差的样本。因此,在DPCM编码器中实际内嵌了一个解码器。在本次实验中,采用固定预测器和均匀量化器

三、实验代码

1、计算概率分布

#include<iostream>
#include<math.h>
using namespace std;

int prob(int height, int width, unsigned char* inbuf, double* outpro)
{
	double size = height * width * 1.5;	
	int num[256] = { 0 };
	double pro[256] = { 0 };

	for (int i = 0; i < size; i++)
	{
		num[(int)*(inbuf + i)]++;
		pro[(int)*(inbuf + i)] = num[(int)*(inbuf + i)] / size;
	}

	for (int i = 0; i < 256; i++)
		*(outpro + i) = pro[i];

	return 0;
}

2、计算psnr

#include<iostream>
#include<math.h>
using namespace std;

int psnr(int height, int width, unsigned char* orbuf, unsigned char* rebuf, int dep)
{
	double max = 255;
	double mse = 0;
	double psnr;

	for (int i = 0; i < height; i++)
		for (int j = 0; j < width; j++)
		{
			mse += (orbuf[i * width + j] - rebuf[i * width + j]) * (orbuf[i * width + j] - rebuf[i * width + j]);
		}
	mse = mse / (double)(width * height);
	psnr = 10 * log10((double)(max * max) / mse);
	cout << dep <<"bit "<< "PSNR = " << psnr << endl;

	return 0;
}

3、dpcm编解码

#include<iostream>
#include<math.h>
using namespace std;

int dpcm(int height, int width, unsigned char* orbuf, unsigned char* rebuf, unsigned char* errbuf, int dep)
{
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			if (j == 0)
			{
				*errbuf = (*orbuf - 128 + 255) / pow(2, 9 - dep);
				*rebuf = 128 + (*errbuf * pow(2, 9 - dep) - 255);
				rebuf++;
				orbuf++;
				errbuf++;
			}
			else
			{
				*errbuf = (*orbuf - *(rebuf - 1) + 255) / pow(2, 9 - dep);
				*rebuf = *(rebuf - 1) + (*errbuf * pow(2, 9 - dep) - 255);
				if (*rebuf < 0) *rebuf = 0;
				if (*rebuf > 255) *rebuf = 255;

				rebuf++;
				orbuf++;
				errbuf++;
			}
		}
	}

	for (int i = 0; i < height * width * 0.5; i++)
	{
		*rebuf = *orbuf;
		*errbuf = 128;

		rebuf++;
		orbuf++;
		errbuf++;
	}

	for (int i = 0; i < height * width * 1.5; i++)
	{
		errbuf--;
		rebuf--;
		orbuf--;
	}

	return 0;
}

4、main函数

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<math.h>
#include"method.h"

using namespace std;

int main()
{
	int height = 768;	
	int width = 512;	
	int dep = 8;		//量化比特

	unsigned char* orbuf = (unsigned char*)malloc(sizeof(unsigned char) * height * width * 1.5);
	unsigned char* rebuf = (unsigned char*)malloc(sizeof(unsigned char) * height * width * 1.5);
	unsigned char* errbuf = (unsigned char*)malloc(sizeof(unsigned char) * height * width * 1.5);
	double* orpro = (double*)malloc(sizeof(double) * 256);
	double* errpro = (double*)malloc(sizeof(double) * 256);


	//文件
	FILE* orfile = fopen("C:/Users/86137/Desktop/数据压缩/test4/test/Lena256B.yuv", "rb");
	FILE* refile = fopen("C:/Users/86137/Desktop/数据压缩/test4/test/reLena256B.yuv", "wb");
	FILE* errfile = fopen("C:/Users/86137/Desktop/数据压缩/test4/test/errLena256B.yuv", "wb");
	FILE* ortxt = fopen("C:/Users/86137/Desktop/数据压缩/test4/test/orpro.txt", "wb");
	FILE* errtxt = fopen("C:/Users/86137/Desktop/数据压缩/test4/test/errpro.txt", "wb");

	if (orfile == NULL || refile == NULL || errfile == NULL || ortxt == NULL || errtxt == NULL)
	{
		cout << "error!" << endl;
		return 0;
	}

	fread(orbuf, 1, height * width * 1.5, orfile);

	dpcm(height, width, orbuf, rebuf, errbuf, dep);

	psnr(height, width, orbuf, rebuf, dep);

	prob(height, width, orbuf, orpro);		//原图概率
	prob(height, width, errbuf, errpro);	//预测误差图概率

	fwrite(rebuf, 1, height * width * 1.5, refile);
	fwrite(errbuf, 1, height * width * 1.5, errfile);
	for (int i = 0; i < 256; i++)
	{
		fprintf(ortxt, "%lf\n", *(orpro + i));
		fprintf(errtxt, "%lf\n", *(errpro + i));
	}

	fclose(orfile);
	fclose(refile);
	fclose(errfile);
	fclose(ortxt);
	fclose(errtxt);

	return 0;
}

四、实验结果

原图及概率分布

原图概率分布

 dpcm实验结果

8bit4bit2bit
psnr
重建图
预测误差图
预测误差图概率分布

熵编码结果(以8bit量化为例)

 原图像大小为96kb,8bit量化+熵编码处理后为129kb,压缩比0.7

只做熵编码,处理后为69kb,压缩比为1.39

误差图像的压缩效率要比直接进行Huffman编码的效率更低了,但具体原因并不太理解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DPCM(差分脉冲编码调制)是一种数据压缩系统,其目的是在尽量不失真的情况下减少数据存储或传输所需的带宽。DPCM 压缩系统实现主要是在传输前对原始信号进行差分编码,将每一个样本值与它前面的样本值的差值编码传输。在解码端,将编码的差值与前一个样本值相加,得到解码后的样本值。 DPCM 压缩系统的性能取决于差分编码器的性能和采样率。通常,差分编码器需要对原始信号进行线性预测,并将其与实际样本值的差异编码。预测器的设计和参数设置是影响性能的关键因素。 DPCM 压缩系统主要有以下优点:首先,DPCM 采用差分编码,可以将一系列相邻的样本压缩成差分值,从而减少需要传输的数据量。其次,由于 DPCM 是一种有损压缩策略,可以通过控制压缩后的失真来有效地减少数据量。再者,DPCM 压缩系统的计算和编码速度较快,可以在硬件中实现,适用于实时视频或音频传输。 然而,DPCM 压缩系统也有一些缺点。首先,差分编码容易受到干扰和噪声的影响,从而导致误差传播和失真的增加。此外,DPCM 不适用于大多数不规则信号,如图片和文本等。 总之,DPCM 压缩系统是一种有损压缩策略,可以通过对原始信号进行差分编码来减少数据量。其性能主要取决于差分编码器的设计和采样率,适用于实时音视频传输和存储等场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值