Search in sources :

Example 56 with ROI

use of qupath.lib.roi.interfaces.ROI in project qupath by qupath.

the class PixelClassifierTools method classifyObjectsByCentroid.

/**
 * Apply classification from a server to a collection of objects.
 *
 * @param classifierServer an {@link ImageServer} with output type
 * @param pathObjects
 * @param preferNucleusROI
 */
public static void classifyObjectsByCentroid(ImageServer<BufferedImage> classifierServer, Collection<PathObject> pathObjects, boolean preferNucleusROI) {
    var labels = classifierServer.getMetadata().getClassificationLabels();
    var reclassifiers = pathObjects.parallelStream().map(p -> {
        try {
            var roi = PathObjectTools.getROI(p, preferNucleusROI);
            int x = (int) roi.getCentroidX();
            int y = (int) roi.getCentroidY();
            int ind = getClassification(classifierServer, x, y, roi.getZ(), roi.getT());
            return new Reclassifier(p, labels.getOrDefault(ind, null), false);
        } catch (Exception e) {
            return new Reclassifier(p, null, false);
        }
    }).collect(Collectors.toList());
    reclassifiers.parallelStream().forEach(r -> r.apply());
}
Also used : ImageServer(qupath.lib.images.servers.ImageServer) Arrays(java.util.Arrays) PathClassTools(qupath.lib.objects.classes.PathClassTools) LoggerFactory(org.slf4j.LoggerFactory) PathClassFactory(qupath.lib.objects.classes.PathClassFactory) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) ChannelThreshold(qupath.lib.analysis.images.ContourTracing.ChannelThreshold) Function(java.util.function.Function) ArrayList(java.util.ArrayList) ClassifierFunction(qupath.opencv.ml.pixel.PixelClassifiers.ClassifierFunction) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) ChannelType(qupath.lib.images.servers.ImageServerMetadata.ChannelType) Map(java.util.Map) Reclassifier(qupath.lib.objects.classes.Reclassifier) GeometryTools(qupath.lib.roi.GeometryTools) ImageData(qupath.lib.images.ImageData) Logger(org.slf4j.Logger) RegionRequest(qupath.lib.regions.RegionRequest) BufferedImage(java.awt.image.BufferedImage) PathObjects(qupath.lib.objects.PathObjects) Collection(java.util.Collection) PathClass(qupath.lib.objects.classes.PathClass) Set(java.util.Set) DefaultPathObjectComparator(qupath.lib.objects.DefaultPathObjectComparator) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) PathObjectTools(qupath.lib.objects.PathObjectTools) PathObject(qupath.lib.objects.PathObject) ROI(qupath.lib.roi.interfaces.ROI) List(java.util.List) PixelClassifier(qupath.lib.classifiers.pixel.PixelClassifier) PixelClassificationImageServer(qupath.lib.classifiers.pixel.PixelClassificationImageServer) ColorModel(java.awt.image.ColorModel) ContourTracing(qupath.lib.analysis.images.ContourTracing) ImagePlane(qupath.lib.regions.ImagePlane) Geometry(org.locationtech.jts.geom.Geometry) Comparator(java.util.Comparator) Collections(java.util.Collections) ImageServerMetadata(qupath.lib.images.servers.ImageServerMetadata) DataBuffer(java.awt.image.DataBuffer) Reclassifier(qupath.lib.objects.classes.Reclassifier) IOException(java.io.IOException)

Example 57 with ROI

use of qupath.lib.roi.interfaces.ROI in project qupath by qupath.

the class PathObjectTools method transformObject.

/**
 * Create a(n optionally) transformed version of a {@link PathObject}.
 * <p>
 * Note: only detections (including tiles and cells) and annotations are fully supported by this method.
 * Root objects are duplicated.
 * TMA core objects are transformed only if the resulting transform creates an ellipse ROI, since this is
 * currently the only ROI type supported for a TMA core (this behavior may change).
 * Any other object types result in an {@link UnsupportedOperationException} being thrown.
 *
 * @param pathObject the object to transform; this will be unchanged
 * @param transform optional affine transform; if {@code null}, this effectively acts to duplicate the object
 * @param copyMeasurements if true, the measurement list of the new object will be populated with the measurements of pathObject
 *
 * @return a duplicate of pathObject, with affine transform applied to the object's ROI(s) if required
 */
