Hello. I am using QuPath 0.2.0-m3
I was looking for a way to import annotations after exporting from QuPath, classifying outside and importing again to check and change in QuPath.
At first I had trouble creating the ROI, as I had the similar problem as here: Example of creating polygonROI
In the end, after reading the code directly on github, the code I came up with is the one below. The problem is that I can’t correct the annotations once they are created, I was hoping to be able to modify them inside QuPath by selecting them and clicking change class.
import qupath.lib.objects.PathObjects
import qupath.lib.roi.ROIs
import qupath.lib.regions.ImagePlane
import qupath.lib.io.GsonTools
import qupath.lib.geom.Point2
def plane = ImagePlane.getPlane(0, 0)
def gson=GsonTools.getInstance(true)
BufferedReader bufferedReader = new BufferedReader(new FileReader("myjsonfile.json"));
HashMap<String, String> myjson = gson.fromJson(bufferedReader, HashMap.class);
xCoords = myjson["allx"]
yCoords = myjson["ally"]
classes_index = myjson["allc"]
c0 = getPathClass("Class0")
c1 = getPathClass("Class1")
c2 = getPathClass("Class2")
c3 = getPathClass("Class3")
c4 = getPathClass("Class4")
c5 = getPathClass("Class5")
classes=[c0,c1,c2,c3,c4,c5]
for (c=0; c < xCoords.size(); c++) {
List<Point2> points = []
def xarr= xCoords[c] as double[]
def yarr= yCoords[c] as double[]
for( i=0; i< xarr.size();i++){
points.add(new Point2(xarr[i], yarr[i]));
}
def cell_roi = ROIs.createPolygonROI(points, plane)
def cell = PathObjects.createDetectionObject(cell_roi)
addObject(cell)
cell.setPathClass(classes[(int) classes_index[c]])
}
First, any hierarchy update results in an error. Second running my script manages to add the polygons with their correct classes but I get a popup with the log that appears as many times as I have classes. Then I also get an error like this one per annotation:
ERROR: QuPath exception
at java.base/java.util.LinkedHashMap$LinkedHashIterator.nextNode(Unknown Source)
at java.base/java.util.LinkedHashMap$LinkedKeyIterator.next(Unknown Source)
at java.base/java.util.AbstractCollection.toArray(Unknown Source)
at java.base/java.util.Collections$UnmodifiableCollection.toArray(Unknown Source)
at qupath.lib.gui.panels.PathObjectHierarchyView$3.getChildren(PathObjectHierarchyView.java:480)
at qupath.lib.gui.panels.PathObjectHierarchyView$3.isLeaf(PathObjectHierarchyView.java:491)
at javafx.scene.control.TreeItem$4.invalidated(TreeItem.java:558)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:145)
at javafx.beans.property.BooleanProperty.setValue(BooleanProperty.java:81)
at javafx.scene.control.TreeItem.setExpanded(TreeItem.java:539)
at javafx.scene.control.TreeView.updateRootExpanded(TreeView.java:1090)
at javafx.scene.control.TreeView$1.invalidated(TreeView.java:462)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
at javafx.scene.control.TreeView.setRoot(TreeView.java:474)
at qupath.lib.gui.panels.PathObjectHierarchyView.hierarchyChanged(PathObjectHierarchyView.java:510)
at qupath.lib.gui.panels.PathObjectHierarchyView.lambda$hierarchyChanged$8(PathObjectHierarchyView.java:506)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
at java.base/java.lang.Thread.run(Unknown Source)
and it results in permanent objects whose class I can’t change in the interface.
Can you tell me what can I do? what am I missing in my ROI creation to make it selectable and editable in QuPath?