import qupath.lib.objects.classes.PathClassFactory
//use add intensity features to add whatever values you need to determine a class.
//Here I used optical density only.
selectAnnotations();
runPlugin('qupath.lib.algorithms.IntensityFeaturesPlugin', '{"pixelSizeMicrons": 2.0, "region": "ROI", "tileSizeMicrons": 25.0, "colorOD": true, "colorStain1": false, "colorStain2": false, "colorStain3": false, "colorRed": false, "colorGreen": false, "colorBlue": false, "colorHue": false, "colorSaturation": false, "colorBrightness": false, "doMean": false, "doStdDev": false, "doMinMax": false, "doMedian": false, "doHaralick": false, "haralickDistance": 1, "haralickBins": 32}');
def ClassA = PathClassFactory.getPathClass("ClassA")
def ClassB = PathClassFactory.getPathClass("ClassB")
//feature has to be exact, including spaces. This can be tricky
def feature = "Exact string for name of measurement"
//get all annotations in the image
Annotations = getAnnotationObjects();
Annotations.each {
double value = it.getMeasurementList().getMeasurementValue(feature)
//use logic here to determine whether each "it" or annotation will be a given class
//this can be as complicated as you want, or as simple as a single if statement.
if (value > 0.5) {it.setPathClass(ClassA)}
else { it.setPathClass(ClassB)}
}
println("Annotation classification done")
def feature = "Exact string for name of measurement"
I don´t know what a string is. What do I need to write there, if i want to use DAB mean as a feature?
Best and thanks a lot.
David
/*
* A script to create detection object(s) having the same ROI as all other annotation objects
*/
import qupath.lib.objects.PathTileObject
import qupath.lib.roi.RectangleROI
import qupath.lib.scripting.QP
// Set this to true to use the bounding box of the ROI, rather than the ROI itself
boolean useBoundingBox = false
// Get the current hierarchy
def hierarchy = QP.getCurrentHierarchy()
// Get the select objects
def selected = getAnnotationObjects()
// Check we have anything to work with
if (selected.isEmpty()) {
print("No objects selected!")
return
}
// Loop through objects
def newDetections = new ArrayList<>()
for (def pathObject in selected) {
// Unlikely to happen... but skip any objects not having a ROI
if (!pathObject.hasROI()) {
print("Skipping object without ROI: " + pathObject)
continue
}
// Don't create a second annotation, unless we want a bounding box
if (!useBoundingBox && pathObject.isDetection()) {
print("Skipping annotation: " + pathObject)
continue
}
// Create an annotation for whichever object is selected, with the same class
// Note: because ROIs are (or should be) immutable, the same ROI is used here, rather than a duplicate
def roi = pathObject.getROI()
if (useBoundingBox)
roi = new RectangleROI(
roi.getBoundsX(),
roi.getBoundsY(),
roi.getBoundsWidth(),
roi.getBoundsHeight(),
roi.getC(),
roi.getZ(),
roi.getT())
def detection = new PathTileObject(roi, pathObject.getPathClass())
newDetections.add(detection)
print("Adding " + detection)
}
// Actually add the objects
hierarchy.addPathObjects(newDetections, false)
if (newDetections.size() > 1)
print("Added " + newDetections.size() + " detections(s)")
detections = getDetectionObjects();
detections.each{
itClass = it.getPathClass()
it.getParent().setPathClass(itClass)
}
fireHierarchyUpdate()
detections = getDetectionObjects();
detections.each{
itClass = it.getPathClass()
it.getParent().setPathClass(itClass)
}
fireHierarchyUpdate();