编程需要知道的知识点:
- 我们这次实现左向预测DPCM
对于第一列像素点,我们假设它左边的像素点值为128,先用第一列原始图像像素点的值减去128,得到当前位置的残差,再用当前位置的残差加上左边的像素点值,得到当前位置的重建图像像素点。
对于其他像素点,我们用当前位置的原始图像像素点的值减去重建图像当前位置左边那个像素点,得到当前位置的残差,再用当前位置得到的残差加上重建图像当前位置左边那个像素点的值,得到当前位置的重建图像像素点 - 量化
对于每一个残差像素点的量化具体实现为:
由于残差的取值范围为-255~255,我们先将他缩小范围 到0~255,加255除以2即可,再除以量化间隔,即2的8次方除以2的量化比特数次方,8bit量化即间隔为1,向下取整后再乘以量化间隔,将此时的值作为残差图像像素点输出。
为了计算当前位置重建图像像素点,我们需要将量化后的残差乘2再减去255. - PSNR计算
均方差:
实际上就是两幅图每个像素点的差值的平方累加起来,最后除以总的像素点个数,即宽乘高
PSNR实际上就是10乘log以10为底的(255乘255除以mse)
程序图像结果
8bit量化时
4bit量化时
2bit量化时
1bit量化时
图像质量评估
可以从上看到量化比特数越小,重建图像质量越差
PSNR大于40时,图像质量是极好的,20到30为较差,20以下为不可接受
压缩率分析
进行DPCM后,由于重复字段增多,熵编码压缩率大幅度提高。
源码
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
const char* out_path_1 = "output.yuv";
const char* out_path_2 = "wucha.yuv";
const char* in_path = "Lena256B.yuv";
int w = 256;
int h = 256;
unsigned char* buffer = new unsigned char[w * h];
unsigned char* uvbuf = new unsigned char[w * h * 0.5];
int i, j, k;
// 原始数据
double** data;
data = new double* [h];
for (int i = 0; i < h; i++)
{
data[i] = new double[w];
}
// 重建图像的数据
double** output;
output = new double* [h