700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > dct变换编码研究课设实验报告_二维DCT变换的实现

dct变换编码研究课设实验报告_二维DCT变换的实现

时间:2023-02-05 02:06:56

相关推荐

dct变换编码研究课设实验报告_二维DCT变换的实现

#include

#include

#include

#include

#include

#include

using namespace std;

/************************************************************************/

/* project:二维DCT变换的实现 / 2D DCT Test author:桑来 date:/10/31 */

/************************************************************************/

#define PI (3.1415926)

#define N (8) /* 当前切成8x8的块进行DCT变换 */

const int width = 256, height = 256;

const int frame_size = height*width;

/* ** 读取yuv文件 ** 取其y分量 */

void read_yuv(const char *file_name_yuv, unsigned char y_buff[height][width]){

FILE *fin = fopen(file_name_yuv, "rb+");

unsigned char *yuv_buff = (unsigned char*)malloc(frame_size * 3 / 2);

fread(yuv_buff, 1, frame_size * 3 / 2, fin);

for (int j = 0; j < height; j++){

for (int i = 0; i < width; i++){

y_buff[j][i] = yuv_buff[j*width + i];

}

}

fclose(fin);

}

/* ** 输出某个块的DCT变换的矩阵 ** DCT_block:指针,指向[N][N]的某个块 */

void visit(const double(*DCT_block)[N][N]){

for (int i = 0; i < N; i++){

for (int j = 0; j < N; j++){

printf("%lf\t", (*DCT_block)[i][j]);

}

cout << endl;

}

}

void visit(const unsigned char(*block)[N][N]){

for (int i = 0; i < N; i++){

for (int j = 0; j < N; j++){

printf("%d\t", (*block)[i][j]);

}

cout << endl;

}

}

/* ** 二维IDCT变换 ** block:指针,指向DCT变换后的[N][N]的某个块 ** IDCT_block:指针,指向反变换后的块 */

void IDCT(const double(*block)[N][N], double(*IDCT_block)[N][N]){

// 申请临时空间

double *tmp = new double[N*N];

double *coff = new double[N*N];

memset(tmp, 0, sizeof(double)*N*N);

// 设置IDCT系数

coff[0] = 1.0 / sqrt((double)N);

for (int m = 1; m < N; m++){

coff[m] = sqrt((double)2) / sqrt((double)N);

}

// 实现IDCT变换

for (int k = 0; k < N; k++){

for (int n = 0; n < N; n++){

for (int x = 0; x < N; x++){

tmp[k*N + n] += coff[x] * (*block)[k][x] * cos((2 * n + 1)*x*PI / 2 / N);

}

}

}

for (int m = 0; m < N; m++){

for (int n = 0; n < N; n++){

for (int x = 0; x < N; x++){

(*IDCT_block)[m][n] += coff[x] * tmp[x*N + n] * cos((2 * m + 1)*x*PI / 2 / N);

}

}

}

// 销毁分配的空间

delete[]tmp;

delete[]coff;

}

/* ** 二维DCT变换 ** block:指针,指向[N][N]的某个块 ** DCT_block:指针,指向变换后的块 */

void DCT(const unsigned char (*block)[N][N],double (*DCT_block)[N][N]){

// 申请临时空间

double *tmp = new double[N*N];

double *coff = new double[N*N];

memset(tmp, 0, sizeof(double)*N*N);

// 设置DCT系数

coff[0] = 1.0 / sqrt((double)N);

for (int m = 1; m < N; m++){

coff[m] = sqrt((double)2) / sqrt((double)N);

}

// 实现DCT变换

for (int m = 0; m < N; m++){

for (int l = 0; l < N; l++){

for (int x = 0; x < N; x++){

tmp[m*N + l] += coff[l] * (*block)[m][x] * cos((2 * x + 1)*PI*l / (2 * N));

}

}

}

for (int k = 0; k < N; k++){

for (int l = 0; l < N; l++){

for (int x = 0; x < N; x++){

(*DCT_block)[k][l] += coff[k] * tmp[x*N + l] * cos((2 * x + 1)*PI*k / (2 * N));

}

}

}

// 销毁分配的空间

delete[]tmp;

delete[]coff;

}

int main(){

// 计算能分解成多少个8x8的块

// 考虑当width或height不能被N整除,填充

const unsigned int num_of_NxN = (height%N ? (height / N) + 1 : (height / N)) * (width%N ? (width / N + 1) : (width / N));

//printf("一共将%dx%d分辨率的图片切成%d个8x8的小块\n", width, height, num_of_NxN);

const char *file_name_yuv = "E:\\sample\\lenna_256x256_yuv420p.yuv";

unsigned char y_buff[height][width];

read_yuv(file_name_yuv, y_buff);

// 将一幅图片切成8*8块 存储在block中.

unsigned char block[num_of_NxN][N][N];

memcpy(block, y_buff, frame_size);

// DCT_block存放DCT变换后的系数

double DCT_block[num_of_NxN][N][N] = { 0 };

// 对每一个8x8块进行DCT变换

for (int i = 0; i < 1; i++){

DCT(&block[i], &DCT_block[i]);

}

// 打印变换前的某个块:

printf("\n打印进行DCT变换之前的块:\n");

visit(&block[0]);

// 打印某个变换后的块

printf("\n打印进行DCT变换之后的块:\n");

visit(&DCT_block[0]);

// IDT_block存放IDCT变换后的系数

// 这里只开辟了一个块的大小

double IDCT_block[1][N][N] = { 0 };

IDCT(&DCT_block[0], &IDCT_block[0]);

// 打印逆变换后的块

printf("\n打印进行IDCT变换之后的块:\n");

visit(&IDCT_block[0]);

printf("\n");

system("pause");

return 0;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。