目录
一、实验原理
1. DPCM编解码原理
DPCM是差分预测编码调制的缩写,是比较典型的预测编码系统。在DPCM系统中,需要注意的是预测器的输入是已经解码以后的样本。之所以不用原始样本来做预测,是因为在解码端无法得到原始样本,只能得到存在误差的样本。因此,在DPCM编码器中实际内嵌了一个解码器,如编码器中虚线框中所示。
在一个DPCM系统中,有两个因素需要设计:预测器和量化器。理想情况下,预测器和量化器应进行联合优化。实际中,采用一种次优的设计方法:分别进行线性预测器和
量化器的优化设计。
2. PSNR的计算
PSNR(峰值信噪比)是一种度量图像失真的方式,它的单位是dB。本实验使用PSNR作为图像质量评价的指标。峰值信噪比与图像质量近似成正比关系。PSNR值越大,就代表失真越少,图像质量越好。
二、实验代码
① dpcm.h
#pragma once
#ifndef DPCM_H_
#define DPCM_H_
void DPCM(unsigned char* y_buffer, unsigned char* differ_buffer, unsigned char* rebuild_buffer, int width, int height, int bitnum);
#endif
#pragma once
② dpcm.cpp
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
void DPCM(unsigned char* y_buffer, unsigned char* differ_buffer, unsigned char* rebuild_buffer, int width, int height, int bitnum)
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (j == 0)
{
differ_buffer[i * width] = ((y_buffer[i * width] - 128) + 255) / pow(2, (double)(9 - bitnum));
rebuild_buffer[i * width] = differ_buffer[i * width] * pow(2, (double)(9 - bitnum)) - 255 + 128;
}
else
{
differ_buffer[i * width + j] = ((y_buffer[i * width + j] - rebuild_buffer[i * width + j - 1]) + 255) / pow(2, (double)(9 - bitnum));
rebuild_buffer[i * width + j] = differ_buffer[i * width + j] * pow(2, (double)(9 - bitnum)) - 255 + rebuild_buffer[i * width + j - 1];
}
if (differ_buffer[i * width + j] > 255)
differ_buffer[i * width + j] = 255;
if (differ_buffer[i * width + j] < 0)
differ_buffer[i * width + j] = 0;
if (rebuild_buffer[i * width + j] > 255)
rebuild_buffer[i * width + j] = 255;
if (rebuild_buffer[i * width + j] < 0)
rebuild_buffer[i * width + j] = 0;
}
}
}
③ main.cpp
#include<stdlib.h>
#include<stdio.h>
#include"math.h"
#include"DPCM.h"
void calculate_fre(unsigned char* buffer, double* frequency, int width, int height)
{
int size = width * height;
for (int i = 0; i < size; i++)
{
frequency[buffer[i]]++;
}
for (int k = 0; k < 256; k++)
{
frequency[k] /= size;
}
}
int main(int argc, char** argv)
{
const char* ori_name = argv[1];
const char* differ_name = argv[2];
const char* rebu_name = argv[3];
int bitnum = atoi(argv[4]);
FILE* ori_file = NULL;
FILE* differ_file = NULL;
FILE* rebu_file = NULL;
if ((ori_file = fopen(ori_name, "rb")) == NULL)
printf("Failed to open the original picture\n");
else
printf("succeeded to open the original picture\n");
if ((differ_file = fopen(differ_name, "wb")) == NULL)
printf("Failed to open the difference picture\n");
else
printf("succeeded to open the difference picture\n");
if ((rebu_file = fopen(rebu_name, "wb")) == NULL)
printf("Failed to open the rebulid picture\n");
else
printf("succeeded to open the rebulid picture\n");
int width = 256;
int height = 256;
unsigned char* y_buffer = new unsigned char[width * height];
unsigned char