Search in sources :

Example 1 with PathObjects

use of qupath.lib.objects.PathObjects in project qupath by qupath.

the class PathIO method exportObjectsAsGeoJSON.

/**
 * Export a collection of objects as a GeoJSON "FeatureCollection" to an output stream.
 * @param stream
 * @param pathObjects
 * @param options
 * @throws IOException
 */
public static void exportObjectsAsGeoJSON(OutputStream stream, Collection<? extends PathObject> pathObjects, GeoJsonExportOptions... options) throws IOException {
    Collection<GeoJsonExportOptions> optionList = Arrays.asList(options);
    // If exclude measurements, 'transform' each PathObject to get rid of measurements
    if (optionList.contains(GeoJsonExportOptions.EXCLUDE_MEASUREMENTS))
        pathObjects = pathObjects.stream().map(e -> PathObjectTools.transformObject(e, null, false)).collect(Collectors.toList());
    var writer = new OutputStreamWriter(new BufferedOutputStream(stream), StandardCharsets.UTF_8);
    var gson = GsonTools.getInstance(optionList.contains(GeoJsonExportOptions.PRETTY_JSON));
    if (optionList.contains(GeoJsonExportOptions.FEATURE_COLLECTION))
        gson.toJson(GsonTools.wrapFeatureCollection(pathObjects), writer);
    else if (pathObjects.size() == 1) {
        gson.toJson(pathObjects.iterator().next(), writer);
    } else {
        gson.toJson(pathObjects, new TypeToken<List<PathObject>>() {
        }.getType(), writer);
    }
    writer.flush();
}
Also used : Arrays(java.util.Arrays) ImageServer(qupath.lib.images.servers.ImageServer) BufferedInputStream(java.io.BufferedInputStream) TypeToken(com.google.gson.reflect.TypeToken) FeatureCollection(qupath.lib.io.PathObjectTypeAdapters.FeatureCollection) ObjectInputStream(java.io.ObjectInputStream) LoggerFactory(org.slf4j.LoggerFactory) Category(java.util.Locale.Category) Locale(java.util.Locale) Gson(com.google.gson.Gson) Map(java.util.Map) URI(java.net.URI) Path(java.nio.file.Path) ZipEntry(java.util.zip.ZipEntry) ImageServerProvider(qupath.lib.images.servers.ImageServerProvider) Collection(java.util.Collection) PathObjects(qupath.lib.objects.PathObjects) Set(java.util.Set) EOFException(java.io.EOFException) Collectors(java.util.stream.Collectors) FileNotFoundException(java.io.FileNotFoundException) StandardCharsets(java.nio.charset.StandardCharsets) Serializable(java.io.Serializable) PathObject(qupath.lib.objects.PathObject) Objects(java.util.Objects) List(java.util.List) Entry(java.util.Map.Entry) ImagePlane(qupath.lib.regions.ImagePlane) Geometry(org.locationtech.jts.geom.Geometry) ZipOutputStream(java.util.zip.ZipOutputStream) HashMap(java.util.HashMap) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) DefaultImageServerBuilder(qupath.lib.images.servers.ImageServerBuilder.DefaultImageServerBuilder) BufferedOutputStream(java.io.BufferedOutputStream) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) JsonElement(com.google.gson.JsonElement) ColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains) OutputStreamWriter(java.io.OutputStreamWriter) ObjectOutputStream(java.io.ObjectOutputStream) GeometryTools(qupath.lib.roi.GeometryTools) LinkedHashSet(java.util.LinkedHashSet) OutputStream(java.io.OutputStream) ImageData(qupath.lib.images.ImageData) Logger(org.slf4j.Logger) Files(java.nio.file.Files) GeneralTools(qupath.lib.common.GeneralTools) Workflow(qupath.lib.plugins.workflow.Workflow) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) ServerBuilder(qupath.lib.images.servers.ImageServerBuilder.ServerBuilder) InputStreamReader(java.io.InputStreamReader) File(java.io.File) PathObjectTools(qupath.lib.objects.PathObjectTools) Collections(java.util.Collections) FileSystems(java.nio.file.FileSystems) InputStream(java.io.InputStream) OutputStreamWriter(java.io.OutputStreamWriter) List(java.util.List) ArrayList(java.util.ArrayList) BufferedOutputStream(java.io.BufferedOutputStream)