public static PathObject transformObject(PathObject pathObject, AffineTransform transform, boolean copyMeasurements) {
    ROI roi = maybeTransformROI(pathObject.getROI(), transform);
    PathClass pathClass = pathObject.getPathClass();
    PathObject newObject;
    if (pathObject instanceof PathCellObject) {
        ROI roiNucleus = maybeTransformROI(((PathCellObject) pathObject).getNucleusROI(), transform);
        newObject = PathObjects.createCellObject(roi, roiNucleus, pathClass, null);
    } else if (pathObject instanceof PathTileObject) {
        newObject = PathObjects.createTileObject(roi, pathClass, null);
    } else if (pathObject instanceof PathDetectionObject) {
        newObject = PathObjects.createDetectionObject(roi, pathClass, null);
    } else if (pathObject instanceof PathAnnotationObject) {
        newObject = PathObjects.createAnnotationObject(roi, pathClass, null);
    } else if (pathObject instanceof PathRootObject) {
        newObject = new PathRootObject();
    } else if (pathObject instanceof TMACoreObject && roi instanceof EllipseROI) {
        var core = (TMACoreObject) pathObject;
        newObject = PathObjects.createTMACoreObject(roi.getBoundsX(), roi.getBoundsY(), roi.getBoundsWidth(), roi.getBoundsHeight(), core.isMissing());
    } else
        throw new UnsupportedOperationException("Unable to transform object " + pathObject);
    if (copyMeasurements && !pathObject.getMeasurementList().isEmpty()) {
        MeasurementList measurements = pathObject.getMeasurementList();
        for (int i = 0; i < measurements.size(); i++) {
            String name = measurements.getMeasurementName(i);
            double value = measurements.getMeasurementValue(i);
            newObject.getMeasurementList().addMeasurement(name, value);
        }
        newObject.getMeasurementList().close();
    }
    return newObject;
}
Also used : MeasurementList(qupath.lib.measurements.MeasurementList) EllipseROI(qupath.lib.roi.EllipseROI) PointsROI(qupath.lib.roi.PointsROI) LineROI(qupath.lib.roi.LineROI) ROI(qupath.lib.roi.interfaces.ROI) PathClass(qupath.lib.objects.classes.PathClass) EllipseROI(qupath.lib.roi.EllipseROI)

Example 58 with ROI

use of qupath.lib.roi.interfaces.ROI in project qupath by qupath.

the class PathObjectTools method mergePointsForSelectedObjectClasses.

// private static void addPathObjectsRecursively(Collection<PathObject> pathObjectsInput, Collection<PathObject> pathObjects, Class<? extends PathObject> cls) {
// Collection<PathObject> buffer = null;
// for (PathObject childObject : pathObjectsInput) {
// if (cls == null || cls.isInstance(childObject)) {
// pathObjects.add(childObject);
// }
// if (childObject.hasChildren()) {
// if (buffer == null)
// buffer = new ArrayList<>();
// else
// buffer.clear();
// childObject.getChildObjects(buffer);
// addPathObjectsRecursively(buffer, pathObjects, cls);
// }
// }
// }
// /**
// * Split annotations containing multi-point ROIs into separate single-point ROIs.
// *
// * @param hierarchy the object hierarchy
// * @param selectedOnly if true, consider only annotations that are currently selected; if false, consider all point annotations in the hierarchy
// * @return true if changes are made to the hierarchy, false otherwise
// */
// public static boolean splitPoints(PathObjectHierarchy hierarchy, boolean selectedOnly) {
// if (hierarchy == null) {
// logger.debug("No hierarchy available, cannot split points!");
// return false;
// }
// return splitPoints(hierarchy, selectedOnly ? hierarchy.getSelectionModel().getSelectedObjects() : hierarchy.getAnnotationObjects());
// }
// 
// /**
// * Split annotations containing multi-point ROIs into separate single-point ROIs.
// *
// * @param hierarchy the object hierarchy
// * @param pathObjects a collection of point annotations to split; non-points and non-annotations will be ignored
// * @return pathObjects if changes are made to the hierarchy, false otherwise
// */
// public static boolean splitPoints(PathObjectHierarchy hierarchy, Collection<PathObject> pathObjects) {
// var points = pathObjects.stream().filter(p -> p.isAnnotation() && p.getROI().isPoint() && p.getROI().getNumPoints() > 1).collect(Collectors.toList());
// if (points.isEmpty()) {
// logger.debug("No (multi)point ROIs available to split!");
// return false;
// }
// List<PathObject> newObjects = new ArrayList<>();
// for (PathObject pathObject : points) {
// ROI p = pathObject.getROI();
// ImagePlane plane = p.getImagePlane();
// PathClass pathClass = pathObject.getPathClass();
// for (Point2 p2 : p.getAllPoints()) {
// PathObject temp = PathObjects.createAnnotationObject(ROIs.createPointsROI(p2.getX(), p2.getY(), plane), pathClass);
// newObjects.add(temp);
// }
// }
// hierarchy.removeObjects(points, true);
// hierarchy.addPathObjects(newObjects);
// // Reset the selection
// hierarchy.getSelectionModel().clearSelection();
// return true;
// }
/**
 * Merge point annotations sharing the same {@link PathClass} and {@link ImagePlane} as the selected annotations,
 * creating multi-point annotations for all matching points and removing the (previously-separated) annotations.
 *
 * @param hierarchy object hierarchy to modify
 * @return true if changes are made to the hierarchy, false otherwise
 */
