实验4 | DPCM编码_帧内编码使用dpcm-程序员宅基地

技术标签: 数据压缩作业  

一、实验目的

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

二、实验内容

1.DPCM编解码原理

DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统。在DPCM系统中, 预测器的输入是已经解码以后的样本。之所以不用原始样本来做预测,是因为在解码端无法得到原始样本,只能得到存在误差的样本,因此在DPCM编码器中实际内嵌了一个解码器。
在这里插入图片描述
在一个DPCM系统中,需要设计预测器和量化器。理想情况下,预测器和量化器应进行联合优化。实际中,采用一种次优的设计方法:分别进行线性预测器和量化器的优化设计。

2.DPCM编码系统的设计

(1)DPCM编码

量化器采用8比特均匀量化。本实验的目标是验证DPCM编码的编码效率。首先读取一个 256级的灰度图像,采用自己设定的预测方法计算预测误差,并对预测误差进行8比特均匀量化。

 //读取原文件
    FILE* fp1 = fopen(yuvfilename, "rb");
    if (fp1 == NULL)
        cout << "错误读取" << endl;
    fread(img, sizeof(unsigned char), width * height * 3 / 2, fp1);
    fclose(fp1);
    for (int i = 0; i < 256 * 256; i++)
    {
    
        y[i] = img[i];
    }

    //取色差信号
     for(int i=0;i<width * height * 1 / 4;i++)
    {
    
        u[i] = img[width * height + i];
        v[i] = img[width * height * 5 / 4 + i];
    }

    //创建缓存区
    unsigned char* prebuff;  //预测
    unsigned char *reconbuff;  //重建
    prebuff = (unsigned char*)malloc(width * height);
    reconbuff = (unsigned char*)malloc(width * height);

    //DPCM
    for (int i = 0; i < width * height; i++)
    {
    
        if (i % width == 0)
        {
    
            recon = 128;  //第一个重建值设为128
            pre = y[i] - recon;  //预测值为原始值减去重建值
        }
        else
        {
    
            recon = reconbuff[i - 1];
            pre = y[i] - recon;
        }
        
        prebuff[i] = unsigned char (pre / 2 + 128) ;
        reconbuff[i] = unsigned char (recon) + prebuff[i]*2;
        if (reconbuff[i] > 255)
        {
    
            reconbuff[i] = 255;
        }
        if (reconbuff[i] < 0 )
        {
    
            reconbuff[i] = 0;
        }
    }

输出原图像、重建图像,差值图像
在这里插入图片描述

(2)概率分布图和压缩比

在DPCM编码器实现的过程中可同时输出预测误差图像和重建图像。将预测误差图像 写入文件并将该文件输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比。将原始图像文件输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比。

    //计算概率分布
    double frey[256] = {
    0},frere[256] = {
    0},frepre[256] = {
    0};
	for (int i = 0; i < 256; i++)
	{
    
	    int county = 0, countre = 0, countpre = 0;//计数
		for (int j = 0; j < 256 * 256; j++)
		{
    
			if ((int)y[j] == i)
				county ++;
			if ((int)reconbuff[j] == i)
				countre ++;
			if ((int)prebuff[j] == i)
				countpre ++;
		}
		frey[i] = (double)county/256/256;
		frere[i] = (double)countre/256/256;
		frepre[i] = (double)countpre/256/256;
	}
	
	//将概率输出为txt文件
	char s[] = "symbol\tfrequency\n";
	FILE* Y_t = fopen("D:\\数据压缩作业\\orig.txt","w");
	fprintf(Y_t, s);
	FILE* Re_t = fopen("D:\\数据压缩作业\\recon.txt","w");
	fprintf(Re_t, s);
	FILE* Pre_t = fopen("D:\\数据压缩作业\\pre.txt","w");
	fprintf(Pre_t, s);
	for (int i = 0;i < 256; i++)
	{
    
		fprintf(Y_t,"%d\t%f\n",i, frey[i]);
		fprintf(Re_t,"%d\t%f\n",i, frere[i]);
		fprintf(Pre_t,"%d\t%f\n",i, frepre[i]);
	}
	fclose(Y_t);
	fclose(Re_t);
	fclose(Pre_t);

