pythonscipydct

In scipy why doesn't idct(dct(a)) equal to a?


I am trying to implement JPEG compression using python. When I tried to apply the DCT, quantization, IDCT process for a tiff image, I found something strange for scipy.fftpack.dct/idct.

Since there is only 1D dct/idct within scipy package, I was doing this for a 2D dct

import numpy as np
from scipy.fftpack import dct, idct

def dct2(block):
    return dct(dct(block.T).T)

def idct2(block):
    return idct(idct(block.T).T)

I tested the 2D dct/idct using a simple 3x3 matrix. I was expecting to get a True matrix with this test case.

a = np.random.randint(0,255,9).reshape(3,3)
print a == idct2(dct2(a))

However it turned out that after idct2(dct2(a)) the result was scaled by a constant factor compared with the original a matrix.

I would like to ask if there is a way to implement a set of 2D dct/idct such that after a idct(dct(a)) operation I can get the same output as the input.


Solution

  • You need to set scaling to ortho for both dct2 and idct2:

    def dct2 (block):
      return dct(dct(block.T, norm = 'ortho').T, norm = 'ortho')
    

    also, you cannot expect the values to be exactly the same, but almost the same within some margin of error:

    np.allclose (a, idct2(dct2(a)))