Skip to content

Instantly share code, notes, and snippets.

@DanaCase
Last active May 6, 2023 09:05
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save DanaCase/9cfc23912fee48e437af03f97763d78e to your computer and use it in GitHub Desktop.
Save DanaCase/9cfc23912fee48e437af03f97763d78e to your computer and use it in GitHub Desktop.
Convert Exported Aperio Image Scope Annotations to QuPath Annotations
import qupath.lib.scripting.QP
import qupath.lib.geom.Point2
import qupath.lib.roi.PolygonROI
import qupath.lib.objects.PathAnnotationObject
import qupath.lib.images.servers.ImageServer
//Aperio Image Scope displays images in a different orientation
def rotated = true
def server = QP.getCurrentImageData().getServer()
def h = server.getHeight()
def w = server.getWidth()
// need to add annotations to hierarchy so qupath sees them
def hierarchy = QP.getCurrentHierarchy()
//Prompt user for exported aperio image scope annotation file
def file = getQuPath().getDialogHelper().promptForFile('xml', null, 'aperio xml file', null)
def text = file.getText()
def list = new XmlSlurper().parseText(text)
list.Annotation.each {
it.Regions.Region.each { region ->
def tmp_points_list = []
region.Vertices.Vertex.each{ vertex ->
if (rotated) {
X = vertex.@Y.toDouble()
Y = h - vertex.@X.toDouble()
}
else {
X = vertex.@X.toDouble()
Y = vertex.@Y.toDouble()
}
tmp_points_list.add(new Point2(X, Y))
}
def roi = new PolygonROI(tmp_points_list)
def annotation = new PathAnnotationObject(roi)
hierarchy.addPathObject(annotation, false)
}
}
@MichaelSNelson
Copy link

The latter error and the solution can be found on the image.sc forum.

I am not sure about the XmlSlurper though. It is likely due to reorganization of the functions used: https://stackoverflow.com/questions/55169114/unable-to-add-xmlslurper-to-eclipse-groovy-project
https://stackoverflow.com/questions/11245073/groovy-2-cant-find-jsonslurper-and-xmlslurper-anymore
Etc. I am not sure what the exact solution for QuPath will be.

@PerfidAlbion
Copy link

Thanks for the answer. I have managed to make it work :

Here is the script that worked for me :

"import qupath.lib.scripting.QP
import qupath.lib.geom.Point2
import qupath.lib.roi.PolygonROI
import qupath.lib.objects.PathAnnotationObject
import qupath.lib.images.servers.ImageServer

//Aperio Image Scope displays images in a different orientation
def rotated = false

def server = QP.getCurrentImageData().getServer()
def h = server.getHeight()
def w = server.getWidth()

// need to add annotations to hierarchy so qupath sees them
def hierarchy = QP.getCurrentHierarchy()

//Prompt user for exported aperio image scope annotation file
def file = Dialogs.promptForFile('xml', null, 'aperio xml file', null)
def text = file.getText()

def list = new XmlSlurper().parseText(text)

list.Annotation.each {

it.Regions.Region.each { region ->

    def tmp_points_list = []

    region.Vertices.Vertex.each{ vertex ->

        if (rotated) {
            X = vertex.@Y.toDouble()
            Y = h - vertex.@X.toDouble()
        }
        else {
            X = vertex.@X.toDouble()
            Y = vertex.@Y.toDouble()
        }
        tmp_points_list.add(new Point2(X, Y))
    }

    def roi = new PolygonROI(tmp_points_list)

    def annotation = new PathAnnotationObject(roi)

    hierarchy.addObject(annotation, false)
}

}"

I changed the following ::

replace getQuPath().getDialogHelper().promptForFile( with Dialogs.promptForFile(
replace hierarchy.addPathObject(annotation, false) with hierarchy.addObject(annotation, false)
Used version groovy-xml-3.0.17

Hope it helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment