Lab4 DPCM 压缩系统的实现和分析——C语言代码实现
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语言代码实现相关推荐
- [数据压缩作业6]DPCM压缩系统的实现和分析
目录 (一)实验名称 (二)实验目的 (三)主要设备 (四)实验内容 一.原理 1. DPCM编解码 2. PSNR峰值信号噪声比 (五)实验步骤 一.DPCM编码系统的设计 二.代码 1. DPCM ...
- 数据压缩【实验四】DPCM压缩系统的实现和分析
目录 一.实验目的 二.实验原理 三. 实验代码 (1)代码 (2)输出结果 四.实验结果 (1)压缩 (2) PSNR峰值信噪比 原理 算法 重建图像 五.实验分析 一.实验目的 掌握DPCM编解码 ...
- DPCM压缩系统的实现与分析
目录 一.实验目的 二.实验原理 1.DPCM编解码原理 2.PSNR峰值信噪比 三.实验步骤 四.实验代码 1.DPCM 2.PSNR 3.主函数 五.实验结果与分析 1.压缩质量 以下图为例 其他 ...
- DPCM压缩系统的实现和分析
目录 实验目的 实验原理 DPCM编解码原理 线性预测器的设计 图像客观质量评价 均方误差 信噪比SNR 峰值信噪比PSNR Huffman编码 代码 dpcm.h DPCM.cpp frequenc ...
- [实验四]DPCM 压缩系统的实现和分析
目录 一.实验原理 1.1 DPCM 1.2 量化 二.代码实现 2.1 程序说明 2.2 main.cpp 2.3 DPCM.h 2.4 DPCM.cpp 2.5 UV通道删除 三.实验测试 四. ...
- 数据压缩(8):DPCM 压缩系统的实现和分析
1.DPCM编解码原理 DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统.在DPCM系统中,需要注意的是预测器的输入是已经解码以后的样本.之所以不用原始样本来做预测,是因为在解码端无法得到原 ...
- DPCM 压缩系统的实现和分析
DPCM基本原理 DPCM即查分预测编码调制,将一个像素与上一个像素的差量化,得到预测误差. 本实验中采用右侧减左侧得到差值来预测,量化器采用8比特均匀量化. 编码代码 /* y_buffer:存储y ...
- 限速linux c语言,基于Linux系统的流量控制程序的C语言代码
基于Linux系统的流量控制程序的C语言代码 基于Linux系统的流量控制程序的C语言代码 mytbf.h头文件 ifndef MYTBF_H_ #define MYTBF_H_ typedef vo ...
- r语言npsurv_10生存分析+R语言代码surv.pdf
10生存分析R语言代码surv 生存函数和危险函数 生存分析数据的 Cox 回归模型 生存分析 R 软件陪同 吴喜之 December 20, 2014 . . . . . . . . . . . . ...
最新文章
- 2022-2028年中国演出市场深度调研与投资可行性报告
- Java培训完可以应用在什么领域
- 深度学习-Tensorflow2.2-深度学习基础和tf.keras{1}-softmax多分类-06
- PAT1044 火星数字 (20 分)
- c++整理程序 dev_C编程从入门到实践:C语言开发工具详解(2)
- 修改 cmd 字体为 Consolas
- kindle的xray怎么用_Xray简单使用教程
- linux学习笔记-文件属性基本知识
- 2022年北京航空航天大学计算机考研复试时间与复试内容
- 基于php的企业公文流转审批系统
- 自考计算机00051笔记,自考00051 管理系统中计算机应用自考笔记自考小抄.doc
- 在SpringBoot项目中,自定义注解+拦截器优雅的实现数据的加解密!
- 14道初级程序员进阶中高级的必经环节
- Windows 10 IDM 下载play.kth.se上面的网课视频
- n行数字组成的数字三角形详解
- 计算机网络ieee802.3标准,计算机网络实验四IEEE 802.3协议分析和以太网
- EMC潘国林: 大话存储系列之磁盘娶亲(RAID)
- CentOS-7-x86_64-DVD-1503-01.iso安装mysqlmysql-5.7.25-1.el7.x86_64.rpm-bundle.tar(亲测有效)
- 计算机二级报名座位按什么顺序,报考指南:计算机二级考试备考与指南
- 刷机一直请求shsh_爱思助手刷机过程里提示请求SHSH失败的处理教程