2017-07-15 21 views
0

私のプロジェクトでは、この2D DCTイメージを作成する必要があります。 コードに式を正しく翻訳しました。論理的にはすべてうまく見えますが、必要な結果は得られません。私は3x3の行列の結果を確認するためにmatlabの関数で集計しましたが、間違っています。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

知識を共有してくれてありがとう。 "数学.PI"うーん。 – user8311562

+0

[DFTを使用したDFCTの計算](https://stackoverflow.com/a/22779268/2521214)と[DFT/DFFTの計算方法](https://stackoverflow.com/a/26355569/2521214)を参照してください。互換性のあるDCTを使用していることを確認してください...私のメモリがうまくいけば、そのうちの4つがあります。 – Spektre

答えて

1

まず、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))

括弧は4つのすべての場合に必要とされています。


私が言いたいもう一つの瞬間はsqrt(2/M)です。 Mに整数型(コードでは不明)があり、それが2より大きい場合、式2/M0に等しくなります。どちらのオペランドも整数型を持ち、/は整数部分のみを与えるからです。これを修正するには、sqrt(2.0/M)のような浮動小数点を追加します。


すでに気づいたように、ループがたくさんあるが、他の言葉で、2D DCT IIの複雑さはO(n^4)です。

実生活では誰も実際の画像全体にDCTを適用しません。イメージは8x8サイズのブロックに分割され、各ブロックはDCTによって処理されます。このアプローチでは、nを低く保ち、複雑さは許容されます。

アルゴリズムの複雑さを軽減するために、1D DCTとFFTを使用する方法がよく説明されているhereをリンクしたいと考えています。

+0

あなたのよく説明された返事のためにEnegeさんありがとうございます。私は間違いを理解した。 8x8ブロックに適用することで複雑さを減らすことも試みます。 1つの良いことは、連続するDCTとIDCTの後に元のピクセル値を取得していることです。しかし、DCT係数はmatlabのテスト結果と一致しません。私はこのテストのために3x3マトリックスを試しました。それを並べ替える必要があります。 MATLABが標準として使用するブロックサイズを知っていますか? – user8311562

+0

@ user8311562、[https://gist.github.com/Ka6aSH/759​​4671a4d60aef7a12b0077e002d6a1]から[こちら](https://www.mathworks.com/help/images/ref/dct2)に記載されているDST2を一から削除しました。 .html)、MathLabオンライン 'J = dct2([11 12 13; 14 15 16; 17 18 19])で同じ入力でテストしました。結果は同じですが、別のエラーが発生する可能性があります。 私はよく分かりませんが、関数dst2はブロックを使用していないと思います。これは純粋な変換です。もう一つの疑問は、それがなぜとても速いのかです。答えは、MathLabは行列演算に高度に最適化されており、そのような性能に到達することは非常に困難です。 – Enegue

+0

ありがとうございました。すべてソートされました。 – user8311562

関連する問題