Search in sources :

Example 1 with PolygonROI

use of qupath.lib.roi.PolygonROI in project qupath by qupath.

the class IJTools method convertToIJRoi.

/**
 * Convert a QuPath ROI to an ImageJ Roi.
 * @param <T>
 * @param pathROI
 * @param xOrigin x-origin indicating relationship of ImagePlus to the original image, as stored in ImageJ Calibration object
 * @param yOrigin y-origin indicating relationship of ImagePlus to the original image, as stored in ImageJ Calibration object
 * @param downsampleFactor downsample factor at which the ImagePlus was extracted from the full-resolution image
 * @return
 */
public static <T extends PathImage<ImagePlus>> Roi convertToIJRoi(ROI pathROI, double xOrigin, double yOrigin, double downsampleFactor) {
    if (pathROI instanceof PolygonROI)
        return ROIConverterIJ.convertToPolygonROI((PolygonROI) pathROI, xOrigin, yOrigin, downsampleFactor);
    if (pathROI instanceof RectangleROI)
        return ROIConverterIJ.getRectangleROI((RectangleROI) pathROI, xOrigin, yOrigin, downsampleFactor);
    if (pathROI instanceof EllipseROI)
        return ROIConverterIJ.convertToOvalROI((EllipseROI) pathROI, xOrigin, yOrigin, downsampleFactor);
    if (pathROI instanceof LineROI)
        return ROIConverterIJ.convertToLineROI((LineROI) pathROI, xOrigin, yOrigin, downsampleFactor);
    if (pathROI instanceof PolylineROI)
        return ROIConverterIJ.convertToPolygonROI((PolylineROI) pathROI, xOrigin, yOrigin, downsampleFactor);
    if (pathROI instanceof PointsROI)
        return ROIConverterIJ.convertToPointROI((PointsROI) pathROI, xOrigin, yOrigin, downsampleFactor);
    // If we have any other kind of shape, create a general shape roi
    if (pathROI != null && pathROI.isArea()) {
        // TODO: Deal with non-AWT area ROIs!
        Shape shape = RoiTools.getArea(pathROI);
        // "scaleX", "shearY", "shearX", "scaleY", "translateX", "translateY"
        shape = new AffineTransform(1.0 / downsampleFactor, 0, 0, 1.0 / downsampleFactor, xOrigin, yOrigin).createTransformedShape(shape);
        return ROIConverterIJ.setIJRoiProperties(new ShapeRoi(shape), pathROI);
    }
    // TODO: Integrate ROI not supported exception...?
    return null;
}
Also used : PolygonROI(qupath.lib.roi.PolygonROI) ShapeRoi(ij.gui.ShapeRoi) RectangleROI(qupath.lib.roi.RectangleROI) Shape(java.awt.Shape) EllipseROI(qupath.lib.roi.EllipseROI) PolylineROI(qupath.lib.roi.PolylineROI) PointsROI(qupath.lib.roi.PointsROI) AffineTransform(java.awt.geom.AffineTransform) LineROI(qupath.lib.roi.LineROI)

Example 2 with PolygonROI

use of qupath.lib.roi.PolygonROI in project qupath by qupath.

the class ObservableMeasurementTableData method updateMeasurementList.

/**
 * Update the entire measurement list for the current objects.
 * @see #setImageData(ImageData, Collection)
 */
