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\", line 243, in <module>
    sharpest_image = run(IMAGEPATH, verbose=False)
  File "C:\Users\m1srh\Documents\Fiji\scripts\", line 175, in run
    imgstack_c = ImageStack.create(imgarray_c)
TypeError: create(): expected 4 args; got 1

	at org.python.core.Py.TypeError(
	at org.python.core.PyReflectedFunction.throwError(
	at org.python.core.PyReflectedFunction.throwArgCountError(
	at org.python.core.PyReflectedFunction.throwError(
	at org.python.core.PyReflectedFunction.__call__(
	at org.python.core.PyReflectedFunction.__call__(
	at org.python.core.PyObject.__call__(
	at org.python.core.PyObject.__call__(
	at org.python.pycode._pyx21.call_function(C:/Users/m1srh/Documents/Fiji/scripts/
	at org.python.core.PyFunction.function___call__(
	at org.python.core.PyFunction.__call__(
	at org.python.pycode._pyx21.f$0(C:/Users/m1srh/Documents/Fiji/scripts/
	at org.python.pycode._pyx21.call_function(C:/Users/m1srh/Documents/Fiji/scripts/
	at org.python.core.Py.runCode(
	at org.python.core.__builtin__.eval(
	at org.python.core.__builtin__.eval(
	at org.python.util.PythonInterpreter.eval(
	at org.python.jsr223.PyScriptEngine.eval(
	at org.python.jsr223.PyScriptEngine.eval(
	at javax.script.AbstractScriptEngine.eval(
	at org.scijava.thread.DefaultThreadService.lambda$wrap$2(
	at java.util.concurrent.ThreadPoolExecutor.runWorker(
	at java.util.concurrent.ThreadPoolExecutor$

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:

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:

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
    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 .