Lab4 DPCM 压缩系统的实现和分析——C语言代码实现

一、实验原理

原理实现框图如下:

  • 将输入的像素值与前一个像素值的预测值作差,并对差值进行编码
  • 编码后的差值一路直接输出
  • 编码后的差值另一路通过解码器解出差值,并与前一个像素的预测值相加,得到当前像素的预测值

需要注意的是:在DPCM编码器中实际内嵌了一个解码器,如编码器中虚线框中所示。

举例说明:

二、实验内容

实验目标:验证DPCM编码的编码效率。

  • 先读取一个256级的灰度图像
  • 根据自己设定的预测方法计算预测误差,并进行量化
  • 在DPCM编码器实现的过程中可同时输出预测误差图像和重建图像
  • 将预测误差图像写入文件并将该文件输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比
  • 将原始图像文件输入Huffman编码器,得到输出码流、给出概率分布图并计算压缩比
  • 比较两种系统的编码效率,如压缩比和压缩质量(PSNR)

本实验采用8bit量化,分别进行向左和向上的预测。

三、实现代码

(头文件省略)

1、向左进行DPCM

void DPCMLeft(int Width,int Height,void *yBuff,void *recBuff,void *errBuff)//DPCM向左预测
{unsigned char *yB=NULL;yB = (unsigned char *)yBuff;unsigned char *recB=NULL;recB = (unsigned char *)recBuff;unsigned char *errB=NULL;errB = (unsigned char *)errBuff;int P1,P2;//P1为当前值与预测值的误差,P2为量化后的误差unsigned char P3;//P3为反量化后的误差for(int i=0;i<Height;i++){for(int j=0;j<Width;j++){if(j == 0)//向左进行预测时,图像最左边一列的像素值直接输出,无需进行差分预测{*(recB+j+i*Width)=*(yB+j+i*Width);//当前值即为重建值,作为下一个像素的参考值*(errB+j+i*Width)=0;//误差为0}else//当不是最左边一列的像素时,进行DPCM{P1=*(yB+j+i*Width)-*(recB+(j-1)+i*Width);//求当前值与参考值的差值if(P1%2==0)//对差值进行8bit均匀量化,并进行+128的偏移以输出P2=P1/2+128;elseP2=(P1-1)/2+128;*(errB+j+i*Width)=unsigned char(P2);//将误差写入errB缓存区域P3=unsigned char(P2*2);//对量化后的误差反量化*(recB+j+i*Width)=*(recB+(j-1)+i*Width)+P3;//将参考值与反量化得到的误差相加,作为当前像素的重建值,即下一个像素的参考值}}}
}

2、向上进行DPCM

void DPCMUp(int Width,int Height,void *yBuff,void *recBuff,void *errBuff)//DPCM向上预测
{unsigned char *yB=NULL;yB = (unsigned char *)yBuff;unsigned char *recB=NULL;recB = (unsigned char *)recBuff;unsigned char *errB=NULL;errB = (unsigned char *)errBuff;int P1,P2;//P1为当前值与预测值的误差,P2为量化后的误差unsigned char P3;//P3为反量化后的误差for(int i=0;i<Height;i++){for(int j=0;j<Width;j++){if(i == 0)//向上进行预测时,图像最上边一列的像素值直接输出,无需进行差分预测{*(recB+j+i*Width)=*(yB+j+i*Width);//当前值即为重建值,作为下一个像素的参考值*(errB+j+i*Width)=0;//误差为0}else//当不是最上边一列的像素时,进行DPCM{P1=*(yB+j+i*Width)-*(recB+j+(i-1)*Width);//求当前值与参考值的差值if(P1%2==0)//对差值进行8bit均匀量化,并进行+128的偏移以输出P2=P1/2+128;elseP2=(P1-1)/2+128;*(errB+j+i*Width)=unsigned char(P2);//将误差写入errB缓存区域P3=unsigned char(P2*2);//对量化后的误差反量化*(recB+j+i*Width)=*(recB+j+(i-1)*Width)+P3;//将参考值与反量化得到的误差相加,作为当前像素的重建值,即下一个像素的参考值}}}
}

3、PSNR计算

