iacosdemo -- Illustrate discrete cosine wave and its DFT showing its periodic nature

This demonstration illustrates the computation of the DFT - Discrete Fourier Transform of a particular discrete cosine wave. We realized that depending on the wave length and angle chosen, its DFT is not a pair of complex conjugate points. The demonstration shows the reason of this by calling the periodic nature of the DFT and when four discrete cosine waves are tiled together, it becomes evident that the wave is not an ideal discrete cosine wave. The demonstration goes on by computing the nearest normalized frequencies and and computes a new discrete cosine wave from the inverse DFT of a single pair of complex conjugate placed at the nearest normalized frequencies. In this case, when four images area tiled together, we see there are no abrupt changes in the boundaries of the images just tiled.

A discrete cosine wave of an image with size 256 columns and 128 rows, with wave length of 100 pixels at 45 degrees is computed and shown below.

1 from ia636 import *
3 s = (128,256)
4 t = 100
5 theta = 45 * pi/180
6 f = iacos(s, t, theta, 0)
7 adshow(ianormalize(f), title='f - cosine wave')

f - cosine wave

The computation of its DFT - Discrete Fourier Transform reveals that the result is not a single pair of complex conjugate points, but also a number of points in the vertical and horizontal directions. This behavior has to do with abrupt changes in the image. As both the DFT and the image are periodic, we place four images as tiles. We can see that when these images are tiled together, there are many abrupt changes in the images as they do not fit together as a single cosine wave.

1 F = iadft(f)
2 adshow(iadftview(F), title='F - DFT of f')
3 adshow(iatile(ianormalize(f),2 * array(shape(f))),title='f tiled 4 times')

F - DFT of f

f tiled 4 times

From the wave length 100 and angle 45 degrees, we compute the value of the normalized horizontal and vertical frequencies and and noticed that they are not integers and so there is no correspondence to an ideal cosine wave in the discrete Fourier domain:

1 u = s[1] * cos(theta) / t
2 v = s[0] * sin(theta) / t
3 print 'u,v = ', u,v
u,v =  1.81019335984 0.905096679919

The nearest integer u and v are 2 and 1, respectively. We create an synthetic Discrete Fourier image with a single pair of complex conjugate points at this nearest integer u and v.

1 ui, vi = round(u), round(v)
2 print 'ui,vi = ', ui, vi
3 FS = zeros(s)
4 FS[vi,ui] = 1
5 FS[s[0]-vi, s[1]-ui] = 1
6 print 'FS is complex conjugate? ', iaisdftsym(FS)
7 adshow(iadftview(FS),title='DFT of a single pair of complex conjugate points')
ui,vi =  2.0 1.0
FS is complex conjugate?  True

DFT of a single pair of complex conjugate points

Computing the inverse DFT we can find the correspondent cosine wave. We observe now that tiling 4 images together, there are no abrupt changes in the boundaries. We compute the equivalent wave length and angle, and we notice that the nearest ideal cosine wave has now a wavelength of 90.5 pixels instead of 100, in the same direction (45 degrees).

1 fs = real(iaidft(FS))
2 adshow(ianormalize(fs), title='fs - ideal cosine wave')
3 adshow(iatile(ianormalize(fs), 2 * array(shape(fs))), title='fs tiled 4 times')
4 txi,tyi = s[1]/ui, s[0]/vi
5 thetai = arctan(tyi/txi)
6 ti = txi * cos(thetai)
7 print 'new period and angle = ', ti, thetai * 180/pi
new period and angle =  90.5096679919 45.0

fs - ideal cosine wave

fs tiled 4 times

We place both the original cosine wave and the ideal cosine wave together for comparison.

1 adshow(ianormalize(f), title='f - cosine wave with period 100 pixels')
2 adshow(ianormalize(fs), title='fs - ideal cosine wave with period 90.5 pixels')

f - cosine wave with period 100 pixels

fs - ideal cosine wave with period 90.5 pixels