Basic Image2 question: How to display result of ops.filter().fft()

Hi again guys,

I’m trying to apply a Fourier transform to an image and visualise the result. But I’m having issues with the visualisation. So here is the code:

import net.imagej.Dataset;
import net.imagej.ImageJ;
import net.imagej.ImgPlus;
import net.imagej.ops.OpService;
import net.imglib2.IterableInterval;
import net.imglib2.converter.Converter;
import net.imglib2.converter.Converters;
import net.imglib2.type.numeric.complex.ComplexFloatType;
import net.imglib2.type.numeric.real.FloatType;
import org.scijava.ui.UIService;

/**
 * Created by rhaase on 3/24/16.
 */
public class FftExperiment {
    public static void main(final String... args) throws Exception {

        final ImageJ ij = new ImageJ();
        OpService ops = ij.op();
        UIService uis = ij.ui();

        final Dataset dataset = ij.scifio().datasetIO().open("http://imagej.nih.gov/ij/images/blobs.gif");

        ImgPlus img = dataset.getImgPlus();

        // this line works fine:
        //uis.show("img", img);

        IterableInterval<ComplexFloatType> fft = ops.filter().fft(img);
        
        // But this line doesn't work
        uis.show("fft", fft);
    }
}

The error message is then:

Exception in thread "main" java.lang.ClassCastException: net.imglib2.type.numeric.complex.ComplexFloatType cannot be cast to net.imglib2.type.numeric.RealType

Ok, I guess that’s intended, so I replace the last line of code with this:

// As the line before was not working, I try to convert the image...
IterableInterval<FloatType> iifft = Converters.convert(fft, new Converter<ComplexFloatType, FloatType>(){
      @Override
    public void convert(ComplexFloatType input, FloatType output) {
       output.set(input.getRealFloat());
  }
}, new FloatType());

uis.show("fft", iifft);

And this time, I get the message:

[WARNING] For UI 'net.imagej.legacy.ui.LegacyUI': no suitable viewer for display: null

and no window appears.

I’m getting a bit frustrated; is there no “simple” way to apply any kind of filter (or ops plugin) and just visualise the result? I mean: All the stuff I’m coding here corresponds to one single line in ImageJ1:

IJ.run(imp, "FFT", "");

Thanks in advance for your help!

Best,
Robert

Hi @haesleinhuepf

does this work??

import net.imglib2.img.display.imagej.ImageJFunctions

ImageJFunctions.show(fft)

I think uis.show(…) should eventually work as well… underneath the hood it needs to convert the complex array to a format to display (like power spectrum)… that may not be implemented yet.

See the imglib2 tutorial for example code to display views of FFTs…

imglib2 fft tutorial

A similar example implemented with ops and jython is in the Fiji script editor under. ‘Templates->Tutorials->Find Template’

1 Like

Hi @bnorthan,

these are a couple of cool hints. Thanks! So, actually,

RandomAccessibleInterval<ComplexFloatType> fft = ops.filter().fft(img);
ImageJFunctions.show(fft);

works. However, it would be cool to get the ui.show stuff running at some point… I mean, for the ease of use…

Thanks again!
Robert

What if you tried converting the result of ops.filter().fft(img) to ImgPlus<FloatType>, and then call uis.show("fft", fftImgPlus)? The class ImgPlus extends IterableInterval whereas an IterableInterval may be any kind of data, i.e. it might not be an image. I think that’s the reason it cannot be shown.

Best,
Richard

1 Like

I don’t have much time to investigate this right now, but I agree with @haesleinhuepf that it should work to call ui.show(myIterableInterval) and/or ui.show(myRandomAccessibleInterval). That command does conversions internally, and is certainly something we should make work.

1 Like

Hi, similar question when calling Ops from a script like so

# @OpService ops
# @Dataset image
# @OUTPUT Dataset outp
from net.imglib2.interpolation.randomaccess  import LanczosInterpolatorFactory
from net.imglib2.img.display.imagej import ImageJFunctions

interp = LanczosInterpolatorFactory()

outp = ops.run('image.scale', image.getImgPlus(), [2,2], interp)
ImageJFunctions.show(outp, "Hello")

First I thought that if outp was set to @OUTPUT, ImageJ would handle the display directly.

Second, I used this forum question to display the result using ImageJFunctions.show() but could I do it using ui().show() as well from a script? If so, how? I have not found an example for showing an image in a script

Yes, just add a @UIService parameter:

# @OpService ops
# @UIService ui
# @Dataset image
# @OUTPUT Dataset outp

from net.imglib2.interpolation.randomaccess  import LanczosInterpolatorFactory

interp = LanczosInterpolatorFactory()

outp = ops.run('scale', image.getImgPlus(), [2,2], interp)
ui.show("Result", outp)

Note that I replaced 'image.scale' by 'scale', running the script in an up-to-date Fiji (with Java 8), because the former didn’t find any op candidate.

1 Like

Thanks for that info!

In my case on an up to date imageJ running on Java8 both image.scale and scale seem to work.

It moved to transform.scale. You can check the net.imagej.ops.Ops class—or the Ops.list template file—for all the categorizations.