概率分布:在这里插入图片描述
原图像和预测误差图像的概率分布
DPCM+熵编码:压缩比为47.9167%
在这里插入图片描述
仅进行熵编码:压缩比为71.875%
在这里插入图片描述

(3)编码效率

比较两种系统(1.DPCM+熵编码和2.仅进行熵编码)之间的编码效率(压缩比和图像质量)。压缩质量以PSNR进行计算。
PSNR(峰值信号噪声比):

均方误差 MSE:
在这里插入图片描述
其中M,N为图像的宽和高,f(i,j),f’(i,j)为原图像和重建图像在(i,j)的像素值。
PSNR(dB):
在这里插入图片描述
其中bits为原图像地量化比特数,即8。
一般来说:
• PSNR ≥ 40 dB时,图像质量非常好,接近于原图像;
• 30 dB ≤ PSNR < 40 dB时,图像有可察觉的失真,但质量仍可接受;
• 20 dB ≤ PSNR < 30 dB时,图像质量较差;
• PSNR < 20 dB时,图像质量已经无法接受。

    int max = 255;
    double mse = 0;
    for (int i = 0; i < width * height; i++)
    {
    
		mse += (double(y[i]) - double(reconbuff[i])) * (double(y[i]) - double(reconbuff[i]));  //分子
    }
    mse = (double)mse / (double)(width * height);
    double psnr = 10 * log10((double)(max * max) / mse);
    cout << "PSNR = " << psnr;

计算得出:PSNR = 51.2641
可知图像质量较好,接近于原图像。

参考

使用DPCM进行图像压缩的C++实现方法

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_48462511/article/details/116402068

智能推荐

疯狂的Web应用开源项目_web 开源工作日历-程序员宅基地

文章浏览阅读2.2k次。下面是一个Web应用的开源列表。没什么可说的,太疯狂了。尤其是Web 2.0那一堆。我不知道你怎么想,有些开源项目的源码写得挺不好的,尤其是性能方面。或许你会以为改一改他们就可以成为为自己所用,不过,改这些开源的项目还真不容易。玩玩还可以。数字媒体相册(Flickr, Picasa)Gallery,基于PHP + MySQL的Web相册。非常易于使用,包括一个配置向导,对于_web 开源工作日历

tp3与tp5的区别 以及 tp5与laravel的区别_tp3版本-程序员宅基地

文章浏览阅读2.6k次。Tp3 和 Tp5之间的区别Tp5版本和Tp3的差异较大的,它们的主要区别:1.URL和路由5.0的URL访问不再支持普通URL模式,路由也不支持正则路由定义,而是全部改为规则路由配合变量规则(正则定义)的方式:主要改进有以下几点:1.增加路由变量规则、2.增加组合变量支持、3.增加资源路由、4.增加路由分组、5.增加闭包定义支持、6.增加MISS路由定义、7.支持URL路由..._tp3版本

docker介绍-程序员宅基地

文章浏览阅读88次。简介:docker是目前最火的技术,没有之一1,与openstack相比,docker的优点:2,docker的使用场景(docker能干什么):1,简化配置2,提高开发效率3,应用隔离4,服务器整合5,多用户使用6,快速部署7,代码流水线管理8,开发调试安装前准备升级内核-3.0参考文档:http://w..._"[graphdriver] prior storage driver \"devicemapper\" failed: error running devi"

Web服务器处理并发连接请求的工作模型_常用的web服务器请求处理模型有哪些-程序员宅基地

文章浏览阅读2.4k次。一、单线程web服务器(Single-threaded web servers)此种架构方式中,web服务器一次处理一个请求,结束后读取并处理下一个请求。在某请求处理过程中,其它所有的请求将被忽略,因此,在并发请求较多的场景中将会出现严重的性能问题。(即一次只能处理一个请求) 二、多进程/多线程web服务器此种架构方式中,web服务器生成多个进程或线程并行处理多个用户请求,进程或线程可以按需或事先..._常用的web服务器请求处理模型有哪些

