Scijava Batch Processing with Macro Language

Hi everybody and in particular @imagejan,

I’m struggling with the scijava batch processing button: it’s working really nicely with Groovy, but I cannot get the same with macro language. For instance, let’s say I want to duplicate and blur an image:

#@ImagePlus img
#@output ImagePlus outImg

run("Duplicate...", " ");
run("Gaussian Blur...", "sigma=200");
outImg = getImageID();

If I try to batch it, I just get an error directly at the selectImage(img); line.
Basically no image is open.

Does it mean that I cannot batch ImagePlus ? Should I always use Files for the macro language batch button ? It’s a bit annoying, because it means that I need to modify the macro if I want to do it in batch or with an already open image. Or maybe I’m missing something.



1 Like

Hey @NicoKiaru,

how about this macro?

run("Duplicate...", " ");
run("Gaussian Blur...", "sigma=200");

In macro, variables cannot hold images. Thus, you cannot use them with the //@ syntax. @imagejan may correct me if I’m wrong…


1 Like

Indeed the IJ1 macro language is very limited in this respect; from the documentation: variables can contain a number, a boolean [represented by 0 or 1], a string or an array.

(For those interested, the Java implementation for macro variables is in ij.macro.Variable.)

This means that any object harvested via script parameters will have to be converted to one of these values, and in many cases this ends up being a String using the object’s toString() method.

The following macro:

#@ ImagePlus imp1
#@ ImagePlus imp2

imageCalculator("Add create 32-bit", imp1, imp2);

… works for exactly that reason, because imp1 and imp2 are actually strings here.

Likely, your macro call to selectImage(img); works fine with any image already open in the (ImageJ1) GUI. I suspect the issue with the SciJava batch-processor is in fact caused by the (too) lazy synchronization between IJ2 and IJ1 data structures.

While running in batch, we use DatasetIOService and ConvertService to get our ImagePlus:

… and the title of this image is then handed over to the macro code. But the LegacyImageMap doesn’t know about the existence of this image yet. I don’t know if there’s an issue tracking this in imagej/imagej-legacy yet, would you mind opening one? I suspect that for the same reason, you cannot use File > Import > Image… run("Image... ", "...") after setBatchMode(true); in a macro.

I wouldn’t expect this to work even without any batch processing. We’d need to convert from integer back to an ImagePlus, and to my knowledge there’s no such converter currently, is there?

By the way, the recommended (and language-agnostic) syntax is “hash-at” (#@), this was agreed upon at the first dais Learnathon in Dresden 2017, after a short survey among developers and the participants of the course. The “comment-at” (// @ or # @) is supported for backwards compatibility, but is only allowed at the very beginning of the script, whereas the recommended #@ syntax can be used anywhere (e.g. after a license header or similiar).


Done here:

I believe for now I will stick to File objects if I need to do batch processing with macro language.

Thanks for the very detailed response!

1 Like

Thanks a lot @imagejan for explaining things so carefully!

Like this?

From the javadoc:

This converter exists so that ImageJ 1.x macros that assign a double ID value to an ImagePlus output will be properly converted when the actual output value is needed.

1 Like