Processing filter headless in jython

Hello,

That is probably a trivial question but I am having issues to run filters on images in headless mode. When I am running the following with:
ImageJ-linux64 --ij2 --headless --console --run test_headless.py

from ij import IJ
from loci.plugins.in import ImagePlusReader,ImporterOptions,ImportProcess

# import image
opts = ImporterOptions()
opts.setId("test.lsm")
process = ImportProcess(opts)
process.execute()
impReader = ImagePlusReader(process)
imps = impReader.openImagePlus()

curImp = imps[0]

IJ.run(curImp, "Gaussian Blur...", "sigma=1 stack")

I get

Reading LSM metadata for series #0
[WARN] Unknown Immersion value 'DIC' will be stored as "Other"
[WARN] Unknown LaserMedium value '' will be stored as "Other"
[WARN] Unknown LaserType value 'Chameleon' will be stored as "Other"
java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    ij/gui/NonBlockingGenericDialog.dispose()V @5: invokestatic
  Reason:
    Type 'ij/gui/NonBlockingGenericDialog' (current frame, stack[0]) is not assignable to 'java/awt/Window'
  Current Frame:
    bci: @5
    flags: { }
    locals: { 'ij/gui/NonBlockingGenericDialog' }
    stack: { 'ij/gui/NonBlockingGenericDialog' }
  Bytecode:
    0x0000000: 2ab7 001a 2ab8 001b 2ab4 000b c600 1e2a
    0x0000010: b400 0bb6 000c 4c2b c600 122a b400 0fc6
    0x0000020: 000b 2b2a b400 0fb6 001c b1            
  Stackmap Table:
    same_frame(@42)

	at ij.plugin.filter.GaussianBlur.showDialog(GaussianBlur.java:86)
	at ij.plugin.filter.PlugInFilterRunner.<init>(PlugInFilterRunner.java:63)
	at ij.IJ.runPlugIn(IJ.java:206)
	at ij.Executer.runCommand(Executer.java:150)
	at ij.Executer.run(Executer.java:68)
	at ij.IJ.run(IJ.java:317)
	at ij.IJ.run(IJ.java:407)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:208)
	at org.python.core.PyObject.__call__(PyObject.java:494)
	at org.python.core.PyObject.__call__(PyObject.java:498)
	at org.python.pycode._pyx0.f$0(test_headless.py:41)
	at org.python.pycode._pyx0.call_function(test_headless.py)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1687)
	at org.python.core.__builtin__.eval(__builtin__.java:497)
	at org.python.core.__builtin__.eval(__builtin__.java:501)
	at org.python.util.PythonInterpreter.eval(PythonInterpreter.java:255)
	at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:57)
	at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:31)
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
	at org.scijava.script.ScriptModule.run(ScriptModule.java:157)
	at org.scijava.module.ModuleRunner.run(ModuleRunner.java:165)
	at org.scijava.module.ModuleRunner.call(ModuleRunner.java:124)
	at org.scijava.module.ModuleRunner.call(ModuleRunner.java:63)
	at org.scijava.thread.DefaultThreadService.lambda$wrap$2(DefaultThreadService.java:225)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

What am I doing wrong?

EDIT:
I could get it to run with:
xvfb-run ImageJ-linux64 --ij2 --console --run test_headless.py

as suggested here:

Not sure if that is the solution?

Hi, it seems that some of the filters in ImageJ have been updated with option to work with NonBlockingGenericDialog (ImageJ 1.52q). It allows some interaction while using a filter (so user in GUI env. can zoom to some part of image while using a filter etc.)

There is an option in Edit->Option->Misc... (or from code Prefs.nonBlockingFilterDialogs) to choose between GenericDialog of NonBlockingGenericDialog. It works fine in GUI but in headless mode even if GenericDialog is default it gives me same error as you got.

Usually on cluster I’m run stuff with xvfb-run so that kind of problems are not visible to me but maybe someone knows solution without xvfb-run that actually works?

Actually method newDialog after mentioned update has a description:

/** Returns a new NonBlockingGenericDialog with given title, unless
	 *  java is running in headless mode; then a GenericDialog will be
	 *  returned (headless mode does not support the NonBlockingGenericDialog).
	 *  @param title Dialog title
	 *  @param imp   The image associated with this dialog
	*/
public static GenericDialog newDialog(String title, ImagePlus imp) {

so I it should run smoothly in headless mode but… does not.

This ImageJ 1.52q regression if fixed in the latest daily build (1.53h55).

This minimal script reproduces the problem:

  imp = IJ.openImage("https://imagej.net/images/blobs.gif");
  IJ.log("blur1: "+imp.getStatistics().stdDev);
  IJ.run(imp, "Gaussian Blur...", "sigma=10");
  IJ.log("blur2: "+imp.getStatistics().stdDev);

The commit is at

2 Likes