Usage of ImageStack.create with jarray

Hi all,

within a python script in Fiji I try to

print 'List CH Stacks :', len(imglist_t_c)

        for i in range(len(imglist_t_c)):
            print str(i) + ' : ', type(imglist_t_c[i])

        # in case of more than one channel use an jarray
        if numch > 1:

            # create an array
            imgarray_c = jarray.array(imglist_t_c, ImagePlus)
            # create an ImageStack from the array
            print 'Type imgarray_c : ', type(imgarray_c)

            for i in range(numch):
                print type(imgarray_c[i])

            imgstack_c = ImageStack.create(imgarray_c)

Output is what I would expect:

List CH Stacks : 2
0 :  <type 'ij.ImagePlus'>
1 :  <type 'ij.ImagePlus'>
Type imgarray_c :  <type 'array.array'>
<type 'ij.ImagePlus'>
<type 'ij.ImagePlus'>

But the script fails inside the last line from above, which I do not understand so far because from the ImageStack I see:

And this is what I actually “think” I am doing.

  • create a list with ImagePlus inside
  • create a jarray using the list
  • create a stack using the jarray

Where is my mistake here? I think the problem has to do with this usage, where 4 arguments would be expected.

Error Message:

Traceback (most recent call last):
  File "C:\Users\m1srh\Documents\Fiji\scripts\calc_focusplane2.py", line 243, in <module>
    sharpest_image = run(IMAGEPATH, verbose=False)
  File "C:\Users\m1srh\Documents\Fiji\scripts\calc_focusplane2.py", line 175, in run
    imgstack_c = ImageStack.create(imgarray_c)
TypeError: create(): expected 4 args; got 1

	at org.python.core.Py.TypeError(Py.java:236)
	at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:213)
	at org.python.core.PyReflectedFunction.throwArgCountError(PyReflectedFunction.java:266)
	at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java:323)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:171)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:208)
	at org.python.core.PyObject.__call__(PyObject.java:461)
	at org.python.core.PyObject.__call__(PyObject.java:465)
	at org.python.pycode._pyx21.run$4(C:/Users/m1srh/Documents/Fiji/scripts/calc_focusplane2.py:211)
	at org.python.pycode._pyx21.call_function(C:/Users/m1srh/Documents/Fiji/scripts/calc_focusplane2.py)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
	at org.python.core.PyFunction.function___call__(PyFunction.java:474)
	at org.python.core.PyFunction.__call__(PyFunction.java:469)
	at org.python.pycode._pyx21.f$0(C:/Users/m1srh/Documents/Fiji/scripts/calc_focusplane2.py:273)
	at org.python.pycode._pyx21.call_function(C:/Users/m1srh/Documents/Fiji/scripts/calc_focusplane2.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)

That’s strange indeed, I’m not sure but I think the method create(ImagePlus[]) might have come in the latest ImageJ versions. Did you try updating the ImageJ1 core?

I think the conversion of the list to a jarray is not actually necessary. The jython engine takes care of it automatically.
As an alternative you can use the method run(ImagePlus[]) from the ImagesToStack class.

Hello Sebi -

As Laurent notes, this appears to be a version issue.

With a newly-updated Help > Update ImageJ... (1.53f), I
can run ImageStack.create (ImagePlus[]) successfully.

Output from a test script:

1.53f99
ist1 = stack[256x256x2]
create array(java.lang.Class, [<type '[Lij.ImagePlus;'>])
create array(java.lang.Class, [<type 'int'>, <type 'int'>, <type 'int'>, <type 'int'>])
ist2 = stack[256x256x2]

With an older version (1.53c), it fails:

1.53c99
ist1 = stack[256x256x2]
create array(java.lang.Class, [<type 'int'>, <type 'int'>, <type 'int'>, <type 'int'>])
exception caught: create(): expected 4 args; got 1

The current documentation for ImageStack does indeed show a
.create (ImagePlus[]) method. However, the older version
doesn’t have this specific method, while the newer version does.
(See reflection in the test script or just look in the ij-xxxx.jar file.)

Here is the test script (jython):

from ij import IJ
from ij import ImageStack

# check the ImageJ version
print  IJ.getFullVersion()

imp1 = IJ.createImage ('imp1', '8-bit ramp', 256, 256, 1)
imp2 = IJ.createImage ('imp2', '8-bit ramp', 256, 256, 1)

# ImageStack.addSlice() approach works
ist1 = ImageStack()
ist1.addSlice (imp1.getProcessor())
ist1.addSlice (imp2.getProcessor())
print  'ist1 =', ist1

# look for ImageStack.create (ImagePlus[]) function signature
for  m in ImageStack.getDeclaredMethods():
    if  m.getName() == 'create':
        print  m.getName(), m.getParameterTypes()

# try ImageStack.create() approach
try:    
    ist2 = ImageStack.create ([imp1, imp2])
    print  'ist2 =', ist2
except Exception as e:
    print  'exception caught:', e

(I couldn’t figure out when the method in question was added or
how to find documentation consistent with the old version.)

Thanks, mm

1 Like

It came since version 1.53d, see release notes.


Apparently Wayne implemented it when I suggested the Roi multi-crop function, I had forgotten ! :rofl:

Thanks to Laurent Thomas, added the ImagePlus.crop(Roi[]), Overlay.createStackOverlay(Roi[]) and ImageStack.create(ImagePlus[]) methods. For an example, run Help>Examples>JavaScript>Crop Multiple Rois .