imagej / imagej-legacy

ImageJ+ImageJ2 compatibility layer
https://imagej.net/libs/imagej-legacy
BSD 2-Clause "Simplified" License
16 stars 25 forks source link

Outputs not available when calling ImageJ2 plugin from ImageJ macro in batch mode #277

Open mdoube opened 2 years ago

mdoube commented 2 years ago

If an ImageJ2 plugin that uses @Parameter notation to specify inputs and outputs is called from an ImageJ1 macro with setBatchMode(true), no image results are produced. They are not just hidden, they are simply not available to the macro API, and do not appear in open image lists. I suspect this is a failure of the plugin to have its output @Parameters processed in a way that makes image data available to ImageJ(1) and macros.

Test image: shrew.zip

Example macro: (requires BoneJ to be installed)

 //set to false to show images. True will fail.
setBatchMode(true);
//expects a binary image stack like shrew.tif
open();
imageTitle = getTitle();
strippedImageTitle = replace(imageTitle, ".tif", "");
print(strippedImageTitle);
print(imageTitle);
outputDir = getDir("Output directory");

//a quick run with results that are not really useful except for testing this macro
run("Ellipsoid Factor", "nvectors=100 vectorincrement=0.435 skipratio=30 contactsensitivity=1 maxiterations=50 maxdrift=1.73 runs=1 weightedaveragen=1 seedondistanceridge=false distancethreshold=0.6 seedontopologypreserving=true showflinnplots=true showconvergence=true showsecondaryimages=false");

//this section of selecting and saving images will break in batch mode but run OK in regular/interactive mode
//the error is usually something like "no image with this title is open"
selectImage(strippedImageTitle+"_EF");
run("Histogram", "bins=256 x_min=-1 x_max=1 y_max=Auto stack");
saveAs("Tiff", outputDir+"Histogram of "+strippedImageTitle+"_EF.tif");
close();

selectImage(strippedImageTitle+"_EF");
saveAs("Tiff", outputDir+strippedImageTitle+"_EF.tif");
close();

selectImage(strippedImageTitle+"_unweighted_Flinn_plot");
saveAs("Tiff", outputDir+strippedImageTitle+"_unweighted_Flinn_plot.tif");
close();

selectImage(strippedImageTitle+"_Flinn_peak_plot");
saveAs("Tiff", outputDir+strippedImageTitle+"_Flinn_peak_plot.tif");
close();

selectImage(imageTitle);
close();

run("Clear BoneJ results");

This similar Jython script works OK in headless mode:

#@ CommandService cs
#@ TableIOService tios

from ij import IJ
from ij import ImagePlus
from org.scijava.table.io import TableIOOptions
from org.bonej.utilities import SharedTable as table

#Set data input-output paths 
input_dir = "/mnt/md0/images/testImages/"
input_image_path = input_dir+"shrew.tif"
outputdir = "/home/mdoube/Desktop/"

#clear old results from the table
IJ.run("Clear BoneJ results");

#open input image as IJ1-style ImagePlus to be compatabile with wrapper  
inputImagePlus = IJ.openImage(input_image_path)

#Run Intertrabecular Angles Plugin specifying parameters 
wrapper = cs.run("org.bonej.wrapperPlugins.IntertrabecularAngleWrapper", True, ["inputImage",inputImagePlus, "minimumValence", 3, "maximumValence", 50, "minimumTrabecularLength", 0, "marginCutOff", 10, "iteratePruning", True, "useClusters", True, "printCentroids", True,"printCulledEdgePercentages", False, "showSkeleton", True])

#must call wrapper.get() to populate the result table with data and to create output images
wrapperInstance = wrapper.get()

#Get and save the skeleton image. Here, you don't have to specify the name of the output.
skeleton= wrapperInstance.getOutput("")
IJ.save(skeleton, outputdir+"skeleton.tif")

#save the result table
tios.save(table.getTable(), outputdir+"ITA.csv", TableIOOptions())