public synchronized void updateMeasurementList() {
    // PathPrefs.setAllredMinPercentagePositive(0);
    builderMap.clear();
    // Add the image name
    if (!PathPrefs.maskImageNamesProperty().get())
        builderMap.put("Image", new ImageNameMeasurementBuilder(imageData));
    // Check if we have any annotations / TMA cores
    boolean containsDetections = false;
    boolean containsAnnotations = false;
    // boolean containsParentAnnotations = false;
    boolean containsTMACores = false;
    boolean containsRoot = false;
    List<PathObject> pathObjectListCopy = new ArrayList<>(list);
    for (PathObject temp : pathObjectListCopy) {
        if (temp instanceof PathAnnotationObject) {
            // if (temp.hasChildren())
            // containsParentAnnotations = true;
            containsAnnotations = true;
        } else if (temp instanceof TMACoreObject) {
            containsTMACores = true;
        } else if (temp instanceof PathDetectionObject) {
            containsDetections = true;
        } else if (temp.isRootObject())
            containsRoot = true;
    }
    boolean detectionsAnywhere = imageData == null ? containsDetections : !imageData.getHierarchy().getDetectionObjects().isEmpty();
    // Include the object displayed name
    // if (containsDetections || containsAnnotations || containsTMACores)
    builderMap.put("Name", new ObjectNameMeasurementBuilder());
    // Include the class
    if (containsAnnotations || containsDetections) {
        builderMap.put("Class", new PathClassMeasurementBuilder());
        // Get the name of the containing TMA core if we have anything other than cores
        if (imageData != null && imageData.getHierarchy().getTMAGrid() != null) {
            builderMap.put("TMA core", new TMACoreNameMeasurementBuilder());
        }
        // Get the name of the first parent object
        builderMap.put("Parent", new ParentNameMeasurementBuilder());
    }
    // Include the TMA missing status, if appropriate
    if (containsTMACores) {
        builderMap.put("Missing", new MissingTMACoreMeasurementBuilder());
    }
    if (containsAnnotations || containsDetections) {
        builderMap.put("ROI", new ROINameMeasurementBuilder());
    }
    // Add centroids
    if (containsAnnotations || containsDetections || containsTMACores) {
        // ROICentroidMeasurementBuilder builder = new ROICentroidMeasurementBuilder(imageData, CentroidType.X);
        // builderMap.put("Centroid X", builder);
        // builder = new ROICentroidMeasurementBuilder(imageData, CentroidType.Y);
        // builderMap.put("Centroid Y", builder);
        ROICentroidMeasurementBuilder builder = new ROICentroidMeasurementBuilder(imageData, CentroidType.X);
        builderMap.put(builder.getName(), builder);
        builder = new ROICentroidMeasurementBuilder(imageData, CentroidType.Y);
        builderMap.put(builder.getName(), builder);
    }
    // If we have metadata, store it
    Set<String> metadataNames = new LinkedHashSet<>();
    metadataNames.addAll(builderMap.keySet());
    for (PathObject pathObject : pathObjectListCopy) {
        if (pathObject instanceof MetadataStore) {
            metadataNames.addAll(((MetadataStore) pathObject).getMetadataKeys());
        }
    }
    // Ensure we have suitable builders
    for (String name : metadataNames) {
        if (!builderMap.containsKey(name))
            builderMap.put(name, new StringMetadataMeasurementBuilder(name));
    }
    // Get all the 'built-in' feature measurements, stored in the measurement list
    Collection<String> features = PathClassifierTools.getAvailableFeatures(pathObjectListCopy);
    // Add derived measurements if we don't have only detections
    if (containsAnnotations || containsTMACores || containsRoot) {
        if (detectionsAnywhere) {
            var builder = new ObjectTypeCountMeasurementBuilder(PathDetectionObject.class);
            builderMap.put(builder.getName(), builder);
            features.add(builder.getName());
        }
        // Here, we allow TMA cores to act like annotations
        manager = new DerivedMeasurementManager(getImageData(), containsAnnotations || containsTMACores);
        for (MeasurementBuilder<?> builder2 : manager.getMeasurementBuilders()) {
            builderMap.put(builder2.getName(), builder2);
            features.add(builder2.getName());
        }
    }
    // If we have an annotation, add shape features
    if (containsAnnotations) {
        boolean anyPoints = false;
        boolean anyAreas = false;
        boolean anyLines = false;
        @SuppressWarnings("unused") boolean anyPolygons = false;
        for (PathObject pathObject : pathObjectListCopy) {
            if (!pathObject.isAnnotation())
                continue;
            ROI roi = pathObject.getROI();
            if (roi == null)
                continue;
            if (roi.isPoint())
                anyPoints = true;
            if (roi.isArea())
                anyAreas = true;
            if (roi.isLine())
                anyLines = true;
            if (pathObject.getROI() instanceof PolygonROI)
                anyPolygons = true;
        }
        // Add point count, if needed
        if (anyPoints) {
            MeasurementBuilder<?> builder = new NumPointsMeasurementBuilder();
            builderMap.put(builder.getName(), builder);
            features.add(builder.getName());
        }
        // Add spatial measurements, if needed
        if (anyAreas) {
            MeasurementBuilder<?> builder = new AreaMeasurementBuilder(imageData);
            builderMap.put(builder.getName(), builder);
            features.add(builder.getName());
            builder = new PerimeterMeasurementBuilder(imageData);
            builderMap.put(builder.getName(), builder);
            features.add(builder.getName());
        }
        if (anyLines) {
            MeasurementBuilder<?> builder = new LineLengthMeasurementBuilder(imageData);
            builderMap.put(builder.getName(), builder);
            features.add(builder.getName());
        }
    // if (anyPolygons) {
    // MeasurementBuilder<?> builder = new MaxDiameterMeasurementBuilder(imageData);
    // builderMap.put(builder.getName(), builder);
    // features.add(builder.getName());
    // 
    // builder = new MinDiameterMeasurementBuilder(imageData);
    // builderMap.put(builder.getName(), builder);
    // features.add(builder.getName());
    // }
    }
    if (containsAnnotations || containsTMACores || containsRoot) {
        var pixelClassifier = getPixelLayer(imageData);
        if (pixelClassifier instanceof ImageServer<?>) {
            ImageServer<BufferedImage> server = (ImageServer<BufferedImage>) pixelClassifier;
            if (server.getMetadata().getChannelType() == ImageServerMetadata.ChannelType.CLASSIFICATION || server.getMetadata().getChannelType() == ImageServerMetadata.ChannelType.PROBABILITY) {
                var pixelManager = new PixelClassificationMeasurementManager(server);
                for (String name : pixelManager.getMeasurementNames()) {
                    // String nameLive = name + " (live)";
                    String nameLive = "(Live) " + name;
                    builderMap.put(nameLive, new PixelClassifierMeasurementBuilder(pixelManager, name));
                    features.add(nameLive);
                }
            }
        }
    }
    // Update all the lists, if necessary
    boolean changes = false;
    if (metadataNames.size() != metadataList.size() || !metadataNames.containsAll(metadataList)) {
        changes = metadataList.setAll(metadataNames);
    }
    if (features.size() != measurementList.size() || !features.containsAll(measurementList))
        changes = measurementList.setAll(features);
    if (changes) {
        if (metadataList.isEmpty())
            fullList.setAll(measurementList);
        else {
            fullList.setAll(metadataList);
            fullList.addAll(measurementList);
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ArrayList(java.util.ArrayList) BufferedImage(java.awt.image.BufferedImage) PolygonROI(qupath.lib.roi.PolygonROI) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) ImageServer(qupath.lib.images.servers.ImageServer) PathDetectionObject(qupath.lib.objects.PathDetectionObject) TMACoreObject(qupath.lib.objects.TMACoreObject) PolygonROI(qupath.lib.roi.PolygonROI) ROI(qupath.lib.roi.interfaces.ROI) MetadataStore(qupath.lib.objects.MetadataStore) PathObject(qupath.lib.objects.PathObject) PixelClassificationMeasurementManager(qupath.opencv.ml.pixel.PixelClassificationMeasurementManager)

Example 3 with PolygonROI

use of qupath.lib.roi.PolygonROI in project qupath by qupath.

the class AbstractPathROITool method mousePressed.

@Override
public void mousePressed(MouseEvent e) {
    super.mousePressed(e);
    if (!e.isPrimaryButtonDown() || e.isConsumed()) {
        return;
    }
    var viewer = getViewer();
    PathObjectHierarchy hierarchy = viewer.getHierarchy();
    if (hierarchy == null)
        return;
    PathObject currentObject = viewer.getSelectedObject();
    ROI currentROI = currentObject == null ? null : currentObject.getROI();
    RoiEditor editor = viewer.getROIEditor();
    boolean adjustingPolygon = (currentROI instanceof PolygonROI || currentROI instanceof PolylineROI) && editor.getROI() == currentROI && (editor.isTranslating() || editor.hasActiveHandle());
    // If we're adjusting a polygon/polyline with an appropriate tool, return at leave it up to the tool to handle the custom things
    if (adjustingPolygon) {
        if (viewer.getActiveTool() == PathTools.POLYGON || viewer.getActiveTool() == PathTools.POLYLINE)
            return;
        else {
            viewer.getHierarchy().getSelectionModel().clearSelection();
            viewer.getHierarchy().fireHierarchyChangedEvent(currentObject);
        }
    }
    // Find out the coordinates in the image domain
    Point2D p2 = mouseLocationToImage(e, false, requestPixelSnapping());
    double xx = p2.getX();
    double yy = p2.getY();
    if (xx < 0 || yy < 0 || xx >= viewer.getServerWidth() || yy >= viewer.getServerHeight())
        return;
    // If we are double-clicking & we don't have a polygon, see if we can access a ROI
    if (!PathPrefs.selectionModeProperty().get() && e.getClickCount() > 1) {
        // Reset parent... for now
        resetConstrainedAreaParent();
        tryToSelect(xx, yy, e.getClickCount() - 2, false);
        e.consume();
        return;
    }
    // Set the current parent object based on the first click
    setConstrainedAreaParent(hierarchy, xx, yy, Collections.emptyList());
    // Create a new annotation
    PathObject pathObject = createNewAnnotation(e, xx, yy);
    if (pathObject == null)
        return;
    // Start editing the ROI immediately
    editor.setROI(pathObject.getROI());
    editor.grabHandle(xx, yy, viewer.getMaxROIHandleSize() * 1.5, e.isShiftDown());
}
Also used : PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PolygonROI(qupath.lib.roi.PolygonROI) PathObject(qupath.lib.objects.PathObject) RoiEditor(qupath.lib.roi.RoiEditor) PolylineROI(qupath.lib.roi.PolylineROI) Point2D(java.awt.geom.Point2D) PolylineROI(qupath.lib.roi.PolylineROI) ROI(qupath.lib.roi.interfaces.ROI) PolygonROI(qupath.lib.roi.PolygonROI)

Example 4 with PolygonROI

use of qupath.lib.roi.PolygonROI in project qupath by qupath.

the class SimpleTissueDetection2 method convertToPathObjects.

private static List<PathObject> convertToPathObjects(ByteProcessor bp, double minArea, boolean smoothCoordinates, Calibration cal, double downsample, double maxHoleArea, boolean excludeOnBoundary, boolean singleAnnotation, ImagePlane plane, List<PathObject> pathObjects) {
    // 
    // var roiIJ = new ThresholdToSelection().convert(bp);
    // var roi = IJTools.convertToROI(roiIJ, cal, downsample, plane);
    // roi = RoiTools.removeSmallPieces(roi, minArea, maxHoleArea);
    // List<PathObject> annotations = new ArrayList<>();
    // if (singleAnnotation)
    // annotations.add(PathObjects.createAnnotationObject(roi));
    // else {
    // for (var roi2 : RoiTools.splitROI(roi)) {
    // annotations.add(PathObjects.createAnnotationObject(roi2));
    // }
    // }
    // for (var annotation : annotations)
    // annotation.setLocked(true);
    // return annotations;
    // 
    List<PolygonRoi> rois = RoiLabeling.getFilledPolygonROIs(bp, Wand.FOUR_CONNECTED);
    if (pathObjects == null)
        pathObjects = new ArrayList<>(rois.size());
    // We might need a copy of the original image
    boolean fillAllHoles = maxHoleArea <= 0;
    ByteProcessor bpOrig = !fillAllHoles ? (ByteProcessor) bp.duplicate() : null;
    bp.setValue(255);
    for (PolygonRoi r : rois) {
        // Check for boundary overlap
        if (excludeOnBoundary) {
            Rectangle bounds = r.getBounds();
            if (bounds.x <= 0 || bounds.y <= 0 || bounds.x + bounds.width >= bp.getWidth() - 1 || bounds.y + bounds.height >= bp.getHeight() - 1)
                continue;
        }
        bp.setRoi(r);
        if (bp.getStatistics().area < minArea)
            continue;
        // Fill holes as we go - it might matter later
        bp.fill(r);
        // if (smoothCoordinates) {
        // //				r = new PolygonRoi(r.getInterpolatedPolygon(2.5, false), Roi.POLYGON);
        // r = new PolygonRoi(r.getInterpolatedPolygon(Math.min(2.5, r.getNCoordinates()*0.1), false), Roi.POLYGON); // TODO: Check this smoothing - it can be troublesome, causing nuclei to be outside cells
        // }
        PolygonROI pathPolygon = IJTools.convertToPolygonROI(r, cal, downsample, plane);
        // Smooth the coordinates, if we downsampled quite a lot
        if (smoothCoordinates) {
            pathPolygon = ROIs.createPolygonROI(ShapeSimplifier.smoothPoints(pathPolygon.getAllPoints()), ImagePlane.getPlaneWithChannel(pathPolygon));
            pathPolygon = ShapeSimplifier.simplifyPolygon(pathPolygon, downsample / 2);
        }
        pathObjects.add(PathObjects.createAnnotationObject(pathPolygon));
    }
    if (Thread.currentThread().isInterrupted())
        return null;
    // TODO: Optimise this - the many 'containsObject' calls are a (potentially easy-to-fix) bottleneck
    if (!fillAllHoles) {
        // Get the holes alone
        bp.copyBits(bpOrig, 0, 0, Blitter.DIFFERENCE);
        // new ImagePlus("Binary", bp).show();
        bp.setThreshold(127, Double.POSITIVE_INFINITY, ImageProcessor.NO_LUT_UPDATE);
        List<PathObject> holes = convertToPathObjects(bp, maxHoleArea, smoothCoordinates, cal, downsample, 0, false, false, plane, null);
        // For each object, fill in any associated holes
        List<Area> areaList = new ArrayList<>();
        for (int ind = 0; ind < pathObjects.size(); ind++) {
            if (holes.isEmpty())
                break;
            PathObject pathObject = pathObjects.get(ind);
            var geom = PreparedGeometryFactory.prepare(pathObject.getROI().getGeometry());
            areaList.clear();
            Iterator<PathObject> iter = holes.iterator();
            while (iter.hasNext()) {
                PathObject hole = iter.next();
                if (geom.covers(hole.getROI().getGeometry())) {
                    areaList.add(RoiTools.getArea(hole.getROI()));
                    iter.remove();
                }
            }
            if (areaList.isEmpty())
                continue;
            // If we have some areas, combine them
            // TODO: FIX MAJOR BOTTLENECK HERE!!!
            Area hole = areaList.get(0);
            for (int i = 1; i < areaList.size(); i++) {
                hole.add(areaList.get(i));
                if (i % 100 == 0) {
                    logger.debug("Added hole " + i + "/" + areaList.size());
                    if (Thread.currentThread().isInterrupted())
                        return null;
                }
            }
            // Now subtract & create a new object
            ROI pathROI = pathObject.getROI();
            if (RoiTools.isShapeROI(pathROI)) {
                Area areaMain = RoiTools.getArea(pathROI);
                areaMain.subtract(hole);
                pathROI = RoiTools.getShapeROI(areaMain, pathROI.getImagePlane());
                pathObjects.set(ind, PathObjects.createAnnotationObject(pathROI));
            }
        }
    }
    // This is a clumsy way to do it...
    if (singleAnnotation) {
        ROI roi = null;
        for (PathObject annotation : pathObjects) {
            ROI currentShape = annotation.getROI();
            if (roi == null)
                roi = currentShape;
            else
                roi = RoiTools.combineROIs(roi, currentShape, CombineOp.ADD);
        }
        pathObjects.clear();
        if (roi != null)
            pathObjects.add(PathObjects.createAnnotationObject(roi));
    }
    // Lock the objects
    for (PathObject pathObject : pathObjects) ((PathAnnotationObject) pathObject).setLocked(true);
    return pathObjects;
}
Also used : ByteProcessor(ij.process.ByteProcessor) ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) PolygonROI(qupath.lib.roi.PolygonROI) ROI(qupath.lib.roi.interfaces.ROI) PolygonRoi(ij.gui.PolygonRoi) PolygonROI(qupath.lib.roi.PolygonROI) Area(java.awt.geom.Area) PathObject(qupath.lib.objects.PathObject)

Example 5 with PolygonROI

use of qupath.lib.roi.PolygonROI in project qupath by qupath.

the class Commands method promptToSimplifySelectedAnnotations.

/**
 * Show a prompt to selected annotations in a hierarchy.
 * @param imageData the current image data
 * @param altitudeThreshold default altitude value for simplification
 */
public static void promptToSimplifySelectedAnnotations(ImageData<?> imageData, double altitudeThreshold) {
    PathObjectHierarchy hierarchy = imageData.getHierarchy();
    List<PathObject> pathObjects = hierarchy.getSelectionModel().getSelectedObjects().stream().filter(p -> p.isAnnotation() && p.hasROI() && p.isEditable() && !p.getROI().isPoint()).collect(Collectors.toList());
    if (pathObjects.isEmpty()) {
        Dialogs.showErrorMessage("Simplify annotations", "No unlocked shape annotations selected!");
        return;
    }
    String input = Dialogs.showInputDialog("Simplify shape", "Set altitude threshold in pixels.\nHigher values give simpler shapes.", Double.toString(altitudeThreshold));
    if (input == null || !(input instanceof String) || ((String) input).trim().length() == 0)
        return;
    try {
        altitudeThreshold = Double.parseDouble(((String) input).trim());
    } catch (NumberFormatException e) {
        logger.error("Could not parse altitude threshold from {}", input);
        return;
    }
    if (altitudeThreshold <= 0) {
        Dialogs.showErrorMessage("Simplify shape", "Amplitude threshold should be greater than zero!");
        return;
    }
    long startTime = System.currentTimeMillis();
    for (var pathObject : pathObjects) {
        ROI pathROI = pathObject.getROI();
        if (pathROI instanceof PolygonROI) {
            PolygonROI polygonROI = (PolygonROI) pathROI;
            pathROI = ShapeSimplifier.simplifyPolygon(polygonROI, altitudeThreshold);
        } else {
            pathROI = ShapeSimplifier.simplifyShape(pathROI, altitudeThreshold);
        }
        ((PathAnnotationObject) pathObject).setROI(pathROI);
    }
    long endTime = System.currentTimeMillis();
    logger.debug("Shapes simplified in " + (endTime - startTime) + " ms");
    hierarchy.fireObjectsChangedEvent(hierarchy, pathObjects);
}
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) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PolygonROI(qupath.lib.roi.PolygonROI) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) RectangleROI(qupath.lib.roi.RectangleROI) ROI(qupath.lib.roi.interfaces.ROI) PolygonROI(qupath.lib.roi.PolygonROI)

Aggregations

PolygonROI (qupath.lib.roi.PolygonROI)5 PathObject (qupath.lib.objects.PathObject)4 ROI (qupath.lib.roi.interfaces.ROI)4 ArrayList (java.util.ArrayList)3 BufferedImage (java.awt.image.BufferedImage)2 PathObjectHierarchy (qupath.lib.objects.hierarchy.PathObjectHierarchy)2 PolygonRoi (ij.gui.PolygonRoi)1 ShapeRoi (ij.gui.ShapeRoi)1 ByteProcessor (ij.process.ByteProcessor)1 Rectangle (java.awt.Rectangle)1 Shape (java.awt.Shape)1 Window (java.awt.Window)1 AffineTransform (java.awt.geom.AffineTransform)1 Area (java.awt.geom.Area)1 Point2D (java.awt.geom.Point2D)1 File (java.io.File)1 IOException (java.io.IOException)1 Files (java.nio.file.Files)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1