I want to apply a Discrete Cosine Transform (as well as the inverse) to an image in Python and I'm wondering what is the best way to do it and how. I've looked at PIL and OpenCV but I still don't understand how to use it.
Asked
Active
Viewed 4.0k times
21
-
Not exactly sure about PIL and OpenCV, but applying both DCT and inverse DCT is basically multiplying source block by the related transformation matrices. – Andrey Agibalov Aug 18 '11 at 16:36
2 Answers
14
Example with scipy.fftpack
:
from scipy.fftpack import dct, idct
# implement 2D DCT
def dct2(a):
return dct(dct(a.T, norm='ortho').T, norm='ortho')
# implement 2D IDCT
def idct2(a):
return idct(idct(a.T, norm='ortho').T, norm='ortho')
from skimage.io import imread
from skimage.color import rgb2gray
import numpy as np
import matplotlib.pylab as plt
# read lena RGB image and convert to grayscale
im = rgb2gray(imread('images/lena.jpg'))
imF = dct2(im)
im1 = idct2(imF)
# check if the reconstructed image is nearly equal to the original image
np.allclose(im, im1)
# True
# plot original and reconstructed images with matplotlib.pylab
plt.gray()
plt.subplot(121), plt.imshow(im), plt.axis('off'), plt.title('original image', size=20)
plt.subplot(122), plt.imshow(im1), plt.axis('off'), plt.title('reconstructed image (DCT+IDCT)', size=20)
plt.show()
Also, if you plot a small slice of the 2D DCT
coefficients array imF (in log
domain), you will get a figure like the following (with a checkerboard pattern):

Sandipan Dey
- 21,482
- 2
- 51
- 63
-
1Can you share the code to display the DCT coefficients? I don't get it quite right, maybe it's the matplotlib scale? – Matthieu Aug 24 '22 at 12:24
12
From OpenCV:
DCT(src, dst, flags) → None Performs a forward or inverse Discrete Cosine transform of a 1D or 2D floating-point array. Parameters: src (CvArr) – Source array, real 1D or 2D array dst (CvArr) – Destination array of the same size and same type as the source flags (int) – Transformation flags, a combination of the following values CV_DXT_FORWARD do a forward 1D or 2D transform. CV_DXT_INVERSE do an inverse 1D or 2D transform. CV_DXT_ROWS do a forward or inverse transform of every individual row of the input matrix. This flag allows user to transform multiple vectors simultaneously and can be used to decrease the overhead (which is sometimes several times larger than the processing itself), to do 3D and higher-dimensional transforms and so forth.
Here is an example of it being used.
The DCT is also available in scipy.fftpack.

Ander Biguri
- 35,140
- 11
- 74
- 120

agf
- 171,228
- 44
- 289
- 238
-
Could you provide a basic program to display its usage? Python seems to complain that my destination array is empty. – jmnwong Aug 19 '11 at 01:20
-
Essentially what I've done is use PIL to resize an input image and then used cv.CreateImageHeader to create the source as well as an empty destination array. Not sure if this is correct. – jmnwong Aug 19 '11 at 01:27
-
[Here is an example of it being used](http://blog.weisu.org/2007/11/opencv-dct-and-idct.html) – agf Aug 19 '11 at 01:30
-
I don't actually use OpenCV, so this is all of the information I have. You could try asking on their mailing list; [this cookbook page](http://opencv.willowgarage.com/documentation/python/cookbook.html) has some good examples of general usage. – agf Aug 19 '11 at 02:15