Combined with experiment 2 code
1, Experimental purpose
Master the basic principle of DPCM codec system.
Preliminarily master the experiment, program the DPCM encoder with C/C++/Python and other languages, and analyze its compression efficiency.
2, Experimental principle
1.DPCM encoding and decoding principle
DPCM is the abbreviation of differential predictive coding modulation. It is a typical predictive coding system.
In DPCM system, it should be noted that the input of predictor is the decoded sample. The reason why the original samples are not used for prediction is that the original samples cannot be obtained at the decoding end, and only the samples with errors can be obtained.
Therefore, a decoder is actually embedded in the DPCM encoder, as shown in the dotted box in the encoder.
In a DPCM system, two factors need to be designed: predictor and quantizer. Ideally, the predictor and quantizer should be jointly optimized. In practice, a suboptimal design method is adopted: the optimal design of linear predictor and quantizer is carried out respectively.
2. Peak signal-to-noise ratio
3, Experimental code
1.main.cpp:
(1) Open up space
int main(int argc, char** argv) { /* variables controlable from command line */ u_int frameWidth = 352; /* --width=<uint> */ u_int frameHeight = 240; /* --height=<uint> */ unsigned int i; /* internal variables */ char* yuvFileName = NULL; char* reFileName = NULL; char* qFileName = NULL; FILE* yuvFile = NULL; FILE* reFile = NULL; FILE* qFile = NULL; u_int8_t* fileBuf = NULL; u_int8_t* yBuf = NULL; u_int8_t* reBuf = NULL; u_int8_t* qBuf = NULL; u_int32_t videoFramesWritten = 0; yuvFileName = argv[1]; qFileName = argv[2]; reFileName = argv[3]; frameWidth = atoi(argv[4]); frameHeight = atoi(argv[5]);//atoi string to number
(2) Open the imported yuv file
yuvFile = fopen(yuvFileName, "rb"); if (yuvFile == NULL) { printf("cannot find yuv file\n"); exit(1); } else { printf("The input yuv file is %s\n", yuvFileName); }
(3) Open the output (to be written) reconstruction image and residual image
qFile = fopen(qFileName, "wb"); reFile = fopen(reFileName, "wb"); qBuf = (u_int8_t*)malloc(frameWidth * frameHeight); reBuf = (u_int8_t*)malloc(frameWidth * frameHeight); yBuf = (u_int8_t*)malloc(frameWidth * frameHeight); fileBuf = (u_int8_t*)malloc(frameWidth * frameHeight / 2); fread(yBuf, 1, frameWidth * frameHeight, yuvFile); DPCM(frameHeight, frameWidth, yBuf, qBuf, reBuf); for (int i = 0; i < frameWidth * frameHeight / 2; i++) { fileBuf[i] = 128; } fwrite(qBuf, 1, frameWidth * frameHeight, qFile); fwrite(fileBuf, 1, frameWidth * frameHeight / 2, qFile); fwrite(reBuf, 1, frameWidth * frameHeight, reFile); fwrite(fileBuf, 1, frameWidth * frameHeight / 2, reFile);
(4) Shut down
free(yBuf); free(qBuf); free(reBuf); free(fileBuf); fclose(qFile); fclose(reFile); fclose(yuvFile);
2.dpcm.cpp
(1)8bit
void DPCM(short int height, short int width, unsigned char* yuvBuf, unsigned char* qBuf, unsigned char* reBuf) { int size = width * height; for (int i = 0; i < size; i++) { if (i % width == 0) { //Determine whether it is the first pixel of each line qBuf[i] = yuvBuf[i]; reBuf[i] = yuvBuf[i]; } else { int dn = yuvBuf[i] - reBuf[i - 1];// The range of dn is - 255-255 //8-bit quantization, 0-255 dn >>= 1;//-127 - 127 int temp = dn + 128;//0 - 255 qBuf[i] = temp; reBuf[i] = qBuf[i] * 2 + reBuf[i - 1]; } } }
(2)4bit
void DPCM(short int height, short int width, unsigned char* yuvBuf, unsigned char* qBuf, unsigned char* reBuf) { int size = width * height; for (int i = 0; i < size; i++) { if (i % width == 0) { //Determine whether it is the first pixel of each line int k = 256 / pow(2, 4); qBuf[i] = int(yuvBuf[i] / k); reBuf[i] = int(yuvBuf[i] / k); } else { int dn = yuvBuf[i] - reBuf[i - 1];// The range of dn is - 255-255 //4-bit quantization dn >>= 5;//-7 - 7 int temp = dn + 8;//0 - 15 qBuf[i] = temp; reBuf[i] = qBuf[i] * 32 + reBuf[i - 1]; } } }
(3)2bit
void DPCM(short int height, short int width, unsigned char* yuvBuf, unsigned char* qBuf, unsigned char* reBuf) { int size = width * height; for (int i = 0; i < size; i++) { if (i % width == 0) { //Determine whether it is the first pixel of each line int k = 256 / pow(2, 6); qBuf[i] = int(yuvBuf[i] / k); reBuf[i] = int(yuvBuf[i] / k); } else { int dn = yuvBuf[i] - reBuf[i - 1];// The range of dn is - 255-255 //2-bit quantization dn >>= 7;//-1 - 1 int temp = dn + 2;//0 - 3 qBuf[i] = temp; reBuf[i] = qBuf[i] * 128 + reBuf[i - 1]; } } }
(4)1bit
void DPCM(short int height, short int width, unsigned char* yuvBuf, unsigned char* qBuf, unsigned char* reBuf) { int size = width * height; for (int i = 0; i < size; i++) { if (i % width == 0) { //Determine whether it is the first pixel of each line int k = 256 / pow(2, 7); qBuf[i] = int(yuvBuf[i] / k); reBuf[i] = int(yuvBuf[i] / k); } else { int dn = yuvBuf[i] - reBuf[i - 1];// The range of dn is - 255-255 //1-bit quantization dn >>=8; int temp = dn + 1; qBuf[i] = temp; reBuf[i] = qBuf[i] * 256 + reBuf[i - 1]; } } }
4, Experimental results
Original drawing:
1.8bit:
2.4bit:
3.2bit:
4.1bit:
5, Experimental analysis
1. Compare coding quality:
Calculate the peak signal-to-noise ratio between the original image and the reconstructed image under their respective quantization standards:
psnr.cpp:
#include <math.h> double psnr(unsigned char* ybuf, unsigned char* rebuf, int height, int width) { double mse = 0; double div = 0; double psnr = 0; for (int v = 0; v < height; v++) { for (int u = 0; u < width; u++) { div = rebuf[v * width + u] - ybuf[v * width + u]; mse += div * div; } } mse = mse / (width * height); psnr = 10 * log10(255 * 255 / mse); return psnr; }
In main CPP add before closing the file:
double ps = psnr(yBuf, reBuf, frameHeight, frameWidth); cout << ps;
8bit: 51.7761
4bit: 23.1471
2bit: 14.8853
1bit: 10.0007
2. Compare coding efficiency:
Using the executable program encoded by Huffman, we get two huff file
(1) Write the prediction error image to a file and input the file into Huffman encoder
(2) Input the original image file into Huffman encoder
Compare the coding efficiency (compression ratio and image quality) between the two systems (1.DPCM + entropy coding and 2. Entropy coding only)
Former: (96-32.6) / 96
Latter: (96-80.7) / 96
summary
It's hard