int simplest_yuv420_psnr(void *yBuff1,void *yBuff2, int w, int h, int num)//计算Y分量的PSNR
{unsigned char *yB1=NULL;yB1 = (unsigned char *)yBuff1;unsigned char *yB2=NULL;yB2 = (unsigned char *)yBuff2;for (int i = 0; i < num; i++){double mse_sum = 0, mse = 0, psnr = 0;for (int j = 0; j < h ; j++){for (int k = 0; k < w; k++){mse_sum += pow((double)(*(yB1+k+j*w) - *(yB2+k+j*w)), 2);//取每个差值的平方,并进行累加}}mse = mse_sum / (w * h); //根据公式计算msepsnr = 10 * log10(255.0 * 255.0 / mse); //根据公式计算psnrprintf("%5.3f\n", psnr);}system("pause");return 0;
}

4、主函数

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <malloc.h>
#include <string.h>
#include"DPCM.h"int main(int argc, char** argv)
{int frameWidth;            int frameHeight;        char* yFileName = NULL;//原始的灰度文件FILE* yFile = NULL;unsigned char* y_Buf = NULL;char* recFileName = NULL;//重建的图像文件FILE* recFile = NULL;unsigned char* rec_Buf = NULL;char* errFileName = NULL;//量化后的预测误差文件FILE* errFile = NULL;unsigned char* err_Buf = NULL;unsigned char* u_Buf = NULL;unsigned char* v_Buf = NULL;yFileName = argv[1];recFileName = argv[2];errFileName = argv[3];frameWidth = atoi(argv[4]);frameHeight = atoi(argv[5]);fopen_s(&yFile,yFileName, "rb");//打开灰度文件if (yFile == NULL){printf("cannot find y file\n");exit(1);}recFile = fopen(recFileName, "wb");//打开重建图像文件if (recFile == NULL){printf("cannot find yuv file\n");exit(1);}errFile = fopen(errFileName, "wb");//打开量化后的误差文件if (errFile == NULL){printf("cannot find yuv file\n");exit(1);}y_Buf = (unsigned char*)malloc(frameWidth * frameHeight * sizeof(unsigned char));  //开辟5个缓存空间u_Buf = (unsigned char*)malloc(frameWidth * frameHeight * sizeof(unsigned char) / 4);v_Buf = (unsigned char*)malloc(frameWidth * frameHeight * sizeof(unsigned char) / 4);rec_Buf = (unsigned char*)malloc(frameWidth * frameHeight * sizeof(unsigned char));err_Buf = (unsigned char*)malloc(frameWidth * frameHeight * sizeof(unsigned char)*1.5);if (y_Buf == NULL || rec_Buf == NULL || err_Buf == NULL || u_Buf == NULL ||v_Buf == NULL){printf("wrong malloc\n");exit(1);}fread(y_Buf, 1, frameWidth * frameHeight, yFile);//读取灰度文件数据if (y_Buf == NULL){printf("wrong fread\n");exit(1);}//DPCMLeft(frameWidth,frameHeight,y_Buf,rec_Buf,err_Buf);//向左进行预测DPCMUp(frameWidth,frameHeight,y_Buf,rec_Buf,err_Buf);//向上进行预测for(int i=0;i<frameHeight/2;i++){for(int j=0;j<frameWidth/2;j++){*(u_Buf+j+i*frameWidth/2)=128;*(v_Buf+j+i*frameWidth/2)=128;}}fwrite(rec_Buf, 1, frameWidth * frameHeight, recFile);//将数据写入文件进行输出fwrite(err_Buf, 1, frameWidth * frameHeight, errFile);fwrite(u_Buf, 1, frameWidth * frameHeight / 4, errFile);fwrite(v_Buf, 1, frameWidth * frameHeight / 4, errFile);//计算PSNRsimplest_yuv420_psnr(y_Buf,rec_Buf,frameWidth,frameHeight,1);free(y_Buf);free(rec_Buf);free(err_Buf);free(u_Buf);free(v_Buf);fclose(yFile);fclose(recFile);fclose(errFile);
}

5、计算Y分量的概率分布

参考1.2 分析RGB和YUV文件三个通道的概率分布,并计算各自的熵(编程实现)

四、实验结果

本次实验用Lena256B.yuv进行验证,Lena256B.yuv的大小为98,304 字节
向左预测量化后的误差图像err_L.yuv和向上预测量化后的误差图像err_L2.yuv的大小均为98,304 字节

原图进行huffcode 向左预测量化后的误差图像进行huffcode 向上预测量化后的误差图像进行huffcode
文件图片
概率分布图
熵编码后文件大小 69,885 字节 45,410 字节 39,966 字节
压缩比 71.09% 46.19% 40.66%
PSNR 51.177 51.185

总结:

  • 经过熵编码之后,图像的大小会被压缩。
  • 经过DPCM+熵编码之后,图像大小比直接使用熵编码减小的更多。
  • 经过DPCM+熵编码的PSNR值比只经过熵编码的PSNR值小,表明经过DPCM预测编码后重建出的图像质量比原始图像的质量差。
  • 理论上,量化比特数的影响:随着量化比特数的减小,压缩效率应该越来越高,但同时PSNR的值应该越来越小,表明重建出的图像质量应该越来越差。

综上,量化应采用合适的量化比特数,既保证画面质量,又可以达到较高的压缩效率。

Lab4 DPCM 压缩系统的实现和分析——C语言代码实现相关推荐

  1. [数据压缩作业6]DPCM压缩系统的实现和分析

    目录 (一)实验名称 (二)实验目的 (三)主要设备 (四)实验内容 一.原理 1. DPCM编解码 2. PSNR峰值信号噪声比 (五)实验步骤 一.DPCM编码系统的设计 二.代码 1. DPCM ...

  2. 数据压缩【实验四】DPCM压缩系统的实现和分析

    目录 一.实验目的 二.实验原理 三. 实验代码 (1)代码 (2)输出结果 四.实验结果 (1)压缩 (2) PSNR峰值信噪比 原理 算法 重建图像 五.实验分析 一.实验目的 掌握DPCM编解码 ...

  3. DPCM压缩系统的实现与分析

    目录 一.实验目的 二.实验原理 1.DPCM编解码原理 2.PSNR峰值信噪比 三.实验步骤 四.实验代码 1.DPCM 2.PSNR 3.主函数 五.实验结果与分析 1.压缩质量 以下图为例 其他 ...

  4. DPCM压缩系统的实现和分析

    目录 实验目的 实验原理 DPCM编解码原理 线性预测器的设计 图像客观质量评价 均方误差 信噪比SNR 峰值信噪比PSNR Huffman编码 代码 dpcm.h DPCM.cpp frequenc ...

  5. [实验四]DPCM 压缩系统的实现和分析

    目录 一.实验原理 1.1 DPCM ​1.2 量化 二.代码实现 2.1 程序说明 2.2 main.cpp 2.3 DPCM.h 2.4 DPCM.cpp 2.5 UV通道删除 三.实验测试 四. ...

  6. 数据压缩(8):DPCM 压缩系统的实现和分析

    1.DPCM编解码原理 DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统.在DPCM系统中,需要注意的是预测器的输入是已经解码以后的样本.之所以不用原始样本来做预测,是因为在解码端无法得到原 ...

  7. DPCM 压缩系统的实现和分析

    DPCM基本原理 DPCM即查分预测编码调制,将一个像素与上一个像素的差量化,得到预测误差. 本实验中采用右侧减左侧得到差值来预测,量化器采用8比特均匀量化. 编码代码 /* y_buffer:存储y ...

  8. 限速linux c语言,基于Linux系统的流量控制程序的C语言代码

    基于Linux系统的流量控制程序的C语言代码 基于Linux系统的流量控制程序的C语言代码 mytbf.h头文件 ifndef MYTBF_H_ #define MYTBF_H_ typedef vo ...

  9. r语言npsurv_10生存分析+R语言代码surv.pdf

    10生存分析R语言代码surv 生存函数和危险函数 生存分析数据的 Cox 回归模型 生存分析 R 软件陪同 吴喜之 December 20, 2014 . . . . . . . . . . . . ...

最新文章

  1. 2022-2028年中国演出市场深度调研与投资可行性报告
  2. Java培训完可以应用在什么领域
  3. 深度学习-Tensorflow2.2-深度学习基础和tf.keras{1}-softmax多分类-06
  4. PAT1044 火星数字 (20 分)
  5. c++整理程序 dev_C编程从入门到实践:C语言开发工具详解(2)
  6. 修改 cmd 字体为 Consolas
  7. kindle的xray怎么用_Xray简单使用教程
  8. linux学习笔记-文件属性基本知识
  9. 2022年北京航空航天大学计算机考研复试时间与复试内容
  10. 基于php的企业公文流转审批系统
  11. 自考计算机00051笔记,自考00051 管理系统中计算机应用自考笔记自考小抄.doc
  12. 在SpringBoot项目中,自定义注解+拦截器优雅的实现数据的加解密!
  13. 14道初级程序员进阶中高级的必经环节
  14. Windows 10 IDM 下载play.kth.se上面的网课视频
  15. n行数字组成的数字三角形详解
  16. 计算机网络ieee802.3标准,计算机网络实验四IEEE 802.3协议分析和以太网
  17. EMC潘国林: 大话存储系列之磁盘娶亲(RAID)
  18. CentOS-7-x86_64-DVD-1503-01.iso安装mysqlmysql-5.7.25-1.el7.x86_64.rpm-bundle.tar(亲测有效)
  19. 计算机二级报名座位按什么顺序,报考指南:计算机二级考试备考与指南
  20. 刷机一直请求shsh_爱思助手刷机过程里提示请求SHSH失败的处理教程

热门文章

  1. 当广告效果追踪撞上隐私保护
  2. AUTOCAD——沿着线种树
  3. 日本最大的社交APP Line的服务架构(1)
  4. Spark的安装与使用 第1关:Scala语言开发环境的部署
  5. U盘或者移动硬盘弹出时出现弹窗的解决方法
  6. 软件测试(黑盒测试技术)+实验报告
  7. 必修三计算机选修三知识点,高二数学必修三知识点归纳总结
  8. ABP入门教程(二)添加一个实体和服务
  9. python和pycharm安装包(附网盘地址)
  10. 高中数学;高考真题函数恒成立问题