I have managed to calculate the dct of an 8*8 matrix and I am having trouble doing the inverse. Can anyone have a look at this code and tell me what I am doing now. I should be getting the exact same values as before but im getting different values. I am reading in the input from a csv file and out putting it to anther csv file. Its programmed in c
void idct_func(float inMatrix[8][8]){
double idct,
Cu,
sum,
Cv;
int i,
j,
u,
v;
float idctMatrix[8][8],
greyLevel;
FILE * fp = fopen("mydata.csv", "r");
FILE * wp = fopen("idct.csv", "w");
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
Cv = (1.0);
// Level around 0
greyLevel = idctMatrix[u][v];
idct = (greyLevel * cos((2 * i + 1) * u * M_PI / 16.0) *
cos((2 * j + 1) * v * M_PI / 16.0));
sum += idct;
}
}
idctMatrix[i][j] = 0.25 * Cu * Cv * sum;
fprintf(wp, "\n %f", idctMatrix[i][j]);
}
fprintf(wp, "\n");
}
the original matrix is:
{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}};
the dct is :
2040 0 -0 0 0 0 -0 -0
0 0 0 0 -0 0 -0 0
-0 0 -0 0 0 0 0 0
0 -0 -0 -0 0 -0 -0 0
0 0 -0 0 -0 -0 -0 0
0 -0 -0 -0 -0 0 -0 -0
-0 -0 -0 0 0 0 0 -0
-0 0 0 0 -0 0 -0 0
the idct calculated should be the same as the original
You're trying to calculate the IDCT in-place, using idctMatrix[][]
as both input and output and hence the input is being modified in the process. That's wrong. You need to have a separate 2-dimensional array for input (or output).
It also appears that the u- and v-dependent scaling factors Cu
and Cv
are applied outside of the u- and v- loops. That would be wrong too.
EDIT: Here's the code if you can't understand the words:
#include <stdio.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979324
#endif
void Compute8x8Dct(const double in[8][8], double out[8][8])
{
int i, j, u, v;
double s;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
s = 0;
for (u = 0; u < 8; u++)
for (v = 0; v < 8; v++)
s += in[u][v] * cos((2 * u + 1) * i * M_PI / 16) *
cos((2 * v + 1) * j * M_PI / 16) *
((i == 0) ? 1 / sqrt(2) : 1) *
((j == 0) ? 1 / sqrt(2) : 1);
out[i][j] = s / 4;
}
}
void Compute8x8Idct(const double in[8][8], double out[8][8])
{
int i, j, u, v;
double s;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
{
s = 0;
for (u = 0; u < 8; u++)
for (v = 0; v < 8; v++)
s += in[u][v] * cos((2 * i + 1) * u * M_PI / 16) *
cos((2 * j + 1) * v * M_PI / 16) *
((u == 0) ? 1 / sqrt(2) : 1.) *
((v == 0) ? 1 / sqrt(2) : 1.);
out[i][j] = s / 4;
}
}
void Print8x8(const char* title, const double in[8][8])
{
int i, j;
printf("%s\n", title);
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
printf("%8.3f ", in[i][j]);
printf("\n");
}
}
int main(void)
{
double pic1[8][8], dct[8][8], pic2[8][8];
int i, j;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
#if 01
pic1[i][j] = 255;
#else
pic1[i][j] = (i ^ j) & 1;
#endif
Print8x8("pic1:", pic1);
Compute8x8Dct(pic1, dct);
Print8x8("dct:", dct);
Compute8x8Idct(dct, pic2);
Print8x8("pic2:", pic2);
return 0;
}
Here's its output:
pic1:
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
dct:
2040.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
pic2:
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000
255.000 255.000 255.000 255.000 255.000 255.000 255.000 255.000