Skip to content

Instantly share code, notes, and snippets.

@caner-ercan
Created February 28, 2025 17:45
Show Gist options
  • Select an option

  • Save caner-ercan/c947fe9ee2f7ca6bce538b5e948d19ac to your computer and use it in GitHub Desktop.

Select an option

Save caner-ercan/c947fe9ee2f7ca6bce538b5e948d19ac to your computer and use it in GitHub Desktop.
QuPath_Polyscope
/*
Purpose:
This QuPath script exports annotations to a CSV file in a format compatible with Polyscope.
The output file must be copied into the following directory in Polyscope:
`..//polyscope/polyzoomer/PathXXXX_XXX/page/imagename/_imagename/annotations.txt`
Works with any version of QuPath—until further notice (or disaster).
Author: Caner Ercan
Date: 28.02.2025
License:
This code is protected under extremely strict intellectual property laws.
The user must compensate the author for any use of this code.
Payment terms:
- 1 beer of the author's choice per 1,000 points or 100 polygon annotations.
In case of disagreement, the author and the user shall resolve the conflict exportthrough an honorable duel.
*/
def folder = buildFilePath(PROJECT_BASE_DIR, "annotations")
def imagename = getCurrentImageNameWithoutExtension()
def path = buildFilePath(folder, imagename + "_annotations.csv")
// Create the folder if it doesn't exist
def directory = new File(folder)
if (!directory.exists()) {
directory.mkdir()
}
def file = new File(path)
file.text = ''
def roi_count = 1
//write function to get file, x, y, count and convert them to x_rel, y_rel, create line, write to file and return updated count
def write_to_file_point(file, x, y, count) {
def type = 6
def server = getCurrentServer()
def w = server.getWidth()
def h = server.getHeight()
def line_end = ",#ffffff,12/4/1961/08:07:00"
//convert x and y to relative coordinates
def x_rel = x / w
def y_rel = y / w
//write to file
def line = "1," + count + "," + type + ",[(" + x_rel + "," + y_rel + "),(" + x_rel + "," + y_rel + ")]" + line_end
file << line << System.lineSeparator()
count = count + 1
return count
}
def write_to_file_rectangle(file, x1, y1, x2, y2, count) {
def type = 2
def server = getCurrentServer()
def w = server.getWidth()
def h = server.getHeight()
def line_end = ",#ffffff,12/4/1961/08:07:00"
//convert x and y to relative coordinates
def x_rel1 = x1 / w
def y_rel1 = y1 / w
def x_rel2 = x2 / w
def y_rel2 = y2 / w
//write to file
def line = "1," + count + "," + type + ",[(" + x_rel1 + "," + y_rel1 + "),(" + x_rel2 + "," + y_rel2 + ")]" + line_end
file << line << System.lineSeparator()
count = count + 1
return count
}
def convert_polygon_to_txt(file, roi, count) {
def type = 4
def server = getCurrentServer()
def w = server.getWidth()
def h = server.getHeight()
def line_end = ",#ffffff,12/4/1961/08:07:00"
def array_txt = "["
def first = true
roi.getAllPoints().each {
def x_rel = it.getX() / w
def y_rel = it.getY() / w
if (!first) {
array_txt = array_txt + ","
}
first = false
array_txt = array_txt + "(" + x_rel + "," + y_rel + ")"
}
array_txt = array_txt + "]"
def line = "1," + count + "," + type + "," + array_txt + line_end
file << line << System.lineSeparator()
count = count + 1
return count
}
for (pathObject in getAnnotationObjects()) {
// Check for interrupt (Run -> Kill running script)
if (Thread.interrupted())
break
// Get the ROI
def roi = pathObject.getROI()
if (roi.isPoint()) {
//get x and y coordinates
roi.getAllPoints().each {
//for each point, create a circle on top of it that is "size" pixels in diameter
def x = it.x
def y = it.y
roi_count = write_to_file_point(file, x, y, roi_count)
}
} else {
def roi_type = roi.getRoiName()
if (roi_type == "Polygon") {
roi_count = convert_polygon_to_txt(file, roi, roi_count)
} else if (roi_type == "Rectangle") {
def tl_point = roi.getAllPoints()[0]
def br_point = roi.getAllPoints()[2]
roi_count = write_to_file_rectangle(file, tl_point.getX(), tl_point.getY(), br_point.getX(), br_point.getY(), roi_count)
} else if (roi_type == "Ellipse") {
// will be added later
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment