DPCM差分预测编码
原理框图:
- 将输入的像素值与前一个像素值的预测值作差,并对差值进行编码
- 编码后的差值一路直接输出
- 编码后的差值另一路通过解码器解出差值,并与前一个像素的预测值相加,得到当前像素的预测值
实验目的:
- 进行不同量化
bit
数的差分预测编码 - 将编码结果进行输出并进行霍夫曼编码
- 分别计算原图像和量化后的图像进行概率分布
- 分别计算原图像经过熵编码和经过
DPCM
+熵编码的图像的压缩比 - 比较二者压缩效率
- 计算重建图像的
PSNR
实现代码:
#define _CRT_SECURE_NO_DEPRECATE//防止fopen报错
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include"math.h"
using namespace std;int Quant(int bnum, int error) //量化
{int i = 0;i = ((error + 255) / pow(2, (9 - bnum))); //+255将误差值抬为正值再做量化return i;
}int iQuant(int bnum, unsigned char ex_pre) //反量化
{int i = 0;i = (ex_pre * pow(2, (9 - bnum)) - 255);return i;
}void DPCM(unsigned char* or_buf, unsigned char* pre_buf, unsigned char* re_buf, int width, int height, int bnum)
{int error;for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){if (j == 0)//第一列以128进行预测{error = (or_buf[i * width + j]) - 128; //误差值pre_buf[i * width + j] = Quant(bnum, error); //量化误差值re_buf[i * width + j] = iQuant(bnum, pre_buf[i * width + j]) + 128; //重建值}else { //其他列都以前一列进行预测error = (or_buf[i * width + j]) - re_buf[i * width + j - 1]; //误差值pre_buf[i * width + j] = Quant(bnum, error); //量化误差值re_buf[i * width + j] = iQuant(bnum, pre_buf[i * width + j]) + re_buf[i * width + j - 1]; //重建值}}}int max = pow(2, bnum) - 1; //当前量化的最大值for (int i = 0; i < width * height; i++) //处理可能溢出的情况{if (pre_buf[i] < 0)pre_buf[i] = 0;if (re_buf[i] > max)re_buf[i] = max;if (re_buf[i] < 0)re_buf[i] = 0;if (re_buf[i] > 255)re_buf[i] = 255;}
}
double PSNR(unsigned char* or_buf, unsigned char* re_buf, int width, int height, int bnum)
{double mse = 0, psnr = 0;for (int i = 0; i < width * height; i++){mse += pow((or_buf[i] - re_buf[i]), 2);}mse = mse / (width * height);psnr = 10 * log10(pow(255, 2) / mse);return psnr;
}
void Frequency(unsigned char* buffer, double* frequency, int height, int width) //计算概率
{int size = height * width;for (int i = 0; i < size; i++) frequency[buffer[i]] += 1;for (int i = 0; i < 256; i++) frequency[i] /= size;
}
int main(int argc, char** argv)
{char* or_n = argv[1]; //原始图像char* pre_n = argv[2]; //预测误差图像char* re_n = argv[3]; //重建图像int bnum = atoi(argv[4]); //量化bit数FILE* or_file = NULL; //原始yuvFILE* pre_file = NULL; //预测误差yuvFILE* re_file = NULL; //重建yuvint width = 256, height = 256; //除了birds以外所有图片都是256*256的//int width = 768, height = 512; //birdsunsigned char* y_buf = new unsigned char[width * height]; //原始图像的yuvunsigned char* u_buf = new unsigned char[(width * height) / 4];unsigned char* v_buf = new unsigned char[(width * height) / 4];unsigned char* pre_buf = new unsigned char[width * height]; //预测误差图像bufferunsigned char* re_buf = new unsigned char[width * height]; //重建图像bufferor_file = fopen(or_n, "rb");if (or_file == NULL) {cout << "Failed to open or_file!" << endl;}else {cout << "The or_file has been opened!" << endl;}pre_file = fopen(pre_n, "wb");if (pre_file == NULL) {cout << "Failed to open pre_file!" << endl;}else {cout << "The pre_file has been opened!" << endl;}re_file = fopen(re_n, "wb");if (re_file == NULL) {cout << "Failed to open re_file!" << endl;}else {cout << "The re_file has been opened!" << endl;}//unsigned char* uv_buf = new unsigned char[(width * height) / 2]; //用来处理birds//for (int i = 0; i < (width * height) / 2; i++)//{// uv_buf[i] = 128;//}//读原文件fread(y_buf, 1, width * height, or_file);fread(u_buf, 1, (width * height) / 4, or_file);fread(v_buf, 1, (width * height) / 4, or_file);//原文件概率分布FILE* ori;ori = fopen("ori_frequency.txt", "wb");double frequency[256] = { 0 };Frequency(y_buf, frequency, height, width);fprintf(ori, "%s\t%s\n", "symbol", "freq");for (int i = 0; i < 256; i++){fprintf(ori, "%d\t%f\n", i, frequency[i]);}DPCM(y_buf, pre_buf, re_buf, width, height, bnum);//计算PSNRdouble psnr;psnr = PSNR(y_buf, re_buf, width, height, bnum);cout << "The PSNR of " << or_n << " is " << psnr << endl;//写预测误差文件fwrite(pre_buf, 1, width * height, pre_file);fwrite(u_buf, 1, (width * height) / 4, pre_file);fwrite(v_buf, 1, (width * height) / 4, pre_file);// //写预测误差文件//fwrite(pre_buf, 1, width * height, pre_file);//fwrite(uv_buf, 1, (width * height) / 2, pre_file); //处理birds//预测误差文件概率分布FILE* pre;pre = fopen("pre_frequency.txt", "wb");double frequency_[256] = { 0 };Frequency(pre_buf, frequency_, height, width);fprintf(pre, "%s\t%s\n", "symbol", "freq");for (int i = 0; i < 256; i++){fprintf(pre, "%d\t%f\n", i, frequency_[i]);}//写重建图像文件fwrite(re_buf, 1, width * height, re_file);fwrite(u_buf, 1, (width * height) / 4, re_file);fwrite(v_buf, 1, (width * height) / 4, re_file);fclose(or_file);fclose(pre_file);fclose(re_file);delete[] y_buf;delete[] u_buf;delete[] v_buf;delete[] pre_buf;delete[] re_buf;return 0;}
8bit量化:
PSNR:
预测和重建图像:
4bit:
原始图像 | 原始大小 | 直接熵编码后大小 | 压缩比 | DPCM+熵编码大小 | 压缩比 |
lena256b.yuv |
96 | 68.2 | 1.4 | 45 | 2.1 |
birds.yuv | 576 | 519 | 1.1 | 191 | 3.0 |
DPCM差分预测编码相关推荐
- 数据压缩第六周作业——DPCM预测编码
目录 实验要求 实验原理 实验内容 实验步骤 实验代码 1.将bmp文件转换为yuv文件(使用之前做的bmptoyuv代码) 2.新建项目,设置命令行参数 3.main函数 4.定义DPCM函数 5. ...
- [数据压缩]_实验③ DPCM编码
实验4 DPCM压缩 文章目录 实验4 DPCM压缩 一.实验名称 二.实验目的 三.实验内容 1.DPCM编码原理 2.DPCM编码系统的设计 四.实验步骤 1.method.h头文件 2.main ...
- 6.1 Python图像处理之图像编码技术和标准-DPCM编码
6.1 Python图像处理之图像编码技术和标准-DPCM编码 文章目录 6.1 Python图像处理之图像编码技术和标准-DPCM编码 1 算法原理 2 代码 3 效果 1 算法原理 预测编码利用的 ...
- DPCM编码算法实现
目录 一.DPCM编解码原理 二.DPCM编码系统设计 三.算法实现 1.代码 2.运行结果 3.结果分析 一.DPCM编解码原理 DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统.在DPC ...
- DPCM算法编码实现
目录 一.DPCM系统 1.DPCM编解码原理 2.量化误差 3.DPCM编解码系统设计 二.算法实现 1.素材准备 2.主程序 3.DPCM 4.PSNR 三.实验结果 一.DPCM系统 1.DPC ...
- [数据压缩作业6]DPCM压缩系统的实现和分析
目录 (一)实验名称 (二)实验目的 (三)主要设备 (四)实验内容 一.原理 1. DPCM编解码 2. PSNR峰值信号噪声比 (五)实验步骤 一.DPCM编码系统的设计 二.代码 1. DPCM ...
- 数据压缩实验四--DPCM
数据压缩实验四--DPCM 实验原理 DPCM编解码原理 PSNR计算压缩质量 实验代码 DPCM.cpp main.cpp DPCM.h 实验步骤 实验图片的准备 命令参数 图像质量比较 8比特量化 ...
- 数据压缩【实验四】DPCM压缩系统的实现和分析
目录 一.实验目的 二.实验原理 三. 实验代码 (1)代码 (2)输出结果 四.实验结果 (1)压缩 (2) PSNR峰值信噪比 原理 算法 重建图像 五.实验分析 一.实验目的 掌握DPCM编解码 ...
- DPCM编码算法的实现与分析
目录 DPCM编解码原理 DPCM编码系统的设计 量化误差PSNR DPCM main.cpp 实验结果 实验总结 DPCM编解码原理 DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统.在D ...
- 数据压缩(8):DPCM 压缩系统的实现和分析
1.DPCM编解码原理 DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统.在DPCM系统中,需要注意的是预测器的输入是已经解码以后的样本.之所以不用原始样本来做预测,是因为在解码端无法得到原 ...
最新文章
- mysql 8.0创建远程连接用户
- 一张图片相对神经网络可能有几种属性?
- 网易云信荣获2021年度智慧教育典型案例奖项,并入选《智慧教育发展及产业图谱研究报告》...
- python递归创建目录_Node.js和Python使用递归查看目录文件和创建目录
- DOM(document object model),文档对象模型
- ROS学习笔记六:理解ROS服务和参数
- fatal error C1853 预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
- HDU2110 Crisis of HDU【母函数】
- cv::Mat转换RGB
- 201671010140. 2016-2017-2 《Java程序设计》java学习第十六周
- java是什么_Java是什么?Java的特点有哪些?
- 包级别的 TCP/UDP 负载均衡和NAT(Network Address Translate)
- Raucous Rockers_usaco3.4.4
- matlab的方法定义变量,Matlab定义变量的操作步骤
- 数学之美系列好文,强推
- Mac 配置多个ssh-key
- 在vue中使用three.js创建一个简单的立体图形
- 一款APP从设计稿到切图过程全方位揭秘
- 记一次失败的实战渗透
- Firebase简介
热门文章
- (原创)Lottie动画使用介绍
- 红米note2移动4g在哪里显示无服务器,小米 红米note2(移动版) 解锁教程
- 设备商网管软件定制开发案例分析
- 【论文撰写和程序员常用软件】
- 网页格式html转换成pdf的方法,将网页内容转化为PDF的三种方法
- DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
- 毕设讲解之 --- 如何完成小程序毕业设计
- 6款令人相见恨晚的在线搜索网站,成年后都会要用上,了解一下!
- 将数字金额转换为对应的中文大写金额
- java数字金额大写金额_Java将数字金额转为大写中文金额