Here I have a DCT algorithm class with the methods "applyDCT" and "applyIDCT". Technically, after performing a direct DCT (discrete cosine transform) in a 2x2 table of random numbers from 0 to 255, and then immediately doing the reverse DCT on these numbers, we must return to the original integers that we had in the first place. In my case, this is not the case. What am I doing wrong here?
public class DCT {
private static final int N = 2;
private double[] c = new double[N];
public DCT() {
this.initializeCoefficients();
}
private void initializeCoefficients() {
for (int i=1;i<N;i++) {
c[i]=1;
}
c[0]=1/Math.sqrt(2.0);
}
public double[][] applyDCT(double[][] f) {
double[][] F = new double[N][N];
for (int u=0;u<N;u++) {
for (int v=0;v<N;v++) {
double sum = 0.0;
for (int i=0;i<N;i++) {
for (int j=0;j<N;j++) {
sum+=Math.cos(((2*i+1)/(2.0*N))*u*Math.PI)*Math.cos(((2*j+1)/(2.0*N))*v*Math.PI)*f[i][j];
}
}
sum*=((c[u]*c[v])/4.0);
F[u][v]=sum;
}
}
return F;
}
public double[][] applyIDCT(double[][] F) {
double[][] f = new double[N][N];
for (int u=0;u<N;u++) {
for (int v=0;v<N;v++) {
double sum = 0.0;
for (int i=0;i<N;i++) {
for (int j=0;j<N;j++) {
sum+=((c[u]*c[v]))*Math.cos(((2*i+1)/(2.0*N))*u*Math.PI)*Math.cos(((2*j+1)/(2.0*N))*v*Math.PI)*F[i][j];
}
}
sum/=4.0;
f[u][v]=sum;
}
}
return f;
}
}
And here is the main class that goes with it:
public class Main {
private static final int N = 2;
private static double[][] f = new double[N][N];
private static Random generator = new Random();
public static void main(String[] args) {
int value;
for (int x=0;x<N;x++) {
for (int y=0;y<N;y++) {
value = generator.nextInt(255);
f[x][y] = value;
System.out.println(f[x][y]+" => f["+x+"]["+y+"]");
}
}
DCT dctApplied = new DCT();
double[][] F = dctApplied.applyDCT(f);
System.out.println("From f to F");
System.out.println("-----------");
for (int x=0;x<N;x++) {
for (int y=0;y<N;y++) {
try {
System.out.println(F[x][y]+" => F["+x+"]["+y+"]");
} catch (Exception e) {
System.out.println(e);
}
}
}
double f[][] = dctApplied.applyIDCT(F);
System.out.println("Back to f");
System.out.println("---------");
for (int y=0;y<N;y++) {
for (int z=0;z<N;z++) {
System.out.println(f[y][z]+" => f["+y+"]["+z+"]");
}
}
}
}
Here is an example of the results:
149.0 => f[0][0]
237.0 => f[0][1]
122.0 => f[1][0]
147.0 => f[1][1]
From f to F
-----------
81.87499999999999 => F[0][0]
-14.124999999999993 => F[0][1]
14.62500000000001 => F[1][0]
-7.875 => F[1][1]
Back to f
---------
9.3125 => f[0][0]
14.812499999999998 => f[0][1]
7.624999999999999 => f[1][0]
9.187499999999998 => f[1][1]
As shown above, "Back to f" does not show the same values as in f initially ...
source
share