Example 2 with PathObjects

use of qupath.lib.objects.PathObjects 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;
}
Also used : FeatureExtractors(qupath.opencv.ml.objects.features.FeatureExtractors) Arrays(java.util.Arrays) ServerTools(qupath.lib.images.servers.ServerTools) PathTileObject(qupath.lib.objects.PathTileObject) IJTools(qupath.imagej.tools.IJTools) GroovyCV(qupath.opencv.tools.GroovyCV) CommandLinePluginRunner(qupath.lib.plugins.CommandLinePluginRunner) ImageRegion(qupath.lib.regions.ImageRegion) Map(java.util.Map) PixelClassifierTools(qupath.opencv.ml.pixel.PixelClassifierTools) Path(java.nio.file.Path) ColorTools(qupath.lib.common.ColorTools) Member(java.lang.reflect.Member) PathObjects(qupath.lib.objects.PathObjects) Set(java.util.Set) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) Project(qupath.lib.projects.Project) Stream(java.util.stream.Stream) ColorModels(qupath.lib.analysis.heatmaps.ColorModels) ShapeFeatures(qupath.lib.analysis.features.ObjectMeasurements.ShapeFeatures) DensityMaps(qupath.lib.analysis.heatmaps.DensityMaps) PathObjectPredicates(qupath.lib.objects.PathObjectPredicates) GeoJsonExportOptions(qupath.lib.io.PathIO.GeoJsonExportOptions) GsonTools(qupath.lib.io.GsonTools) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) Constructor(java.lang.reflect.Constructor) PathPlugin(qupath.lib.plugins.PathPlugin) Projects(qupath.lib.projects.Projects) ArrayList(java.util.ArrayList) ROIs(qupath.lib.roi.ROIs) ImageOps(qupath.opencv.ops.ImageOps) LinkedHashSet(java.util.LinkedHashSet) PathClassifierTools(qupath.lib.classifiers.PathClassifierTools) ObjectArrays(com.google.common.collect.ObjectArrays) Files(java.nio.file.Files) GeneralTools(qupath.lib.common.GeneralTools) RegionRequest(qupath.lib.regions.RegionRequest) TileExporter(qupath.lib.images.writers.TileExporter) DistanceTools(qupath.lib.analysis.DistanceTools) IOException(java.io.IOException) Padding(qupath.lib.regions.Padding) Field(java.lang.reflect.Field) DelaunayTools(qupath.lib.analysis.DelaunayTools) File(java.io.File) PathObjectTools(qupath.lib.objects.PathObjectTools) ROI(qupath.lib.roi.interfaces.ROI) PixelClassifier(qupath.lib.classifiers.pixel.PixelClassifier) Paths(java.nio.file.Paths) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) UriResource(qupath.lib.io.UriResource) ImageServerMetadata(qupath.lib.images.servers.ImageServerMetadata) PathIO(qupath.lib.io.PathIO) RunSavedClassifierWorkflowStep(qupath.lib.plugins.workflow.RunSavedClassifierWorkflowStep) CreateObjectOptions(qupath.opencv.ml.pixel.PixelClassifierTools.CreateObjectOptions) ImageServer(qupath.lib.images.servers.ImageServer) LoggerFactory(org.slf4j.LoggerFactory) Scanner(java.util.Scanner) PathObjectFilter(qupath.lib.objects.PathObjectFilter) OpenCVMLClassifier(qupath.opencv.ml.objects.OpenCVMLClassifier) BufferedImageTools(qupath.lib.awt.common.BufferedImageTools) URI(java.net.URI) ImageServers(qupath.lib.images.servers.ImageServers) Method(java.lang.reflect.Method) ImageType(qupath.lib.images.ImageData.ImageType) ObjectMeasurements(qupath.lib.analysis.features.ObjectMeasurements) BufferedImage(java.awt.image.BufferedImage) PixelClassifiers(qupath.opencv.ml.pixel.PixelClassifiers) Predicate(java.util.function.Predicate) ImageServerProvider(qupath.lib.images.servers.ImageServerProvider) Collection(java.util.Collection) DensityMapBuilder(qupath.lib.analysis.heatmaps.DensityMaps.DensityMapBuilder) UriUpdater(qupath.lib.io.UriUpdater) Collectors(java.util.stream.Collectors) FileNotFoundException(java.io.FileNotFoundException) PathObject(qupath.lib.objects.PathObject) PathDetectionObject(qupath.lib.objects.PathDetectionObject) List(java.util.List) ProjectIO(qupath.lib.projects.ProjectIO) ContourTracing(qupath.lib.analysis.images.ContourTracing) PathObjectClassifier(qupath.lib.classifiers.PathObjectClassifier) Modifier(java.lang.reflect.Modifier) DnnTools(qupath.opencv.dnn.DnnTools) ImagePlane(qupath.lib.regions.ImagePlane) Geometry(org.locationtech.jts.geom.Geometry) Pattern(java.util.regex.Pattern) PathCellObject(qupath.lib.objects.PathCellObject) PathClassTools(qupath.lib.objects.classes.PathClassTools) ImageChannel(qupath.lib.images.servers.ImageChannel) OpenCVTools(qupath.opencv.tools.OpenCVTools) HashMap(java.util.HashMap) PathClassFactory(qupath.lib.objects.classes.PathClassFactory) ColorTransforms(qupath.lib.images.servers.ColorTransforms) CellTools(qupath.lib.objects.CellTools) HashSet(java.util.HashSet) ColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains) ObjectClassifiers(qupath.lib.classifiers.object.ObjectClassifiers) GeometryTools(qupath.lib.roi.GeometryTools) NoSuchElementException(java.util.NoSuchElementException) WeakHashMap(java.util.WeakHashMap) ImageData(qupath.lib.images.ImageData) RoiTools(qupath.lib.roi.RoiTools) Logger(org.slf4j.Logger) ProjectImageEntry(qupath.lib.projects.ProjectImageEntry) ImageWriterTools(qupath.lib.images.writers.ImageWriterTools) PixelType(qupath.lib.images.servers.PixelType) PathClass(qupath.lib.objects.classes.PathClass) PointIO(qupath.lib.io.PointIO) TMACoreObject(qupath.lib.objects.TMACoreObject) ObjectClassifier(qupath.lib.classifiers.object.ObjectClassifier) Comparator(java.util.Comparator) Collections(java.util.Collections) Geometry(org.locationtech.jts.geom.Geometry) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PathObject(qupath.lib.objects.PathObject) ArrayList(java.util.ArrayList) ImagePlane(qupath.lib.regions.ImagePlane) ROI(qupath.lib.roi.interfaces.ROI)

