DPCM编解码原理
PCM是差分预测编码调制的缩写,是比较典型的预测编码系统。在DPCM系统中,需要注意的是预测器的输入是已经解码以后的样本。之所以不用原始样本来做预测,是因为在解码端无法得到原始样本,只能得到存在误差的样本。因此,在DPCM编码器中实际内嵌了一个解码器,如编码器中虚线框中所示。在一个DPCM系统中,有两个因素需要设计:预测器和量化器。理想情况下,预测器和量化器应进行联合优化。实际中,采用一种次优的设计方法:分别进行线性预测器和量化器的优化设计。
编程实现的算法
#include<iostream>
#include <stdio.h>
#include<math.h>
using namespace std;
int main(int argc, char* argv[])
{
FILE* NOISE = NULL;
if ((fopen_s(&NOISE, "E://Study//test1//noise.yuv", "rb")) != 0)
{
cout << "打开文件失败" << endl;
}
else
{
cout << "打开文件成功" << endl;
}
FILE* RNOISE = NULL;
if ((fopen_s(&RNOISE, "E://Study//test1//rnoise.yuv", "wb")) != 0)
{
cout << "创建重建文件失败" << endl;
}
else
{
cout << "创建重建文件成功" << endl;
}
FILE* PNOISE = NULL;
if ((fopen_s(&PNOISE, "E://Study//test1//pnoise.yuv", "wb")) != 0)
{
cout << "创建误差文件失败" << endl;
}
else
{
cout << "创建误差文件成功" << endl;
}
int size;
fseek(NOISE, 0L, SEEK_END);
size = ftell(NOISE);
fseek(NOISE, 0L, SEEK_SET);
unsigned char* NOISE_BUFFER = new unsigned char[size];
unsigned char* RNOISE_BUFFER = new unsigned char[size];
unsigned char* PNOISE_BUFFER = new unsigned char[size];
unsigned char* Y_BUFFER = new unsigned char[size / 3];
fread(NOISE_BUFFER, sizeof(unsigned char), size, NOISE);
for (int i = 0; i < size / 3; i++)
{
Y_BUFFER[i] = NOISE_BUFFER[i];
}
unsigned char* Y_REBUILD = new unsigned char[size * 1 / 3];
unsigned char* E_BUFFER = new unsigned char[size * 1 / 3];
for (int i = 0; i < 500; i++)
{
for (int j = 0; j < 500; j++)
{
int k = 0;
if (j == 0)
{
Y_REBUILD[j + i * 500] = Y_BUFFER[j + i * 500];
E_BUFFER[j + i * 500] = 0;
}
if (j != 0)
{
k = Y_BUFFER[j + i * 500] - Y_REBUILD[j + i * 500 - 1];
E_BUFFER[j + i * 500] = (k + 256) / 2 - 1;
Y_REBUILD[j + i * 500] = 2 * (E_BUFFER[j + i * 500] + 1) + Y_REBUILD[j + i * 500 - 1];
}
if (E_BUFFER[j + i * 500] > 255)
{
E_BUFFER[j + i * 500] = 255;
}
if (E_BUFFER[j + i * 500] < 0)
{
E_BUFFER[j + i * 500] = 0;
}
if (Y_REBUILD[j + i * 500] > 255)
{
Y_REBUILD[j + i * 500] = 255;
}
if (Y_REBUILD[j + i * 500] < 0)
{
Y_REBUILD[j + i * 500] = 0;
}
}
}
for (int i = 0; i < size / 3; i++)
{
RNOISE_BUFFER[i] = Y_REBUILD[i];
RNOISE_BUFFER[size / 3 + i] = NOISE_BUFFER[size / 3 + i];
RNOISE_BUFFER[size / 3 + size / 3 + i] = NOISE_BUFFER[size / 3 + size / 3 + i];
}
for (int i = 0; i < size / 3; i++)
{
PNOISE_BUFFER[i] = E_BUFFER[i];
PNOISE_BUFFER[size / 3 + i] = NOISE_BUFFER[size / 3 + i];
PNOISE_BUFFER[size / 3 + size / 3 + i] = NOISE_BUFFER[size / 3 + size / 3 + i];
}
fwrite(RNOISE_BUFFER, sizeof(unsigned char), size, RNOISE);
fwrite(PNOISE_BUFFER, sizeof(unsigned char), size, PNOISE);
fclose(NOISE);
fclose(RNOISE);
fclose(PNOISE);
system("pause");
}
运行结果:
(分别为原图像,预测误差图像,重建图像)