栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

第四次实验:DPCM编码

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

第四次实验:DPCM编码

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

DPCM编码原理:

 

在一个DPCM系统中,需要设计预测器和量化器两部分,在本次实验中,采用固定预测器和均匀量化器

代码部分:

#include
#include
#include
using namespace std;
 
int main(int argc, char** argv)
{
	char* orifilename = NULL;
	char* prefilename = NULL;
	char* recfilename = NULL;
 
	orifilename = argv[1];
	prefilename = argv[2];
	recfilename = argv[3];
 
	FILE* fp1 = fopen(orifilename, "rb");
	FILE* fp2 = fopen(prefilename, "wb");
	FILE* fp3 = fopen(recfilename, "wb");
 
	if (fp1 == NULL)
		cout << "cannot find oriyuv" << endl;
	if (fp2 == NULL)
		cout << "cannot find preyuv" << endl;
	if (fp3 == NULL)
		cout << "cannot find recyubv" << endl;
 
	unsigned char* oribuffer;
	unsigned char* prebuffer;
	unsigned char* recbuffer;
	unsigned char* u_buffer;
	unsigned char* v_buffer;
 
	int width = atoi(argv[4]);
	int height = atoi(argv[5]);
 
	oribuffer = (unsigned char*)malloc(width * height * 1.5);
	prebuffer = (unsigned char*)malloc(width * height * 1.5);
	recbuffer = (unsigned char*)malloc(width * height);
	u_buffer = (unsigned char*)malloc(width * height * 1 / 4);
	v_buffer = (unsigned char*)malloc(width * height * 1 / 4);
 
	fread(oribuffer, sizeof(unsigned char), width * height, fp1);
 
	int p1;
	int p2;
	unsigned char p3;
 
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			if (j == 0)
			{
				*(recbuffer + i * width + j) = 128;
				*(prebuffer + i * width + j) = *(oribuffer + i * width + j) - 128;
			}
			else
			{
				p1 = *(oribuffer + i * width + j) - *(oribuffer + i * width + j - 1);//误差
				if (p1 % 2 == 0)
					p2 = p1 / 2 + 128;//8bit量化
				else
					p2 = (p1 - 1) / 2 + 128;//8bit量化
				*(prebuffer + i * width + j) = unsigned char(p2);
				p3 = unsigned char(p2 * 2);//反量化
				*(recbuffer + i * width + j) = *(oribuffer + i * width + j - 1) + p3;
			}
		}
	}
 
	for (int i = 0; i < height / 2; i++)
	{
		for (int j = 0; j < width / 2; j++)
		{
			*(u_buffer + i * width / 2 + j) = 128;
			*(v_buffer + i * width / 2 + j) = 128;
		}
	}
 
 
	fwrite(recbuffer, 1, width * height, fp3);
	fwrite(u_buffer, 1, width * height / 4, fp3);
	fwrite(v_buffer, 1, width * height / 4, fp3);
 
	fwrite(prebuffer, 1, width * height, fp2);
	fwrite(u_buffer, 1, width * height / 4, fp2);
	fwrite(v_buffer, 1, width * height / 4, fp2);
 
	int max = 255;
	double mse = 0;
	for (int i = 0; i < width * height; i++)
	{
		mse += (double(oribuffer[i]) - double(recbuffer[i])) * (double(oribuffer[i]) - double(recbuffer[i]));  //分子
	}
	mse = (double)mse / (double)(width * height);
	double psnr = 10 * log10((double)(max * max) / mse);
	cout << "PSNR = " << psnr;
 
	return 0;
}

dpcm编码

for(int i=0;i < frameWidth*frameHeight;i++)
	{
		if(i % frameWidth==0)
	{   
			prebuf[i]=(yBuf[i]-128)/2+128;
		resconbuf[i]=(prebuf[i]-128)*2+ 128;//重现信号为预测信号反量化后的值+0
		}
		else{
				prebuf[i]=(yBuf[i]- resconbuf[i-1])/2+128;// 预测信号为当前输入的y信号与上一个重现信号的差值做量化
				resconbuf[i]=((prebuf[i]-128)*2+resconbuf[i-1]);//重现信号为当前预测信号反量化后的值与上个重现信号的和的值
		}}

psnr代码

double MSE = 0;
	double sub = 0;
	double sum = 0;
	for (int j = 0; j < 256; j++)
	{
		for (int i = 0; i <256; i++)
		{
			sub = yBuf[i] - resconbuf[i];
			sum = sum + pow(sub, 2);
		}
	}
	MSE = (sum) / (256 * 256);
	double psnr = 10 * log10 ((255 * 255) / MSE);
	cout<<"PSNR="< 

实验结果及分析:

8bit:

4bit :

  

 2bit:

 

 

 

 

1、从预测误差图像概率分布与原始图像的概率分布对比可以看出,预测误差图像的概率分布更集中,大部分像素都集中在灰度值为100-150之间,像素之间的关联性更高分布的很集中,很适合用霍夫曼编码进行熵编码,压缩的时候更加容易,而原始图像的概率分布则更均匀,在进行霍夫曼编码时压缩的效率就没有那么高。

2、PSNR越大,图像质量越好,8bit量化的重现图像的PSNR=51.1411dB,比4/2/1bit要好

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1001589.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号