与DCT和IDCT算法在java中存在的问题 [英] Problems with DCT and IDCT algorithm in java

查看:121
本文介绍了与DCT和IDCT算法在java中存在的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里,我有我的DCT算法类applyDCT和applyIDCT的方法。上随机整数的0和255之间一个2x2表做正向DCT(离散余弦变换),然后立即做一个反DCT这些数字后在技术上,我们应该回到我们不得不首先原始整数。就我而言,情况并非如此。我在做什么错在这里?

Here I have my DCT algorithm class with "applyDCT" and "applyIDCT" methods. Technically after doing a forward DCT (discrete cosine transform) on a 2x2 table of random integers between 0 and 255, and then immediately doing a reverse DCT on these numbers, we should come back to the original integer numbers we had in the first place. In my case, this is not so. 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;
            //sum*=((c[u]*c[v])/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) {
        // Generate random integers between 0 and 255
        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+"]");
            }
        }
    }
}

下面是示例结果:

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]

如上所示,返回到f不显示包含在f中相同的值最初...

As shown above, "Back to f" does not show the same values contained in f initially...

推荐答案

,我很抱歉,如果我的问题是不清楚,但这里是不是对的,我已经解决了这个问题:IDCT方法,必须有我的内心系数和j的循环:

I have resolved this problem, I am sorry if my question was unclear but here is what was not right: The IDCT method had to have the coefficient inside the i and j for loops :

public double[][] applyIDCT(double[][] F) {
        double[][] f = new double[N][N];
        for (int i=0;i<N;i++) {
          for (int j=0;j<N;j++) {
            double sum = 0.0;
            for (int u=0;u<N;u++) {
              for (int v=0;v<N;v++) {
                sum+=(c[u]*c[v])/4.0*Math.cos(((2*i+1)/(2.0*N))*u*Math.PI)*Math.cos(((2*j+1)/(2.0*N))*v*Math.PI)*F[u][v];
              }
            }
            f[i][j]=Math.round(sum);
          }
        }
        return f;
    }

这仅适用于数据的8×8区块,否则你就必须改变这一点:

This only works for a 8x8 bloc of data, or else you would have to change this:

(c[u]*c[v])/4.0)

弄成这个样子:

into something like this:

(2*c[u]*c[v])/Math.sqrt(M*N)

其中M和N是该表的dimentions ...

Where M and N are the dimentions of the table...

下面是结果数据的2×2块:

Here are the results with a 2x2 block of data:

Original values
---------------
54.0 => f[0][0]
35.0 => f[0][1]
128.0 => f[1][0]
185.0 => f[1][1]

From f to F
-----------
200.99999999999994 => F[0][0]
-18.99999999999997 => F[0][1]
-111.99999999999997 => F[1][0]
37.99999999999999 => F[1][1]

Back to f
---------
54.0 => f[0][0]
35.0 => f[0][1]
128.0 => f[1][0]
185.0 => f[1][1]

这篇关于与DCT和IDCT算法在java中存在的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