Skip to content

New ImageJ script runner#1682

Merged
petebankhead merged 35 commits intoqupath:mainfrom
petebankhead:ij-macros
Oct 20, 2024
Merged

New ImageJ script runner#1682
petebankhead merged 35 commits intoqupath:mainfrom
petebankhead:ij-macros

Conversation

@petebankhead
Copy link
Copy Markdown
Member

@petebankhead petebankhead commented Oct 20, 2024

This replaces the ImageJ macro runner.

Both can be seen in this screenshot - the old on the left, the new on the right:

imagej-macro-runner

Improvements include:

  • Syntax highlighting
  • Autocomplete with built-in macro functions when pressing Ctrl+space
  • Better control over which objects are sent for processing
  • Better control over resolution, with 3 different methods to control the size of images sent to ImageJ (not just downsample)
  • Better control over parallelization
  • Option to select channels to send
  • Built-in examples of potentially-useful macros
  • Support for Roi groups, which map to QuPath classifications
  • Scriptability; macros can be stored in the command history and run later through Groovy scripts
  • Ability to run Groovy scripts instead of macros
    • These are different from Groovy scripts run through the script editor; they are specifically written to work on an ImagePlus obtained from ImageJ via a call to IJ.getImage()
    • New IJProcessing and IJFilters classes make it easier to process images obtained this way
  • Properties are set in the ImagePlus based on the QuPath image type so it's possible to determine a sensible value of darkBackground or lightBackground in macros or scripts
  • Better maintainability through the use of fxml and externalised strings
  • Available by the 'ImageJ' toolbar button, not only the menus

This required a lot of changes, so there is a reasonable chance things have broken elsewhere... including with the regular script editor (which needed changed to make it possible to generate a script editor control elsewhere). But I think it remains functional...

Some limitations:

  • It's not possible to control via a script which objects or Rois are sent to ImageJ with an OverlayOptions object
  • It's not currently possible to send back measurements with objects added to an overlay
  • Only 'original' channels can be sent through the user interface, not color deconvolved channels (although scripting gives more options)
  • The scripting language can't be set explicitly; for Groovy, ensure that IJ.getImage() or import [something] is included

Almost... but still not.
Only for the main QuPath window currently
Fix regression that broke storing the script in the workflow history
Also add lots of javadocs
Also externalize more strings (this time for dialogs)
These make it possible to determine whether an image has a dark or light background based on QuPath's image type.
This starts to replace RoiLabeling with a more general-purpose class that should be more intuitive.
MenuItems for copy, cut, paste etc. having accelerators caused trouble because the behaviors were already built in to TextArea, so the commands could end up being called twice.
This involves considerable changes around ScriptEditor classes, so it will take a bit of time to iron out any new troubles that have been introduced...
ScriptLanguage no longer uses a service provider, because that was making things very awkward.

It required public constructors, and calling things like GroovyLanguage.getInstance() could return null if things were done in the wrong order.

It is still possible to add jython (or other jsr223 engines) to the extensions folder, and they should become supported by the script editor.
@petebankhead petebankhead added this to the v0.6.0 milestone Oct 20, 2024
@petebankhead
Copy link
Copy Markdown
Member Author

This is the macro shown above, included as an example:

/*
 * ImageJ macro to apply an automated threshold to detect a single region.
 * You will need to return the active Roi to see the results in QuPath.
 */

// Define method (e.g. "Triangle", "Otsu"...)
method = "Otsu";

// Check if the image has a property specifying a dark background
// Override this by setting the value to true or false
if (Property.get("qupath.image.background")=="dark")
    darkBackground = true;
else
    darkBackground = false;

// Ensure 8-bit grayscale
resetMinAndMax();
run("8-bit");

// Create Roi from threshold
if (darkBackground)
    setAutoThreshold(method + " dark");
else
    setAutoThreshold(method);
run("Create Selection");

This effectively makes it possible to apply any of ImageJ's auto thresholding methods to any region of an image (or the entire image) - adapting for brightfield or fluorescence based on the image type.

The resolution and channel can be specified from within QuPath's UI when the region is being sent.

@petebankhead petebankhead merged commit dbc5cdb into qupath:main Oct 20, 2024
@petebankhead petebankhead deleted the ij-macros branch October 20, 2024 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant