use of qupath.lib.objects.PathObject in project qupath by qupath.
the class QP method getAllObjects.
/**
* Get an array of all objects in the current hierarchy.
*
* @param includeRootObject
* @return
* @see #getCurrentHierarchy
*/
public static PathObject[] getAllObjects(boolean includeRootObject) {
PathObjectHierarchy hierarchy = getCurrentHierarchy();
if (hierarchy == null)
return new PathObject[0];
var objList = hierarchy.getFlattenedObjectList(null);
if (includeRootObject)
return objList.toArray(new PathObject[0]);
return objList.parallelStream().filter(e -> !e.isRootObject()).toArray(PathObject[]::new);
}
use of qupath.lib.objects.PathObject in project qupath by qupath.
the class QP method clearAllObjects.
/**
* Remove all the objects of a specified Java class.
*
* @param cls the class, e.g. {@code PathAnnotationObject.class}, {@code PathDetectionObject.class}, or
* {@code null} if all objects should be removed.
*
* @see #getCurrentHierarchy
* @see qupath.lib.objects.hierarchy.PathObjectHierarchy#getObjects
*/
public static void clearAllObjects(final Class<? extends PathObject> cls) {
if (cls == null) {
clearAllObjects();
return;
}
PathObjectHierarchy hierarchy = getCurrentHierarchy();
if (hierarchy == null)
return;
Collection<PathObject> pathObjects = hierarchy.getObjects(null, cls);
hierarchy.removeObjects(pathObjects, true);
PathObject selected = hierarchy.getSelectionModel().getSelectedObject();
if (selected != null && selected.getClass().isAssignableFrom(cls))
hierarchy.getSelectionModel().setSelectedObject(null);
}
use of qupath.lib.objects.PathObject in project qupath by qupath.
the class QP method makeInverseAnnotation.
/**
* Make an annotation, for which the ROI is obtained by subtracting the ROIs of the specified objects from the closest
* common ancestor ROI (or entire image if the closest ancestor is the root).
* <p>
* In an inverted annotation can be created, it is added to the hierarchy and set as selected.
*
* @param imageData the image containing the annotation
* @param pathObjects the annotation to invert
* @return true if an inverted annotation is added to the hierarchy, false otherwise.
*/
public static boolean makeInverseAnnotation(final ImageData<?> imageData, Collection<PathObject> pathObjects) {
if (imageData == null)
return false;
var map = pathObjects.stream().filter(p -> p.hasROI() && p.getROI().isArea()).collect(Collectors.groupingBy(p -> p.getROI().getImagePlane()));
if (map.isEmpty()) {
logger.warn("No area annotations available - cannot created inverse ROI!");
return false;
}
if (map.size() > 1) {
logger.error("Cannot merge annotations from different image planes!");
return false;
}
ImagePlane plane = map.keySet().iterator().next();
List<PathObject> pathObjectList = map.get(plane);
PathObjectHierarchy hierarchy = imageData.getHierarchy();
// Try to get the best candidate parent
Collection<PathObject> parentSet = pathObjectList.stream().map(p -> p.getParent()).collect(Collectors.toCollection(HashSet::new));
PathObject parent;
if (parentSet.size() > 1) {
parentSet.clear();
boolean firstTime = true;
for (PathObject temp : pathObjectList) {
if (firstTime)
parentSet.addAll(PathObjectTools.getAncestorList(temp));
else
parentSet.retainAll(PathObjectTools.getAncestorList(temp));
firstTime = false;
}
List<PathObject> parents = new ArrayList<>(parentSet);
Collections.sort(parents, Comparator.comparingInt(PathObject::getLevel).reversed().thenComparingDouble(p -> p.hasROI() ? p.getROI().getArea() : Double.MAX_VALUE));
parent = parents.get(0);
} else
parent = parentSet.iterator().next();
// Get the parent area
Geometry geometryParent;
if (parent == null || parent.isRootObject() || !parent.hasROI())
geometryParent = GeometryTools.createRectangle(0, 0, imageData.getServer().getWidth(), imageData.getServer().getHeight());
else
geometryParent = parent.getROI().getGeometry();
// Get the parent area to use
var union = GeometryTools.union(pathObjectList.stream().map(p -> p.getROI().getGeometry()).collect(Collectors.toList()));
var geometry = geometryParent.difference(union);
// Create the new ROI
ROI shapeNew = GeometryTools.geometryToROI(geometry, plane);
PathObject pathObjectNew = PathObjects.createAnnotationObject(shapeNew);
parent.addPathObject(pathObjectNew);
hierarchy.fireHierarchyChangedEvent(parent);
hierarchy.getSelectionModel().setSelectedObject(pathObjectNew);
return true;
}
use of qupath.lib.objects.PathObject in project qupath by qupath.
the class ObjectMeasurements method addShapeMeasurements.
/**
* Add shape measurements for multiple objects. If any of these objects is a cell, measurements will be made for both the
* nucleus and cell boundary where possible.
*
* @param pathObjects the objects for which measurements should be added
* @param cal pixel calibration, used to determine units and scaling
* @param features specific features to add; if empty, all available shape features will be added
*/
public static void addShapeMeasurements(Collection<? extends PathObject> pathObjects, PixelCalibration cal, ShapeFeatures... features) {
PixelCalibration calibration = cal == null || !cal.unitsMatch2D() ? PixelCalibration.getDefaultInstance() : cal;
Collection<ShapeFeatures> featureCollection = features.length == 0 ? ALL_SHAPE_FEATURES : Arrays.asList(features);
pathObjects.parallelStream().filter(p -> p.hasROI()).forEach(pathObject -> {
if (pathObject instanceof PathCellObject) {
addCellShapeMeasurements((PathCellObject) pathObject, calibration, featureCollection);
} else {
try (var ml = pathObject.getMeasurementList()) {
addShapeMeasurements(ml, pathObject.getROI(), calibration, "", featureCollection);
}
}
});
}
use of qupath.lib.objects.PathObject in project qupath by qupath.
the class SmoothFeaturesPlugin method getParentObjects.
@Override
protected Collection<PathObject> getParentObjects(final PluginRunner<T> runner) {
PathObjectHierarchy hierarchy = runner.getImageData().getHierarchy();
List<PathObject> parents = new ArrayList<>();
if (hierarchy.getTMAGrid() != null) {
logger.info("Smoothing using TMA cores");
for (TMACoreObject core : hierarchy.getTMAGrid().getTMACoreList()) {
if (core.hasChildren())
parents.add(core);
}
} else {
for (PathObject pathObject : hierarchy.getSelectionModel().getSelectedObjects()) {
if (pathObject.isAnnotation() && pathObject.hasChildren())
parents.add(pathObject);
}
if (!parents.isEmpty())
logger.warn("Smoothing using annotations");
}
return parents;
}
Aggregations