我试图在 C 中实现正向和反向离散余弦变换(DCT)。代码是通过 dct() 函数将单个输入像素块转换为变换矩阵,然后通过 idct( ) 功能。请参阅随附的代码。我的 idct 输出是 244、116、244、116 等的连续值。从 idct 值的外观来看,我的程序似乎无法正常工作。有人可以帮我看看我的结果是什么应该期待每个功能之后?显然,在 idct 之后,我应该非常接近原始输入矩阵。
谢谢
# include <stdio.h>
# define PI 3.14
void dct(float [][]); // Function prototypes
void idct(float [][]); // Function prototypes
void dct(float inMatrix[8][8]){
double dct,
Cu,
sum,
Cv;
int i,
j,
u,
h = 0,
v;
FILE * fp = fopen("mydata.csv", "w");
float dctMatrix[8][8],
greyLevel;
for (u = 0; u < 8; ++u) {
for (v = 0; v < 8; ++v) {
if (u == 0) {
Cu = 1.0 / sqrt(2.0);
} else {
Cu = 1.0;
}
if (v == 0) {
Cv = 1.0 / sqrt(2.0);
} else {
Cu = (1.0);
}
sum = 0.0;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
// Level around 0
greyLevel = inMatrix[i][j];
dct = greyLevel * cos((2 * i + 1) * u * PI / 16.0) *
cos((2 * j + 1) * v * PI / 16.0);
sum += dct;
}
}
dctMatrix[u][v] = 0.25 * Cu * Cv * sum;
fprintf(fp, "\n %f", dctMatrix[u][v]);
}
fprintf(fp, "\n");
}
idct(dctMatrix);
}
void idct(float dctMatrix[8][8]){
double idct,
Cu,
sum,
Cv;
int i,
j,
u,
v;
float idctMatrix[8][8],
greyLevel;
FILE * fp = fopen("mydata.csv", "a");
fprintf(fp, "\n Inverse DCT");
for (i = 0; i < 8; ++i) {
for (j = 0; j < 8; ++j) {
sum = 0.0;
for (u = 0; u < 8; u++) {
for (v = 0; v < 8; v++) {
if (u == 0) {
Cu = 1.0 / sqrt(2.0);
} else {
Cu = 1.0;
}
if (v == 0) {
Cv = 1.0 / sqrt(2.0);
} else {
Cu = (1.0);
}
// Level around 0
greyLevel = dctMatrix[u][v];
idct = (greyLevel * cos((2 * i + 1) * u * PI / 16.0) *
cos((2 * j + 1) * v * PI / 16.0));
sum += idct;
}
}
idctMatrix[i][j] = 0.25 * Cu * Cv * sum;
fprintf(fp, "\n %f", idctMatrix[i][j]);
}
fprintf(fp, "\n");
}
}
int main() {
float
testBlockA[8][8] = { {255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255},
{255, 255, 255, 255, 255, 255, 255, 255} },
testBlockB[8][8] = {{255, 0, 255, 0, 255, 0, 255, 0},
{0, 255, 0, 255, 0, 255, 0, 255},
{255, 0, 255, 0, 255, 0, 255, 0},
{0, 255, 0, 255, 0, 255, 0, 255},
{255, 0, 255, 0, 255, 0, 255, 0},
{0, 255, 0, 255, 0, 255, 0, 255},
{255, 0, 255, 0, 255, 0, 255, 0},
{0, 255, 0, 255, 0, 255, 0, 255} };
dct(testBlockB);
}