Linux-在linux修改文件夹及其子文件夹的权限_centos 更改文件夹子文件权限-程序员宅基地

文章浏览阅读2.2k次。加入-R 参数,就可以将读写权限传递给子文件夹例如chmod -R 777 /home/mypackage那么mypackage 文件夹和它下面的所有子文件夹的属性都变成了777.777是读、写、执行权限..._centos 更改文件夹子文件权限

随便推点

html中可以单独使用的标签,html标签怎么用-程序员宅基地

文章浏览阅读867次。如何选择使用的HTML标签?什么时候选择什么样的标签?在网页布局中HTML标签如何选择?在布局时会遇到如何选择HTML标签布局,但对于非新手CSSer来说非常简单,但对于刚刚学习或刚刚入手CSS制作来说却是一个无形问题。这里为大家简单介绍在DIV+CSS布局中如何选择HTML标签:1、框架布局(使用DIV标签)在网页中框架布局一般使用DIV布局,无论大小DIV盒子一般均使用DIV标签(2、列表型布..._html多个li标签单独调用

Python字符串类型:字符串索引、字符串切片、字符串format()方法格式化、字符串操作符、字符串处理函数_字符串类型类型的索引方式-程序员宅基地

文章浏览阅读956次。字符串:由0个或多个字符组成的有序序列sequence。一、字符串表示方式:2类4种由一对单引号或双引号表示,该方式仅用于表示单行字符串由一对三单引号或三双引号,该方式可以表示多行字符串如果希望在字符串中包含单引号,外面就用双引号;反之亦然。否则出错如果希望在字符串中既包含单引号又包含双引号,外面用三单引号注:无论单双,无论几个,外面的引号一定都是英文引号。反斜杠()的作用:①转义符;②续行符转义符与后面相邻的一个字符共同组成了新的含义,如\n表示换行,\表示反斜杠,\‘表示单引_字符串类型类型的索引方式

win7休眠开启与关闭_win7 关闭休眠-程序员宅基地

文章浏览阅读4w次。从开始菜单中找到“附件→命令提示符”,手工输入如下命令:powercfg-a,从这里可以清楚的看到,计算机是支持休眠的,显示“尚未启用休眠"。仍然在命令提示符下进行操作, 开始休眠方法:手工键入如下命令:powercfg -hibernate on(关闭则为powercfg -hibernate off) 命令执行之后立即就可以生效,无需要重新启动系统,再次执行“powercfg -a..._win7 关闭休眠

完美解决mysql保存中文出现1366错误_在mysql shell中输入 show variables like 'character%'; -程序员宅基地

文章浏览阅读5.7w次,点赞14次,收藏48次。最近在使用sqlalchemy将中文存放至mysql数据库的表中时出现:Warning Code :1366 Incorrect string value: '\xE5\x9C\xA8' for column 'content' at row 1这是因为我们存放的中文,而我们的表并不支持中文字符集,使用 show variables like 'character%'; 查看mysql当前..._在mysql shell中输入 show variables like 'character%'; 结果出现 (code 1366):

《ElasticStack从入门到实践》学习笔记1_elastic stack从入门到精通 笔记-程序员宅基地

文章浏览阅读760次。一、ElasticSearch入门介绍 1、常见术语: A、Document 文档 用户存储在ES中的数据文档。 B、Index 索引 由具有相同字段的文档列表组成。在当前版本,不在推荐下设Type,在后续版本,不再设立Type。 ..._elastic stack从入门到精通 笔记

dinic (poj2987)_poj2987 dinic-程序员宅基地

文章浏览阅读995次。program poj2987; const inf=10000001;var d,dis,pre,s,q:array[0..10000] of longint; p,next,b:array[0..200000] of longint; c:array[0..200000] of int64; aa,bb,o,i,m,tt,ans1,t:longint; ans,n,f:int64;procedure link(aa,bb:longint;cc:int_poj2987 dinic