Loop through child annotations and make inverse

Hi,

QuPath very nicely sends annotations to ImageJ, but devoid of the location. I’d like to send the inverse of annotations, then re-invert in ImageJ to effectively position the ROI at its location in the origin image. I want to invert only the child detections of one particular annotation (a rectangle). How can I script this; how can I loop through the children of an annotation in QuPath?

Thanks!

-Esteban

Hi, it’s not completely clear to me how you are sending annotations to ImageJ / what isn’t working.

QuPath does encode the position information when it sends regions to ImageJ – this is stored in the image properties (the ‘origin’ entry, although it must also be interpreted in combination with the pixel size information for scaling):
https://qupath.readthedocs.io/en/latest/docs/advanced/imagej.html#sending-image-regions-to-imagej

Can you describe (perhaps with a screenshot) what the ultimate aim is? From your post, I’m not certain whether there needs to be an ImageJ step at all – it might be easier to modify/invert the geometries directly, without ImageJ.

1 Like

Thanks for responding Pete. In QuPath I use ImageJ > Send Regions to ImageJ. That creates a tiny image for each ROI, with the ROI devoid of its position info in the original image.

If I invert the ROI before sending then I get a ROI the size of the full image, minus the ROI itself, then I just re-invert in ImageJ and I have the original ROI positioned within the full image.

I use QuPath for cell detection and want to transfer the detections to ImageJ for further analysis that I already have macros for. I need a subset of detections that are all under one parent.

I’d like to know how to loop all child detections so I can invert them quickly with makeInverseAnnotation().

-Esteban

If you send the annotation of interest to ImageJ, then all the detections can be sent too as an ImageJ overlay if the ‘Include overlay’ option is selected:
https://qupath.readthedocs.io/en/latest/docs/advanced/imagej.html#qupath-objects-and-imagej-rois

From that, you can access the rois in ImageJ or send them to the ROI Manager.

2 Likes

Sweet, thank you, that does what I need.

For future use, is it possible in QuPath scripting to iterate over all child detections of one annotation?

-Esteban

Something like


listOfObjectsHere.each{
    print(it);
}

Note that getChildObjects only works if the objects are actually child objects, not simply contained within the larger object. So if you are not getting any results from getChildObjects, you likely need to resolveHierarchy()

Also this recent post if you want a reference for translating that into single annotations. Though if you have multiple you will need some attribute to specify them by.

1 Like

Yes, you can use pathObject.getChildObjects() – but it’s risky inasmuch as it depends upon the hierarchy being as you wish (and if there are annotations inside annotations then some of the detections might not be direct ‘children’…).

If you want something more region-based, you can use

def selected = getSelectedObject()
def roi = selected.getROI()

def hierarchy = getCurrentHierarchy()
def pathObjects = hierarchy.getObjectsForROI(null, roi)
println pathObjects

which uses the same rules as the hierarchy for deciding if objects are inside the specified ROI, but without caring whether the hierarchical relationships have been resolved internally or not.

Note: You might need to take care to avoid counting the outer ROI using that method.

1 Like