实验四 DPCM 压缩系统的实现和分析
来源:互联网 发布:php和java的混合编程 编辑:程序博客网 时间:2024/06/08 11:56
一、实验原理
1. 预测编码
在数字图像中,如果不是随机的噪声,那么每个像素与其周围的像素都会存在着一定的关联,像素值很大程度上依赖于其邻域中其它像素的值。也就是预测误差(在这个实验中用当前像素值与前一个像素值的差来表示)应该非常接近,通常比单个的像素值要小。因此如果只存储预测误差,由预测误差也可以重构出原图像,而且这样可以降低图像中的冗余信息,实现图像的压缩。
如果用前面几个样值的线性组合来预测当前的样值,称为线性预测,只用前一个样值进行预测,就称为 DPCM 。
2. DPCM 编解码框图
从框图中可以看出,由于需要更新预测值,编码器中已经内嵌了一个解码器。
二、实验流程及代码分析
从框图可以看出,本实验的编码流程如下
实验用图像均为 BMP 格式,使用实验二中的方法读入 BMP 图像并提取出亮度通道 Y 。在下面的代码中, Y 通道的值已经存在了 yBuf 中。另外在每一行中,由于第一个像素的前面没有像素,因此假设它的预测值为平均灰度值 128 。
//命令行参数:输入图像名、误差图像名、重建图像名、量化比特数unsigned char g(int x) //防止超过 0 到 255 的动态范围{ if (x < 0) return 0; if (x > 255) return 255; return x;}...int Qbits = atoi(argv[4]); // Qbits 为量化比特数...unsigned char* diffBuf = (unsigned char*)malloc(width*height); //量化预测误差存储区unsigned char* reBuf = (unsigned char*)malloc(width*height); //重建图像存储区int ek; //原始的预测误差值,范围从 -255 到 +255int scale = 512 / (1<<Qbits); //误差值的压缩比率for (i = 0; i < height; i++) //行循环{ //对每行第一个像素的处理 ek = yBuf[width*i] - 128; //假设第一个像素的预测值为128 diffBuf[width*i] = (ek + 255) / scale; //量化后的预测误差 reBuf[width*i] = g((diffBuf[width*i] - 255 / scale)*scale + 128); //根据预测误差再重建当前电平值 for (j = 1; j < width; j++) //列循环 { //后面的像素与第一个像素处理方法一样 ek = yBuf[j + width*i] - reBuf[j - 1 + width*i]; diffBuf[j + width*i] = (ek + 255) / scale; reBuf[j + width*i] = g((diffBuf[j + width*i] - 255 / scale)*scale + reBuf[j - 1 + width*i]); }}
代码很短,外层循环为图像中每一行的循环,每行起始像素的预测值设为 128,单独对其进行预测并重建。首先得到差值 ek,像素灰度值范围从 0 到 255,那么两个像素灰度值之差 ek 的范围从 -255 到 255。由于要存储误差图像,那么先把负灰度值变成正的,也就是 ek + 255,在 0 到 510 这个区间内再做量化,区间长度可以看成 9 bit,512 级。
要将预测误差作为一幅图像显示以观察预测结果,那么最基本的要做 8 bit量化,将误差范围压缩在 0 到 255 之间,也就是误差值除以 2 下取整。 7 bit 量化,误差值要除以 4 下取整。因此定义了变量 scale 用于对误差值进行量化,量化预测误差存储到 diffBuf 中。
最后要根据量化值重建当前像素值以用于下一个像素的预测。 误差已经量化了,因此要得到原本的误差要先乘以比率 scale 再减去 255 ,就得到了真实的量化误差。但是对比一下这样两种代码
y[i] = diff * scale - 255 + y[i - 1];y[i] = (diff - 255/scale) * scale + y[i - 1];
对于量化比特数的不同,误差移动的范围也不同。在对误差的量化,也就是 (ek + 255) / scale 中,如果是 4 bit 量化,scale = 32,那么 ek = 0 对应 7,重建时 7×32-255 = -31,对应上面的第一种写法,重建结果不对。这种问题的原因在于端点值 255 也被量化了,由于取整的存在,重建时的正确表达式应为 (7-255/32)×32 = 0,也就是第二种写法。
最后还要解决一个问题,就是这样做可能会超出动态范围。考虑图像不使用差分编码,直接量化:
int scale = 256 / (1 << (Qbits - 1));reBuf[j + width*i] = yBuf[j + width*i] / scale*scale;
如果对误差图像进行量化,也就是要对 512 级灰度进行量化,而对原图像的直接量化是对 256 级灰度量化,因此如果要得到相同的灰度级数,直接量化的量化比特数要比误差的量化比特数少 1。表 1 为一个量化比特数为 3 的示例,也就是直接量化为 2 bit 量化,共有 4 级灰度。
三、实验结果
1. 两种方法编码效率的对比
差分预测编码可降低图像中的冗余信息,那么对量化后的误差图像进行实验三中的 Huffman 编码可以得到比直接进行 Huffman 编码更高的压缩效率。表 2 中为几种图像的量化误差分布情况,表 3 为两种压缩方法的对比。
2. 不同量化比特数的对比
上表中都是对误差进行 8 bit 量化,下面的表 4 进行了不同量化比特数之间的对比,图 1 为原始图像。
p[j + width*i] = diffBuf[j + width*i] * scale / 2;
比如 4 bit 量化的误差图像,量化误差全部变换成正值后最大值为 16,那么把最大值乘以之前定义的缩放比率 scale(512 / 2^n),这里是 32 ,再除以 2 之后就变到了 0 ~ 255 区间内。量化比特数越少,误差 0 对应的灰度值就越小,4 bit 量化时误差 0 对应量化值 7,在误差图像中为 7 × 16 = 112,而 8 bit量化时误差 0 对应量化值 127,在误差图像中也为 127,因此表格中从上到下误差图像会越来越暗。
- 实验四 DPCM 压缩系统的实现和分析
- 数据压缩实验四:DPCM 压缩系统的实现和分析
- 实验四 DPCM压缩系统的实现和分析
- 实验四 DPCM压缩系统的实现和分析
- 数据压缩实验四 DPCM 压缩系统的实现和分析
- 数据压缩 实验四 DPCM压缩系统的实现和分析
- 数据压缩 实验四 DPCM压缩系统的实现和分析
- 数据压缩实验四 DPCM压缩系统的实现与分析
- 数据压缩实验四——DPCM压缩系统的实现和分析
- 数据压缩原理与应用 实验四 DPCM 压缩系统的实现和分析
- 数据压缩原理 实验四 DPCM压缩系统的实现和分析
- DPCM 压缩系统的实现和分析
- DPCM 压缩系统的实现和分析
- DPCM 压缩系统的实现和分析
- 【数据压缩】DPCM 压缩系统的实现和分析
- 数据压缩实验四--dpcm压缩系统
- 实验报告4_DPCM压缩系统的实现和分析
- 实验四-dpcm编码
- 线索化二叉树 前中后序线索化及前序中序遍历
- C6678多核DSP开发——image_processing例程
- hive之UDF编程
- 用python做http协议的api自动化测试二
- 写篇博文记录下自己实现maven自动化部署到服务器的心得
- 实验四 DPCM 压缩系统的实现和分析
- 【bzoj2301】[HAOI2011]Problem b
- 自己整合的Android mvp+singlenet小框架
- Easy Java
- Jmeter连接Oracle数据库
- Centos7下安装多python版本并存开发环境
- Jquery分页插件开发
- C、C++存储区域
- CentOS7Jenkins安装