2017-07-15 99 views
0

我必須爲我的項目執行此圖像的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

回答

1

首先,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