Example 3 with PathObjects

use of qupath.lib.objects.PathObjects in project qupath by qupath.

the class PixelClassifierTools method createObjectsFromPixelClassifier.

/**
 * Create objects based upon an {@link ImageServer} that provides classification or probability output.
 *
 * @param server image server providing pixels from which objects should be created
 * @param labels classification labels; if null, these will be taken from ImageServer#getMetadata() and all non-ignored classifications will be used.
 * 		   Providing a map makes it possible to explicitly exclude some classifications.
 * @param roi region of interest in which objects should be created (optional; if null, the entire image is used)
 * @param creator function to create an object from a ROI (e.g. annotation or detection)
 * @param minArea minimum area for an object fragment to retain, in calibrated units based on the pixel calibration
 * @param minHoleArea minimum area for a hole to fill, in calibrated units based on the pixel calibration
 * @param doSplit if true, split connected regions into separate objects
 * @return the objects created within the ROI
 * @throws IOException
 */
public static Collection<PathObject> createObjectsFromPixelClassifier(ImageServer<BufferedImage> server, Map<Integer, PathClass> labels, ROI roi, Function<ROI, ? extends PathObject> creator, double minArea, double minHoleArea, boolean doSplit) throws IOException {
    // We need classification labels to do anything
    if (labels == null)
        labels = parseClassificationLabels(server.getMetadata().getClassificationLabels(), false);
    if (labels == null || labels.isEmpty())
        throw new IllegalArgumentException("Cannot create objects for server - no classification labels are available!");
    ChannelThreshold[] thresholds = labels.entrySet().stream().map(e -> ChannelThreshold.create(e.getKey())).toArray(ChannelThreshold[]::new);
    if (roi != null && !roi.isArea()) {
        logger.warn("Cannot create objects for non-area ROIs");
        return Collections.emptyList();
    }
    Geometry clipArea = roi == null ? null : roi.getGeometry();
    // Identify regions for selected ROI or entire image
    // This is a list because it might need to handle multiple z-slices or timepoints
    List<RegionRequest> regionRequests;
    if (roi != null) {
        var request = RegionRequest.createInstance(server.getPath(), server.getDownsampleForResolution(0), roi);
        regionRequests = Collections.singletonList(request);
    } else {
        regionRequests = RegionRequest.createAllRequests(server, server.getDownsampleForResolution(0));
    }
    double pixelArea = server.getPixelCalibration().getPixelWidth().doubleValue() * server.getPixelCalibration().getPixelHeight().doubleValue();
    double minAreaPixels = minArea / pixelArea;
    double minHoleAreaPixels = minHoleArea / pixelArea;
    // Create output array
    var pathObjects = new ArrayList<PathObject>();
    // Loop through region requests (usually 1, unless we have a z-stack or time series)
    for (RegionRequest regionRequest : regionRequests) {
        Map<Integer, Geometry> geometryMap = ContourTracing.traceGeometries(server, regionRequest, clipArea, thresholds);
        var labelMap = labels;
        pathObjects.addAll(geometryMap.entrySet().parallelStream().flatMap(e -> geometryToObjects(e.getValue(), creator, labelMap.get(e.getKey()), minAreaPixels, minHoleAreaPixels, doSplit, regionRequest.getPlane()).stream()).collect(Collectors.toList()));
    }
    pathObjects.sort(DefaultPathObjectComparator.getInstance());
    return pathObjects;
}
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) Geometry(org.locationtech.jts.geom.Geometry) ArrayList(java.util.ArrayList) ChannelThreshold(qupath.lib.analysis.images.ContourTracing.ChannelThreshold) RegionRequest(qupath.lib.regions.RegionRequest)

