原理框图:

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

实验目的:

  • 进行不同量化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差分预测编码相关推荐

  1. 数据压缩第六周作业——DPCM预测编码

    目录 实验要求 实验原理 实验内容 实验步骤 实验代码 1.将bmp文件转换为yuv文件(使用之前做的bmptoyuv代码) 2.新建项目,设置命令行参数 3.main函数 4.定义DPCM函数 5. ...

  2. [数据压缩]_实验③ DPCM编码

    实验4 DPCM压缩 文章目录 实验4 DPCM压缩 一.实验名称 二.实验目的 三.实验内容 1.DPCM编码原理 2.DPCM编码系统的设计 四.实验步骤 1.method.h头文件 2.main ...

  3. 6.1 Python图像处理之图像编码技术和标准-DPCM编码

    6.1 Python图像处理之图像编码技术和标准-DPCM编码 文章目录 6.1 Python图像处理之图像编码技术和标准-DPCM编码 1 算法原理 2 代码 3 效果 1 算法原理 预测编码利用的 ...

  4. DPCM编码算法实现

    目录 一.DPCM编解码原理 二.DPCM编码系统设计 三.算法实现 1.代码 2.运行结果 3.结果分析 一.DPCM编解码原理 DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统.在DPC ...

  5. DPCM算法编码实现

    目录 一.DPCM系统 1.DPCM编解码原理 2.量化误差 3.DPCM编解码系统设计 二.算法实现 1.素材准备 2.主程序 3.DPCM 4.PSNR 三.实验结果 一.DPCM系统 1.DPC ...

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

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

  7. 数据压缩实验四--DPCM

    数据压缩实验四--DPCM 实验原理 DPCM编解码原理 PSNR计算压缩质量 实验代码 DPCM.cpp main.cpp DPCM.h 实验步骤 实验图片的准备 命令参数 图像质量比较 8比特量化 ...

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

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

  9. DPCM编码算法的实现与分析

    目录 DPCM编解码原理 DPCM编码系统的设计 量化误差PSNR DPCM main.cpp 实验结果 实验总结 DPCM编解码原理 DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统.在D ...

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

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

最新文章

  1. mysql 8.0创建远程连接用户
  2. 一张图片相对神经网络可能有几种属性?
  3. 网易云信荣获2021年度智慧教育典型案例奖项,并入选《智慧教育发展及产业图谱研究报告》...
  4. python递归创建目录_Node.js和Python使用递归查看目录文件和创建目录
  5. DOM(document object model),文档对象模型
  6. ROS学习笔记六:理解ROS服务和参数
  7. fatal error C1853 预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
  8. HDU2110 Crisis of HDU【母函数】
  9. cv::Mat转换RGB
  10. 201671010140. 2016-2017-2 《Java程序设计》java学习第十六周
  11. java是什么_Java是什么?Java的特点有哪些?
  12. 包级别的 TCP/UDP 负载均衡和NAT(Network Address Translate)
  13. Raucous Rockers_usaco3.4.4
  14. matlab的方法定义变量,Matlab定义变量的操作步骤
  15. 数学之美系列好文,强推
  16. Mac 配置多个ssh-key
  17. 在vue中使用three.js创建一个简单的立体图形
  18. 一款APP从设计稿到切图过程全方位揭秘
  19. 记一次失败的实战渗透
  20. Firebase简介

热门文章

  1. (原创)Lottie动画使用介绍
  2. 红米note2移动4g在哪里显示无服务器,小米 红米note2(移动版) 解锁教程
  3. 设备商网管软件定制开发案例分析
  4. 【论文撰写和程序员常用软件】
  5. 网页格式html转换成pdf的方法,将网页内容转化为PDF的三种方法
  6. DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
  7. 毕设讲解之 --- 如何完成小程序毕业设计
  8. 6款令人相见恨晚的在线搜索网站,成年后都会要用上,了解一下!
  9. 将数字金额转换为对应的中文大写金额
  10. java数字金额大写金额_Java将数字金额转为大写中文金额