我必须为我的项目做图像的2D DCT。
我翻译了公式编码的权利。从逻辑上来说,这一切似乎都很好,但没有给出所需的结果。我已经用matlab函数对它进行了检查,以检查3x3矩阵的结果,但是它们是不正确的。

另外,我编码的方式和方式给出了大量的循环,因此实际的图像操作需要花费数小时才能计算出来。

任何减少循环和指出程序错误的建议都是很好的。
谢谢。

这是我的代码。

    double alpha_p, alpha_q;
    double pi = Math.atan(1.0) * 4.0;
    //dct begins
    System.out.println("it begins");
    for (int p = 0; p < M; p++) {
        for (int q = 0; q < N; q++) {
            if (p == 0)
                alpha_p = 1 / sqrt(M);
            else
                alpha_p = sqrt(2 / M);
            if (q == 0)
                alpha_q = 1 / sqrt(N);
            else
                alpha_q = sqrt(2 / N);
            double toreturn = 0;
            for (int m = 0; m < M; m++) {
                for (int n = 0; n < N; n++) {
                    toreturn = toreturn + img[m][n]
                            * cos(((2 * m + 1) * p * pi) / 2 * M)
                            * cos(((2 * n + 1) * q * pi) / 2 * N);
                }
            }
            dctimg[p][q] = alpha_p * alpha_q * toreturn;
            System.out.println("euta");
        }
    }
    // dct over
    System.out.println("its over");

    //inverse dct begins
    for (int m = 0; m < M; m++) {
        for (int n = 0; n < N; n++) {
            double toreturn = 0;
            for (int p = 0; p < M; p++) {
                for (int q = 0; q < N; q++) {
                    if (p == 0)
                        alpha_p = 1 / sqrt(M);
                    else
                        alpha_p = sqrt(2 / M);
                    if (q == 0)
                        alpha_q = 1 / sqrt(N);
                    else
                        alpha_q = sqrt(2 / N);
                    toreturn = toreturn + alpha_p * alpha_q * dctimg[p][q]
                                          * cos(((2 * m + 1) * p * pi) / 2 * M)
                                          * cos(((2 * n + 1) * q * pi) / 2 * N);
                }
            }
            finalimg[m][n] = toreturn;
        }
    }
    //inverse dct over

最佳答案

首先,在DCT的公式中,cos的分母为2 * M。这是一个典型的错误。 4 / 2 * 2 = 4不是1

cos(((2 * m + 1) * p * pi) / 2 * M)应该是cos(((2 * m + 1) * p * pi) / (2 * M))

在所有四种情况下都需要括号。



我想提的另一个时刻是sqrt(2 / M)。如果M具有整数类型(代码中不清楚),并且它大于2,则表达式2 / M等于0。因为两个操作数都具有整数类型,并且/仅给出整数部分。要解决此问题,请添加一个类似于sqrt(2.0 / M)的浮点。



正如您已经注意到的,有很多循环,换句话说,2D DCT II的复杂度是O(n^4)

在现实生活中,没有人将DCT应用于整个实际图像。图像被分成大小为8x8的块,每个块都由DCT处理。这种方法可以将n保持在较低水平,并且复杂度可以接受。

为了降低算法复杂度,我想链接here,其中很好地解释了使用一维DCT和FFT的方法。

关于java - 2D DCT程序不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45116919/

10-10 19:35