Example 4 with PathObjects

use of qupath.lib.objects.PathObjects 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 5 with PathObjects

use of qupath.lib.objects.PathObjects in project qupath by qupath.

the class Commands method combineAnnotations.

/**
 * Combine all the annotations that overlap with a selected object.
 * <p>
 * The selected object should itself be an annotation.
 *
 * @param hierarchy
 * @param pathObjects
 * @param op
 * @return true if any changes were made, false otherwise
 */
static boolean combineAnnotations(PathObjectHierarchy hierarchy, List<PathObject> pathObjects, RoiTools.CombineOp op) {
    if (hierarchy == null || hierarchy.isEmpty() || pathObjects.isEmpty()) {
        logger.warn("Combine annotations: Cannot combine - no annotations found");
        return false;
    }
    pathObjects = new ArrayList<>(pathObjects);
    PathObject pathObject = pathObjects.get(0);
    if (!pathObject.isAnnotation()) {
        // || !RoiTools.isShapeROI(pathObject.getROI())) {
        logger.warn("Combine annotations: No annotation with ROI selected");
        return false;
    }
    var plane = pathObject.getROI().getImagePlane();
    // pathObjects.removeIf(p -> !RoiTools.isShapeROI(p.getROI())); // Remove any null or point ROIs, TODO: Consider supporting points
    // Remove any null or point ROIs, TODO: Consider supporting points
    pathObjects.removeIf(p -> !p.hasROI() || !p.getROI().getImagePlane().equals(plane));
    if (pathObjects.isEmpty()) {
        logger.warn("Cannot combine annotations - only one suitable annotation found");
        return false;
    }
    var allROIs = pathObjects.stream().map(p -> p.getROI()).collect(Collectors.toCollection(() -> new ArrayList<>()));
    ROI newROI;
    switch(op) {
        case ADD:
            newROI = RoiTools.union(allROIs);
            break;
        case INTERSECT:
            newROI = RoiTools.intersection(allROIs);
            break;
        case SUBTRACT:
            var first = allROIs.remove(0);
            newROI = RoiTools.combineROIs(first, RoiTools.union(allROIs), op);
            break;
        default:
            throw new IllegalArgumentException("Unknown combine op " + op);
    }
    if (newROI == null) {
        logger.debug("No changes were made");
        return false;
    }
    PathObject newObject = null;
    if (!newROI.isEmpty()) {
        newObject = PathObjects.createAnnotationObject(newROI, pathObject.getPathClass());
        newObject.setName(pathObject.getName());
        newObject.setColorRGB(pathObject.getColorRGB());
    }
    // Remove previous objects
    hierarchy.removeObjects(pathObjects, true);
    if (newObject != null)
        hierarchy.addPathObject(newObject);
    return true;
}
Also used : Arrays(java.util.Arrays) ServerTools(qupath.lib.images.servers.ServerTools) PathTileObject(qupath.lib.objects.PathTileObject) StackPane(javafx.scene.layout.StackPane) ImageWriter(qupath.lib.images.writers.ImageWriter) ParameterList(qupath.lib.plugins.parameters.ParameterList) ImageRegion(qupath.lib.regions.ImageRegion) Map(java.util.Map) PathObjects(qupath.lib.objects.PathObjects) Screen(javafx.stage.Screen) WorkflowStep(qupath.lib.plugins.workflow.WorkflowStep) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) Project(qupath.lib.projects.Project) ShapeFeatures(qupath.lib.analysis.features.ObjectMeasurements.ShapeFeatures) MeasurementMapPane(qupath.lib.gui.panes.MeasurementMapPane) BorderPane(javafx.scene.layout.BorderPane) StringProperty(javafx.beans.property.StringProperty) RectangleROI(qupath.lib.roi.RectangleROI) CheckBoxListCell(javafx.scene.control.cell.CheckBoxListCell) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) Supplier(java.util.function.Supplier) Bindings(javafx.beans.binding.Bindings) ViewTrackerControlPane(qupath.lib.gui.viewer.recording.ViewTrackerControlPane) Projects(qupath.lib.projects.Projects) ArrayList(java.util.ArrayList) CheckListView(org.controlsfx.control.CheckListView) ROIs(qupath.lib.roi.ROIs) ShapeSimplifier(qupath.lib.roi.ShapeSimplifier) TextAlignment(javafx.scene.text.TextAlignment) PathClassPane(qupath.lib.gui.panes.PathClassPane) GridPane(javafx.scene.layout.GridPane) Files(java.nio.file.Files) GeneralTools(qupath.lib.common.GeneralTools) RegionRequest(qupath.lib.regions.RegionRequest) Window(java.awt.Window) DistanceTools(qupath.lib.analysis.DistanceTools) IOException(java.io.IOException) File(java.io.File) OverlayOptions(qupath.lib.gui.viewer.OverlayOptions) PathObjectTools(qupath.lib.objects.PathObjectTools) ROI(qupath.lib.roi.interfaces.ROI) QP(qupath.lib.scripting.QP) GridLines(qupath.lib.gui.viewer.GridLines) PathPrefs(qupath.lib.gui.prefs.PathPrefs) RenderedImageServer(qupath.lib.gui.images.servers.RenderedImageServer) PaneTools(qupath.lib.gui.tools.PaneTools) PathIO(qupath.lib.io.PathIO) Button(javafx.scene.control.Button) Pos(javafx.geometry.Pos) ImageServer(qupath.lib.images.servers.ImageServer) CombineOp(qupath.lib.roi.RoiTools.CombineOp) LoggerFactory(org.slf4j.LoggerFactory) ObservableDoubleValue(javafx.beans.value.ObservableDoubleValue) ComboBox(javafx.scene.control.ComboBox) ImageServers(qupath.lib.images.servers.ImageServers) PolygonROI(qupath.lib.roi.PolygonROI) QuPathGUI(qupath.lib.gui.QuPathGUI) Pane(javafx.scene.layout.Pane) TextField(javafx.scene.control.TextField) BufferedImage(java.awt.image.BufferedImage) Collection(java.util.Collection) Collectors(java.util.stream.Collectors) PathDetectionObject(qupath.lib.objects.PathDetectionObject) PathObject(qupath.lib.objects.PathObject) QuPathViewer(qupath.lib.gui.viewer.QuPathViewer) Priority(javafx.scene.layout.Priority) List(java.util.List) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) ProjectIO(qupath.lib.projects.ProjectIO) GuiTools(qupath.lib.gui.tools.GuiTools) TMASummaryViewer(qupath.lib.gui.tma.TMASummaryViewer) ImagePlane(qupath.lib.regions.ImagePlane) PathCellObject(qupath.lib.objects.PathCellObject) Scene(javafx.scene.Scene) WorkflowCommandLogView(qupath.lib.gui.panes.WorkflowCommandLogView) TextArea(javafx.scene.control.TextArea) ButtonType(javafx.scene.control.ButtonType) Action(org.controlsfx.control.action.Action) HashMap(java.util.HashMap) DoubleProperty(javafx.beans.property.DoubleProperty) Function(java.util.function.Function) Dialogs(qupath.lib.gui.dialogs.Dialogs) Insets(javafx.geometry.Insets) ActionTools(qupath.lib.gui.ActionTools) Tooltip(javafx.scene.control.Tooltip) WeakHashMap(java.util.WeakHashMap) ImageData(qupath.lib.images.ImageData) RoiTools(qupath.lib.roi.RoiTools) Modality(javafx.stage.Modality) Logger(org.slf4j.Logger) Label(javafx.scene.control.Label) Iterator(java.util.Iterator) ImageWriterTools(qupath.lib.images.writers.ImageWriterTools) TMACoreObject(qupath.lib.objects.TMACoreObject) Stage(javafx.stage.Stage) Collections(java.util.Collections) ContentDisplay(javafx.scene.control.ContentDisplay) DialogButton(qupath.lib.gui.dialogs.Dialogs.DialogButton) PathObject(qupath.lib.objects.PathObject) ArrayList(java.util.ArrayList) RectangleROI(qupath.lib.roi.RectangleROI) ROI(qupath.lib.roi.interfaces.ROI) PolygonROI(qupath.lib.roi.PolygonROI)

Aggregations

IOException (java.io.IOException)7 ArrayList (java.util.ArrayList)7 Arrays (java.util.Arrays)7 List (java.util.List)7 Map (java.util.Map)7 PathObject (qupath.lib.objects.PathObject)7 PathObjects (qupath.lib.objects.PathObjects)7 ImagePlane (qupath.lib.regions.ImagePlane)7 Collection (java.util.Collection)6 Collections (java.util.Collections)6 Collectors (java.util.stream.Collectors)6 Logger (org.slf4j.Logger)6 LoggerFactory (org.slf4j.LoggerFactory)6 ImageData (qupath.lib.images.ImageData)6 ImageServer (qupath.lib.images.servers.ImageServer)6 PathObjectTools (qupath.lib.objects.PathObjectTools)6 PathObjectHierarchy (qupath.lib.objects.hierarchy.PathObjectHierarchy)6 BufferedImage (java.awt.image.BufferedImage)5 File (java.io.File)5 HashMap (java.util.HashMap)5