public static boolean mergePointsForSelectedObjectClasses(PathObjectHierarchy hierarchy) {
    var pathClasses = hierarchy.getSelectionModel().getSelectedObjects().stream().filter(p -> p.isAnnotation() && p.getROI().isPoint()).map(p -> p.getPathClass()).collect(Collectors.toSet());
    boolean changes = false;
    for (PathClass pathClass : pathClasses) changes = changes || mergePointsForClass(hierarchy, pathClass);
    return changes;
}
Also used : PathClassTools(qupath.lib.objects.classes.PathClassTools) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) PathClassFactory(qupath.lib.objects.classes.PathClassFactory) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) Function(java.util.function.Function) ArrayList(java.util.ArrayList) MeasurementList(qupath.lib.measurements.MeasurementList) EllipseROI(qupath.lib.roi.EllipseROI) HashSet(java.util.HashSet) ROIs(qupath.lib.roi.ROIs) PointsROI(qupath.lib.roi.PointsROI) Point2(qupath.lib.geom.Point2) ImageRegion(qupath.lib.regions.ImageRegion) Map(java.util.Map) PreparedGeometry(org.locationtech.jts.geom.prep.PreparedGeometry) LinkedHashSet(java.util.LinkedHashSet) LineROI(qupath.lib.roi.LineROI) Line2D(java.awt.geom.Line2D) RoiTools(qupath.lib.roi.RoiTools) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) Predicate(java.util.function.Predicate) Collection(java.util.Collection) PathClass(qupath.lib.objects.classes.PathClass) Set(java.util.Set) AffineTransform(java.awt.geom.AffineTransform) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) ROI(qupath.lib.roi.interfaces.ROI) List(java.util.List) Entry(java.util.Map.Entry) ImagePlane(qupath.lib.regions.ImagePlane) Geometry(org.locationtech.jts.geom.Geometry) Comparator(java.util.Comparator) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) Collections(java.util.Collections) PreparedGeometryFactory(org.locationtech.jts.geom.prep.PreparedGeometryFactory) STRtree(org.locationtech.jts.index.strtree.STRtree) PathClass(qupath.lib.objects.classes.PathClass)

Example 59 with ROI

use of qupath.lib.roi.interfaces.ROI in project qupath by qupath.

the class PathObjectTileCache method getGeometry.

Geometry getGeometry(PathObject pathObject) {
    ROI roi = pathObject.getROI();
    Geometry geometry = geometryMap.get(roi);
    if (geometry == null) {
        geometry = roi.getGeometry();
        if (pathObject.isAnnotation() || pathObject.isTMACore()) {
            geometryMap.put(roi, geometry);
        }
    // //			long startTime = System.currentTimeMillis();
    // if (!geometry.isValid()) {
    // int nVertices = geometry.getNumPoints();
    // if (geometry.getNumPoints() < 100)
    // logger.warn("{} is not a valid geometry! Actual geometry {}", pathObject, geometry);
    // else
    // logger.warn("{} is not a valid geometry! Actual geometry {} ({} vertices)", pathObject, geometry.getGeometryType(), nVertices);
    // }
    // //			long endTime = System.currentTimeMillis();
    // //			System.err.println("Testing " + (endTime - startTime) + " ms for " + geometry);
    }
    return geometry;
}
Also used : PreparedGeometry(org.locationtech.jts.geom.prep.PreparedGeometry) Geometry(org.locationtech.jts.geom.Geometry) ROI(qupath.lib.roi.interfaces.ROI)

Example 60 with ROI

use of qupath.lib.roi.interfaces.ROI in project qupath by qupath.

the class ParallelTileObject method getObjectsForRegion.

/**
 * Get all the objects whose bounding box intersects with a specified region
 * @param region
 * @return
 */
List<PathObject> getObjectsForRegion(Rectangle2D region) {
    List<PathObject> pathObjects = new ArrayList<>();
    for (PathObject child : getChildObjectsAsArray()) {
        ROI childROI = child.getROI();
        if (childROI != null && childROI.isArea() && region.intersects(getBounds2D(childROI))) {
            pathObjects.add(child);
        }
    }
    Collections.sort(pathObjects, DefaultPathObjectComparator.getInstance());
    return pathObjects;
}
Also used : PathObject(qupath.lib.objects.PathObject) ArrayList(java.util.ArrayList) ROI(qupath.lib.roi.interfaces.ROI)

Aggregations

ROI (qupath.lib.roi.interfaces.ROI)87 PathObject (qupath.lib.objects.PathObject)61 ArrayList (java.util.ArrayList)31 BufferedImage (java.awt.image.BufferedImage)24 PathObjectHierarchy (qupath.lib.objects.hierarchy.PathObjectHierarchy)24 IOException (java.io.IOException)20 RegionRequest (qupath.lib.regions.RegionRequest)19 List (java.util.List)17 Collectors (java.util.stream.Collectors)17 RectangleROI (qupath.lib.roi.RectangleROI)17 Logger (org.slf4j.Logger)16 LoggerFactory (org.slf4j.LoggerFactory)16 PolygonROI (qupath.lib.roi.PolygonROI)16 PathAnnotationObject (qupath.lib.objects.PathAnnotationObject)15 Point2D (java.awt.geom.Point2D)14 Collection (java.util.Collection)14 Collections (java.util.Collections)14 Geometry (org.locationtech.jts.geom.Geometry)14 PathClass (qupath.lib.objects.classes.PathClass)14 ImagePlane (qupath.lib.regions.ImagePlane)13