2d DCT程序不能正常工作

问题描述:

我必须为我的项目执行此图像的2d DCT。 我翻译了编码的权利。从逻辑上看,这一切似乎都很好,但它并没有给出所需的结果。我已经用matlab函数来检查3x3矩阵的结果,但它们不正确。2d DCT程序不能正常工作

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

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

这是我的代码。所有的

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 
+1

'double pi = Math.atan(1.0)* 4.0' ..或者你可以使用'Math.PI' – harold

+0

感谢分享知识。 “Math.PI”嗯。 – user8311562

+0

参见[使用DFFT计算DFCT](https://stackoverflow.com/a/22779268/2521214)和[如何计算DFT/DFFT](https://stackoverflow.com/a/26355569/2521214)。确保你使用的是兼容的DCT ......如果我的记忆效果很好,其中有4个...... – Spektre

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

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)


正如你已经注意到了,有很多循环,换句话说,该二维DCT II的复杂性是O(n^4)

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

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

+0

谢谢你,先生,请您解释清楚的答复。我意识到了错误。我会尝试通过应用8x8块来减少复杂性。一件好事是,现在我在连续的DCT和IDCT之后获得原始像素值。但是,DCT系数与matlab测试结果并不匹配。我为这个测试尝试了一个3x3矩阵。将不得不整理出来。你知道matlab使用什么块大小作为标准吗? – user8311562

+0

@ user8311562,我[实施](https://gist.github.com/Ka6aSH/759​​4671a4d60aef7a12b0077e002d6a1)从头开始描述DST2 [这里](https://www.mathworks.com/help/images/ref/dct2 .html)并在MathLab online'J = dct2([11 12 13; 14 15 16; 17 18 19]);''的相同输入上对其进行测试。结果是一样的,也许我们错过了另一个错误。 我不确定,但我认为函数dst2不使用块,它是一个纯粹的转换。另一个问题是为什么它如此之快?答案是MathLab针对矩阵运算进行了高度优化,并且很难达到这样的性能。 – Enegue

+0

谢谢Enegue。全部整理出来。 – user8311562