Created
February 28, 2025 17:45
-
-
Save caner-ercan/c947fe9ee2f7ca6bce538b5e948d19ac to your computer and use it in GitHub Desktop.
QuPath_Polyscope
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| 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