\(•ᴗ•)/ QuPath scripting (#5): Export image and Rois to ImageJ

I am still working to complete my 10 series :slight_smile:

This time inspired from the discussion in

I have created a script to export the image of a selected annotation to ImageJ together with the Rois of the detections (detections have to be inside the annotation hierarchy).

Here is the script

// Export_to_IJ.groovy

import ij.ImageJ
import qupath.lib.scripting.QP
import qupath.lib.gui.scripting.QPEx
import qupath.imagej.tools.IJTools
import ij.plugin.frame.RoiManager
import ij.gui.Roi
import qupath.imagej.gui.IJExtension
import qupath.lib.regions.RegionRequest

def viewer = QPEx.getCurrentViewer()
def server = viewer.getImageData().getServer()

// Select an annotation
def anno = QP.getSelectedObject()

if (anno == null){
    print 'No annotation selected!\n'
def annoRoi = anno.getROI()
def annoX = annoRoi.boundsX
def annoY = annoRoi.boundsY
def region = RegionRequest.createInstance(server.getPath(), 1, annoRoi);

def imp = IJExtension.extractROIWithOverlay(server, anno, null, region, false, null).getImage();

ImageJ ij = IJExtension.getImageJInstance();
if (ij != null) {

RoiManager roiMan = RoiManager.getRoiManager()

// Collect all detections in the hierarchy below the selected annotation
def detectionsInThisAnnotation = viewer.getHierarchy().getObjectsForROI(qupath.lib.objects.PathDetectionObject, annoRoi)

detectionsInThisAnnotation.each { detect ->
    def roi = detect.getROI()

    def x = roi.boundsX - annoX
    def y = roi.boundsY - annoY

    Roi roiIJ = IJTools.convertToIJRoi(roi, 0, 0, 1)
    roiIJ.setLocation(x, y)

// Save IJ Rois (optional)
//def filePath = QPEx.buildFilePath(QPEx.PROJECT_BASE_DIR, 'rois.zip')
//roiMan.runCommand("Save", filePath)


Info can be found here Exporting annotations — QuPath 0.2.3 documentation

and for an earlier QuPath version (which may still be helpful) here


If you are using getObjectsForROI

def detectionsInThisAnnotation = viewer.getHierarchy().getObjectsForROI(qupath.lib.objects.PathDetectionObject, annoRoi)

The hierarchy actually should not matter - that’s the main use (for me at least) for using that function, as I do not need to worry about computationally expensive resolveHierarchy() statements. Which, I realize, may seem odd at first since it is a hierarchy.something command :slight_smile:

1 Like

Absolutely correct and important!
Thanks @Research_Associate for this second hint regarding this nice function :wink:

1 Like