Python How Can I Perform a 3D Fourier Transform on 2D Images Over Time in Python?

Click For Summary
The discussion focuses on performing a 3D Fourier Transform on a series of 2D images over time using Python. The user initially demonstrates their ability to execute a 1D FFT but struggles to extend this to a 2D array and subsequently to a 3D transformation. Suggestions include using NumPy arrays instead of Python lists for better performance and employing functions like rfft2 or rfftn for real-valued inputs. The user encounters an error when attempting to visualize the magnitude spectrum of the Fourier Transform, which is attributed to incorrect dimensions in the image data. Overall, the conversation emphasizes the importance of proper array handling and the appropriate use of FFT functions in Python.
EnSlavingBlair
Messages
34
Reaction score
6
Hi,

My aim is to get a series of images in 2D space that run over different timestamps and put them through a 3D Fourier Transform. So my 3D FT has 2 spatial axes and one temporal axis. However I have never done anything like this before, and I have a very basic knowledge of Python.

So far, I can do the FFT for a list (or 1D array) of point sources as follows:

##
# Import libs
import matplotlib.pyplot as plt
import numpy as np

# create point sources
tmp = range(100)
source = [0 for x in tmp]
source.insert(50,1)
source.insert(5,1)
source.insert(60,0.5)

# make t useable later
t = np.array(source)

# equations for later
f = np.fft.fft(t)
g = np.sqrt(np.abs(f)**2)

# set up plot
fig = plt.figure()

# add sources to plot
ax1 = fig.add_subplot(211)
plt.plot(source)
ax1.set_title('Source')
ax1.xaxis.set_visible(False)

# add FT of sources to plot
ax2 = fig.add_subplot(212)
plt.plot(f)
ax2.set_title('Fourier Transform')
ax2.xaxis.set_visible(False)

# show plot
plt.show()
##

Now I would like to turn my 1D image into a 2D image, and I just can't work out how to do this. I've tried by doing something like this for my point sources:

##
# Array of 3 source lists
# Create list of lists - seems dodgy
tmp_array = range(3)
array_list = []

# create source lists to go in array
tmp = range(10)
source1 = [0 for x in tmp]
source1.insert(5,1)
source2 = [0 for x in tmp]
source2.insert(4,1)
source3 = [0 for x in tmp]
source3.insert(2,1)

# put lists in array
array_list.insert(1,source1)
array_list.insert(2,source2)
array_list.insert(3,source3)
##

Though calling it "source" instead of "array_list" would fit better with previous code.
However it is not working and I cannot figure out why.

I was also wandering if I need to bother with getting the 2D FT working before trying the 3D, or if I can just jump forward? Not that I have any idea how to do that yet.

Thank you for your help
 
Technology news on Phys.org
I would suggest creating arrays as numpy arrays first, not as Python lists:

For the 1d array:

t = np.zeros(103)
t[5] = 1
t[51] = 1
t[60] = 0.5

(if that was your intention)

For the 2d array:

array_list = np.zeros((3, 11))
array_list[0,5] = 1
# etc...

For a 2d fft of with real-valued input, use rfft2 or rfftn.

Note that for large FFT sizes, try to avoid a size with large prime factors, or pad out to the next largest power of 2 if that is unavoidable (using the optional size parameter). Fftpack seems to handle small prime factors like 3 or 5 OK, though.
 
One more comment:

f = np.fft.fft(t)
g = np.sqrt(np.abs(f)**2)
The sqrt and square here are unnecessary: np.abs(f) is already sqrt(f.real**2 + f.imag**2).
 
Thank you :)

I've gone for a slightly different approach now than above, and hitting different problems.

# A lot of this is taken from http://matplotlib.org/users/image_tutorial.html
# as well as http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_transforms/py_fourier_transform/py_fourier_transform.html

##
img=mpimg.imread('stinkbug.png')
img_red = img[:,:,0]
img_green = img[:,:,1]
img_blue = img[:,:,2]
# I assume this is taking the data in each of the red, green and blue columns?

array_list = []
array_list.append(img_red)
array_list.append(img_green)
array_list.append(img_blue)

t = np.array(array_list)
f = np.fft.fftn(t)
fshift = np.fft.fftshift(f)
magnitude_spectrum = np.log(np.abs(fshift))

fig = plt.figure()

ax1 = fig.add_subplot(211)
imgplot=plt.imshow(img)
ax1.set_title('FT this Bug')
imgplot.set_cmap('gray')
plt.colorbar()

ax2 = fig.add_subplot(212)
plt.imshow(magnitude_spectrum)
plt.colorbar()

plt.show()
##

I get the following error

###
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "image_test2", line 51, in <module>
plt.imshow(magnitude_spectrum)
File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 2892, in imshow
imlim=imlim, resample=resample, url=url, **kwargs)
File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 7300, in imshow
im.set_data(X)
File "/usr/lib/pymodules/python2.7/matplotlib/image.py", line 429, in set_data
raise TypeError("Invalid dimensions for image data")
TypeError: Invalid dimensions for image data
##

Which I believe is because I'm trying to plot 3 images in 1 2D image, where I should be making a very thin rectangular cube. Because the images are basically the same, I expect that all the information will be in the first part and only left-over stuff in the others as I am sampling a limited sized image. I just don't know how to do that!
 
Try plotting the red, green, and blue sections separately.

A few other comments on the code

nSlavingBlair said:
Thank you :)
img=mpimg.imread('stinkbug.png')
img_red = img[:,:,0]
img_green = img[:,:,1]
img_blue = img[:,:,2]
# I assume this is taking the data in each of the red, green and blue columns?

array_list = []
array_list.append(img_red)
array_list.append(img_green)
array_list.append(img_blue)

t = np.array(array_list)

This could more easily be achieved using rollaxis(img, 2, 0):

img_rgba = img.rollaxis(img, 2, 0)
img_rgb = img_rgba[:3]

f = np.fft.fftn(t)
fshift = np.fft.fftshift(f)
magnitude_spectrum = np.log(np.abs(fshift))

Again, for real-valued input, the fft will have a second set of redundant conjugate negative-frequency values (the shift just moves them to to the beginning of the array, IIRC). I suggest using rfftn.
 
I tried a web search "the loss of programming ", and found an article saying that all aspects of writing, developing, and testing software programs will one day all be handled through artificial intelligence. One must wonder then, who is responsible. WHO is responsible for any problems, bugs, deficiencies, or whatever malfunctions which the programs make their users endure? Things may work wrong however the "wrong" happens. AI needs to fix the problems for the users. Any way to...

Similar threads

  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
Replies
13
Views
2K
  • · Replies 4 ·
Replies
4
Views
2K
Replies
5
Views
8K