Fourier transform

Hi
Is there any command in ImageJ to calculate the Fourier transform of images with a size that is non-power of two?

Best regards,
Sara

I think this plugin might help:

1 Like

Hi @sara_sh,

you posted the same question on the mailing list, where Herbie and @ctrueden replied with some useful answers. In the future, please always disclose when cross-posting like that, so others can also follow the discussion.

For the record, here’s the Groovy script that @ctrueden was suggesting (run it from the script editor after selecting Language > Groovy):

#@ OpService ops
#@input Img image
#@input Double (value=10) radius
#@output Img result

import net.imglib2.type.numeric.real.FloatType
import net.imglib2.util.Util

lowpass = { fft, radius ->
  pos = new long[fft.numDimensions()]
  long[] origin = [0, 0]
  long[] origin2 = [0, fft.dimension(1)]
  cursor = fft.localizingCursor()
  while (cursor.hasNext()) {
    cursor.fwd()
    cursor.localize(pos)
    dist = Util.distance(origin, pos)
    dist2 = Util.distance(origin2, pos)
    if (dist > radius && dist2 > radius)
      cursor.get().setZero()
  }
}

// Perform fft of the input.
fft = ops.filter().fft(image)

// Filter it.
lowpass(fft, radius)

// Reverse the FFT.
result = ops.run("create.img", image, new FloatType())
ops.filter().ifft(result, fft)
2 Likes

For anyone using ops FFT note there are additional considerations if one wants to see a full sized centered FFT like the one that is displayed by ImageJ.

Below is a Jython script that takes the FFT of a 2D image then reflects and centers it. An FFT of a real signal has Hermitian symmetry. In Ops (which is build on FFTMethods) only the non-redundant part of the FFT is returned. As well Ops does not support every input size (because the library ops and imglib are built on, jdk mines, does not support every size. Also ops returns an FFT with 0,0 at the origin, while imagej returns an FFT with 0,0 centered. So there is a bit of wrangling that has to be done to get the full sized, centered FFT. See the below script.

@haesleinhuepf, if you do end up using clFFT note that all the above complications, also apply to clFFT. See clFFT docs, especially the section ‘FFT of real data’.

#@ OpService ops
#@ UIService ui
#@ ImgPlus image

from net.imglib2.outofbounds import OutOfBoundsMirrorFactory;
from net.imglib2.outofbounds.OutOfBoundsMirrorFactory import Boundary;

from net.imglib2.img.display.imagej import ImageJFunctions
from net.imglib2.view import Views;
from net.imglib2.util import Intervals;

#fft=ops.filter().fft(image)

fft=ops.filter().fft(image, [10, 10], True, OutOfBoundsMirrorFactory(Boundary.SINGLE))

# display fft (by default in generalized log power spectrum)
ImageJFunctions.show(fft).setTitle("fft power spectrum")

# get FFT size (this is a long[][] that contained the real and complex size
fftSize=ops.filter().fftSize(image, True, True);

# use the extended real size to create a centered interval that contains the redundant part of the FFT
interval = Intervals.createMinMax(-fftSize[0][0] / 2, -fftSize[0][1] / 2, fftSize[0][0] / 2, fftSize[0][1] / 2);

# mirror the FFT and get the above interval
reflectedCenteredFFT=Views.interval(Views.extend(fft, OutOfBoundsMirrorFactory(Boundary.SINGLE)), interval);

#display the interval
ImageJFunctions.show(reflectedCenteredFFT).setTitle("reflected centered fft power spectrum")
3 Likes