Drawing custom annotations

I am trying to draw annotations using the example here Script of the Day: Create new annotations and it never shows in the view until I delete any old annotation that was not added by code. Do I have to refresh the view somehow? is there any update() method I can call to refresh the view?

If I want to add a polygon should I add a polyline or a polygon roi?

A rectangle is fine as well.

Should I invoke all its methods so that I get the convex hull and so on, in case qupath needs it for something? or is it automatic?

Can you please post the exact script you use, and state which version of QuPath.
If you want to add a closed polygon, you should add a PolygonROI.
Polylines aren’t supported in v0.1.2 anyway.

This is the script, I am running it directly in the script editor in qupath

import qupath.lib.objects.PathAnnotationObject
import qupath.lib.objects.classes.PathClassFactory
import qupath.lib.roi.RectangleROI

// Get main data structures
def imageData = getCurrentImageData()

// Convert size in microns to pixels - QuPath ROIs are defined in pixel units of the full-resolution image
int sizePixels = 5000

// Get the current viewer & the location of the pixel currently in the center
def viewer = getCurrentViewer()
double cx = viewer.getCenterPixelX()
double cy = viewer.getCenterPixelY()

// Create a new Rectangle ROI
def roi = new RectangleROI(cx-sizePixels/2, cy-sizePixels/2, sizePixels, sizePixels)

// Create & new annotation & add it to the object hierarchy
def annotation = new PathAnnotationObject(roi, PathClassFactory.getPathClass("Region"))
imageData.getHierarchy().addPathObject(annotation, false)

I am using v 0.2.0 m3

ps
This doesn’t work getAveragedPixelSizeMicrons
int sizePixels = Math.round(sizeMicrons / server.getAveragedPixelSizeMicrons())

Try changing

imageData.getHierarchy().addPathObject(annotation, false)

to become

imageData.getHierarchy().addPathObject(annotation, true)

You can also change

server.getAveragedPixelSizeMicrons()

to

server.getPixelCalibration().getAveragedPixelSizeMicrons()
1 Like

Thank you! I feel so silly now.

Don’t, it needs more documentation :slight_smile:

Thanks Pete. Quick question. About groovy. QuPath comes with it’s own groovy SDK? how can I use my system’s groovy? Working with IntelliJ I can load all the thing my groovy has but not in QuPath.

If you find the missing jar files, you can drag them on top of QuPath and thereby install them to the extensions directory, e.g. see https://github.com/qupath/qupath/issues/238

There are lots of jars with Groovy that likely aren’t very relevant within QuPath so aren’t included. However it might be worth adding one or two of the most useful ones if they could be helpful for others. Which do you need?

1 Like

Id like to use groovy.json I don’t have many other suggestions but it is good to know I can just drag them and have the used :slight_smile: thanks

For reading or writing JSON?
Gson is included with QuPath already and I find it quite nice to use.

Yeah you mentioned it, and it is good to know, but I am not working with geography data, I don’t want to include much overhead, and I need documentation (groovy 257 api) :sweat_smile:

I think you’re thinking of GeoJSON / Java Topology Suite.

Gson is here: https://github.com/google/gson
Easy to use, lots of documentation… and much less overhead if you consider the need to install an extra jar as overhead.

Hmm yes I was just reading it.

Ok so it seems good

With this I load my file and I am able to find the things I need without creating a class for the objects contained (which was my only excuse for not using it haha)

import qupath.lib.io.GsonTools

def gson=GsonTools.getInstance(true)
BufferedReader bufferedReader = new BufferedReader(new FileReader("/path/to/json/file.json"));
HashMap<String, String> myjson = gson.fromJson(bufferedReader, HashMap.class); 

print(myjson)

I wanted to use JsonSlurper though

import groovy.json.JsonSlurper
def inputFile = new File("/your/path/my.json")
def InputJSON = new JsonSlurper().parseFile(inputFile, 'UTF-8')
InputJSON.each{ println it }