Shape parameters for annotations

117/5000

Hello everyone! I need help. Would it be possible to add the “Circularity” parameter to this script? thank you

import qupath.imagej.objects.*

getAnnotationObjects().each {
    def ml = it.getMeasurementList()
    def roi = it.getROI()
    def roiIJ = ROIConverterIJ.convertToIJRoi(roi, 0, 0, 1)
    def maxDiam = roiIJ.getFeretValues()[0]
    def minDiam = roiIJ.getFeretValues()[2]
    ml.putMeasurement('Feret max diameter', maxDiam)
    ml.putMeasurement('Feret min diameter', minDiam)
    ml.putMeasurement('Average diameter', (minDiam+maxDiam)/2)
    
    
    ml.closeList()
}
fireHierarchyUpdate()
print "done"

The problem is that these parameters are only for detections, cells and TMA cores. I need to calculate them for annotations. Since with this script I can calculate Feret’s diameters, I was wondering if circularity could also be calculated. if this is not possible, I will have to transform these annotations into detection (but I would like to avoid it because the annotations are marked with specific classes)

For most objects you would want to run the Add Shape Features command, but unfortunately that will not work for annotations. The calculation itself is fairly simple, meaning that as long as you can access the area and perimeter measurements for the annotation, you should be fine. Getting those measurements can be a bit tricky.
Accessing those measurements is shown here:
https://gist.github.com/Svidro/68dd668af64ad91b2f76022015dd8a45#file-accessing-dynamic-measurements-groovy

The following script seems to work in 0.2.0m8, I haven’t tried it in other versions.

import qupath.lib.gui.models.ObservableMeasurementTableData
def ob = new ObservableMeasurementTableData();

def annotations = getAnnotationObjects()
 // This line creates all the measurements
ob.setImageData(getCurrentImageData(),  annotations);


annotations.each { 
    area=ob.getNumericValue(it, "Area µm^2")
    perimeter=ob.getNumericValue(it, "Perimeter µm")
    circularity = 4*3.14159*area/(perimeter*perimeter)
    it.getMeasurementList().putMeasurement("Circularity", circularity)
}

Note that in some earlier versions of the software, holes and splits in the annotation would break the perimeter calculation. In 0.2.0m8, any holes in the annotations ALSO count towards the perimeter. Annotations that are split have a perimeter that is the sum of all individual pieces. Depending on the version and how the annotations were generated, you may need to check whether all objects have working perimeters and areas.

1 Like

Thank you! the script runs in the earlier version, too.

1 Like

I have noticed a strange thing. If I copy and paste the code into the script editor, it runs. If i save the script, I open it in a second moment, I can view only the perimeter and area, but not the circularity. I don’t know if it happens only in old version ( i use 0.1.2), but it’s very strange.

Not sure what you mean, but the circularity should only show up after you have run the script. Any new images, need to run the script again. Same with adding any new annotations, since it is only adding the values to current annotations.

i have just tried the script with M7. it doesn0t run if you open the script (it only shows the area and perimeter, but not the circularity). If you copy the script (for example from Notes or from this forum) on script editor, you click Run and it shows the circularity too

In QuPath v0.1.2 the µ symbol could become mangled when you close/reopen a script in certain circumstances (I think on Windows but not on Mac).

The script file encoding has been changed in v0.2.0 to resolve this issue. However, many other changes in v0.2.0 mean that scripts often need updated to work, e.g. see here.

Since v0.2.0 remains a work-in-progress and is not backwards-compatible with v0.1.2, I think v0.1.2 is probably still the best version to use for many people until v0.2.0 is stabilized.

Oh, right, been a while and forgot about that.

For adding a micrometer symbol in v1.2, use " + qupath.lib.common.GeneralTools.micrometerSymbol() + "

From the making measurements scripts list. There should be some scripts around that use that method, if you search for it.