Using IJ1 BandPass FFT Filter in a script

Consider the following script :

# @ImageJ ij
# @StatusService status

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

from ij.plugin.filter import FFTFilter

data = ij.dataset().open("8bit-signed&pixelType=int8&axes=X,Y,Time&lengths=800,800,10.fake")

imp = ImageJFunctions.wrap(data, "Image")

args = "filterLargeDia=40 filterSmallDia=10 processStack"

fft_filter = FFTFilter()
fft_filter.setup(args, imp)


The script shows the parameter dialog. How can I not display it ? Also, is the way I pass the parameters args are correct ?

I guess @Wayne, you’re the best person to answer that.

Thank you

I have also tried to use IJ2/Ops but the output is not what excepted :

# @Dataset data
# @ImageJ ij

from net.imglib2.img.display.imagej import ImageJFunctions; 
from net.imglib2.algorithm.fft import Bandpass

fft = ij.op().run("filter.fft", data.getImgPlus()) 

bp = Bandpass(fft, 10, 40,  fft.factory())

if not bp.checkInput():
	print(bp.getClass().getSimpleName() + " failed: " + bp.getErrorMessage())

if not bp.process():
	print(bp.getClass().getSimpleName() + " failed: " + bp.getErrorMessage())

inverted = ij.op().create().img(data)
ij.op().run("filter.ifft", inverted, fft) 

This is the code generated when I use the Process>FFT>Bandpass Filter command with the recorder running:, "Bandpass Filter...", "filter_large=40 filter_small=3 suppress=None tolerance=5 autoscale saturate");

I should have specified that I have already tried that :

# @ImageJ ij
# @StatusService status

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

from ij import IJ
from ij.plugin.filter import FFTFilter

data = ij.dataset().open("8bit-signed&pixelType=int8&axes=X,Y,Time&lengths=800,800,10.fake")

imp = ImageJFunctions.wrap(data, "Image"), "Bandpass Filter...", "filter_large=40 filter_small=10 suppress=None tolerance=5 autoscale saturate")


The output image shows the correct filtered image but as soon as I click on it, the whole stack becomes black.

It’s actually not black if you run auto contrast, but the image does not seems to be the filtered one.

This complete 10 slice stack JavaScript example works as expected:

imp = IJ.createImage("Untitled", "8-bit ramp", 800, 800, 10);, "Bandpass Filter...", "filter_large=40 filter_small=10 suppress=None tolerance=5 autoscale saturate process");;

@hadim we should be able to replicate the bandpass filter in ops. I am happy to debug this, but I am wondering where the best place to put it would be??

I think this would best be implemented in java (not a jython script), perhaps as a command.

I think there is a need for a ‘BAR’ like project for IJ2, ie re-usable components that are meant to be part of scripts.

Do you think we should start a java project in imagej-scripting, to develop re-usable components?? Or do you think it should a separate repository?? Maybe a “BAR2” or something? @tferr?

1 Like

Hum ideally I would like to see a bandpass filter in ops. That is the most convenient option in my opinion.

I have already created a small Python lib (very specific to my needs) here :

On the long term I would like to have all the functions of this libs in ops too. In the meantime a Python lib imagej-scripting would make a lot of sense (and would be automatically available to users since imagej-scripting is installed in Fiji.

For the bandpass filter, if you could tweak my script to make it work as the IJ1 FFTFilter plugin, that would be great. Then I could maybe try to translate this to an ops.

What do you think ?

1 Like

Long term it would be great to have the band pass filter in ops.

Medium term it would be nice to have a place to implement small snippets in java. I prefer java to jython, because I can use eclipse and have autocomplete, shortcuts, documentation, debugging.

Do you think some java commands would fit in the scripting project??

Sure go ahead. Small Java commands totally fit in the scripting project I think.

This is exactly what the ImageJ-Ops is aiming at, no?

Agreed, we can include some Command examples in the scripting repo, but anything that’s more generally useful should go to Ops, IMHO.

To do it properly, an ops feature addition and pull request can take weeks to months to complete, There are a lot of things to consider. One has to know a bit about templates, and something about the ops computational model (computers, functions, hybrids, etc.). One also has to maintain a namespace to go with a new op. It’s not trivial. And the core IJ2, KNIME guys like @ctrueden and @dietzc need to review.

I think it would be useful to have an “intermediate” level java project where community members can make contributions, relatively quickly, so I am all for including java Command examples in the scripting repo.

There can be Commands and Ops for the same algorithm. The first attempt at an algorithm is often implemented as a Command. or script, using a combination of Ops and ```imglib2````. As seen in recent gitter conversations, someone will say “yikes that’s way to complicated”, and in turn ops will be improved/expanded so that Commands and/or scripts can be implemented more concisely and cleanly.


It’s exactly what I had in mind. Ops are the long term goal for those intermediate Python/Java scripts/commands.

1 Like

@hadim I think the problem you had when using “bandpass” is that it expected frequency 0,0 to be in the center of the image, however the newer imglib2 FFT (which ops is based on) puts frequency 0,0 at the origin.

Also the redundant information of the real to complex transform is not kept, which means there are only half as many complex pixels in the x direction

So given that, I think this script implements bandpass… let me know if I have it right. I still need to improve the documentation.