Annotation count within an ROI

Hi Guys

I was wondering what is that is the best way to count the amount of annotation (which have been created using a classifier) and add that information to the parent Annotation as a measurement.

Would it be possible to specify maximum area size of annotation to be counted, as I would like to count protein aggregation in a particular area size range ?

Thanks in advance

Mustafa

Which version of QuPath?
What kind of classifier? Pixel? SLIC?
You could always select and remove objects that were outside of your desired size range, but be careful about whether you are working in pixels or microns.
selecting objects
https://gist.github.com/Svidro/8f9c06e2c8bcae214cdd7aa9afe57c50
removing objects
https://gist.github.com/Svidro/33558ac3bd9f68a5ec2428f74550831f

m9 and the classification is PIXEL, split
How would I count or do the sum of separate annotations within a parent annotation?

Do you need them to be annotations? It would probably be easier to sum the area of detection objects and apply them to the parent annotation, but you could do either if you can label them in some way, by class or by name.
There are some sample scripts for making summary measurements and putting them in the parent annotation here:
https://gist.github.com/Svidro/68dd668af64ad91b2f76022015dd8a45
Particularly some of the area measurements to annotations and similar scripts.

Another way of approaching it might be to not create the objects at all, since the classifier will generate the area sum and percentages automatically.

Hi
So turning them into detections does automatically give me a count within the parental annotation, so next I am trying to a attempt to remove objects greater that 10 from a specific class with the following code, to no avail

def ANNOTATION_AREA_MICRONS = 10
def server = getCurrentImageData().getServer()
double pixelHeight = server.getPixelCalibration().getPixelHeightMicrons()
double pixelWidth = server.getPixelCalibration().getPixelWidthMicrons()
def LargeObjects
LargeObjects = getDetectionObjects().findAll {
    it.getPathClass().toString().contains("aggregates") {
        it.getROI().getScaledArea(pixelWidth, pixelHeight) > ANNOTATION_AREA_MICRONS
    }
}
removeObjects(LargeObjects, true)
fireHierarchyUpdate()

println("done")

It seems it runs with no errors however object are not removed,
I 'm not sure if this is the correct way its an adaptation from Removing small annotation bits.groovy

The curly brackets contain the code that pertains to the preceeding function, so the findAll in the case of your LargeObjects variable. The second set of curly brackets has no function, so it will fail. If you want to apply two different limitations on the objects you findAll, you want to put an && between them, not a second set of brackets. && for both conditions, || for either condition.

Thank you, it seems that the newly created detections don’t seem to have the Area hence I had to do that with ShapeFeaturesPlugin which added the “ROI Shape: Area um^2.”

I guess there would need to be something else to call upon instead of it.getROI().getScaledArea

Mustafa

An alternative is getting the ROI and then using .getArea(). That gives you the area in pixels. Then use the pixelHeight and pixelWidth to convert the ANNOTATION_AREA_MICRONS into pixels (divide, I think). Either way, there doesn’t need to be an area measurement to use functions like getROI().getArea() or similar. They are accessing the size of the object itself.

Great The following works a treat, Thank you

def ANNOTATION_AREA_MICRONS = 15
def server = getCurrentImageData().getServer()
double pixelHeight = server.getPixelCalibration().getPixelHeightMicrons()
double pixelWidth = server.getPixelCalibration().getPixelWidthMicrons()
def LargeObjects = getDetectionObjects().findAll {it.getPathClass().toString().contains("aggregates") && it.getROI().getScaledArea(pixelWidth, pixelHeight) > ANNOTATION_AREA_MICRONS }
removeObjects(LargeObjects, true)
fireHierarchyUpdate()

println("done")
1 Like