Search in sources :

Example 1 with PathCellObject

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

the class PathHierarchyPaintingHelper method paintObject.

/**
 * Paint an object (or, more precisely, its ROI), optionally along with the ROIs of any child objects.
 *
 * This is subject to the OverlayOptions, and therefore may not actually end up painting anything
 * (if the settings are such that objects of the class provided are not to be displayed)
 *
 * @param pathObject
 * @param paintChildren
 * @param g
 * @param boundsDisplayed
 * @param overlayOptions
 * @param selectionModel
 * @param downsample
 * @return true if anything was painted, false otherwise
 */
public static boolean paintObject(PathObject pathObject, boolean paintChildren, Graphics2D g, Rectangle boundsDisplayed, OverlayOptions overlayOptions, PathObjectSelectionModel selectionModel, double downsample) {
    if (pathObject == null)
        return false;
    // g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
    // g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
    // Always paint the selected object
    // Note: this makes the assumption that child ROIs are completely contained within their parents;
    // this probably should be the case, but isn't guaranteed
    boolean isSelected = (selectionModel != null && selectionModel.isSelected(pathObject)) && (PathPrefs.useSelectedColorProperty().get() || !PathObjectTools.hasPointROI(pathObject));
    boolean isDetectedObject = pathObject.isDetection() || (pathObject.isTile() && pathObject.hasMeasurements());
    // Check if the PathClass isn't being shown
    PathClass pathClass = pathObject.getPathClass();
    if (!isSelected && overlayOptions != null && overlayOptions.isPathClassHidden(pathClass))
        return false;
    boolean painted = false;
    // See if we need to check the children
    ROI pathROI = pathObject.getROI();
    if (pathROI != null) {
        double roiBoundsX = pathROI.getBoundsX();
        double roiBoundsY = pathROI.getBoundsY();
        double roiBoundsWidth = pathROI.getBoundsWidth();
        double roiBoundsHeight = pathROI.getBoundsHeight();
        if (PathObjectTools.hasPointROI(pathObject) || boundsDisplayed == null || pathROI instanceof LineROI || boundsDisplayed.intersects(roiBoundsX, roiBoundsY, Math.max(roiBoundsWidth, 1), Math.max(roiBoundsHeight, 1))) {
            // Paint the ROI, if necessary
            if (isSelected || (overlayOptions.getShowDetections() && isDetectedObject) || (overlayOptions.getShowAnnotations() && pathObject.isAnnotation()) || (overlayOptions.getShowTMAGrid() && pathObject.isTMACore())) {
                boolean doFill = overlayOptions.getFillDetections() || pathObject instanceof ParallelTileObject;
                boolean doOutline = true;
                Color color = null;
                boolean useMapper = false;
                double fillOpacity = .75;
                if (isSelected && PathPrefs.useSelectedColorProperty().get() && PathPrefs.colorSelectedObjectProperty().getValue() != null)
                    color = ColorToolsAwt.getCachedColor(PathPrefs.colorSelectedObjectProperty().get());
                else {
                    MeasurementMapper mapper = overlayOptions.getMeasurementMapper();
                    useMapper = mapper != null && mapper.isValid() && pathObject.isDetection();
                    if (useMapper) {
                        if (pathObject.hasMeasurements()) {
                            Integer rgb = mapper.getColorForObject(pathObject);
                            // If the mapper returns null, the object shouldn't be painted
                            if (rgb == null)
                                return false;
                            // , mapper.getColorMapper().hasAlpha());
                            color = ColorToolsAwt.getCachedColor(rgb);
                        } else
                            color = null;
                        // System.out.println(color + " - " + pathObject.getMeasurementList().getMeasurementValue(mapper.));
                        fillOpacity = 1.0;
                        // Outlines are not so helpful with the measurement mapper
                        if (doFill)
                            doOutline = doOutline && !pathObject.isTile();
                    } else {
                        Integer rgb = ColorToolsFX.getDisplayedColorARGB(pathObject);
                        color = ColorToolsAwt.getCachedColor(rgb);
                    }
                // color = PathObjectHelpers.getDisplayedColor(pathObject);
                }
                // Check if we have only one or two pixels to draw - if so, we can be done quickly
                if (isDetectedObject && downsample > 4 && roiBoundsWidth / downsample < 3 && roiBoundsHeight / downsample < 3) {
                    int x = (int) roiBoundsX;
                    int y = (int) roiBoundsY;
                    // Prefer rounding up, lest we lose a lot of regions unnecessarily
                    int w = (int) (roiBoundsWidth + .9);
                    int h = (int) (roiBoundsHeight + .9);
                    if (w > 0 && h > 0) {
                        g.setColor(color);
                        // g.setColor(DisplayHelpers.getMoreTranslucentColor(color));
                        // g.setStroke(getCachedStroke(overlayOptions.strokeThinThicknessProperty().get()));
                        g.fillRect(x, y, w, h);
                    }
                    painted = true;
                } else {
                    Stroke stroke = null;
                    // Decide whether to fill or not
                    Color colorFill = doFill && (isDetectedObject || PathObjectTools.hasPointROI(pathObject)) ? color : null;
                    if (colorFill != null && fillOpacity != 1) {
                        if (pathObject instanceof ParallelTileObject)
                            colorFill = ColorToolsAwt.getMoreTranslucentColor(colorFill);
                        else if (pathObject instanceof PathCellObject && overlayOptions.getShowCellBoundaries() && overlayOptions.getShowCellNuclei()) {
                            // if (isSelected)
                            // colorFill = ColorToolsAwt.getTranslucentColor(colorFill);
                            // else
                            colorFill = ColorToolsAwt.getMoreTranslucentColor(colorFill);
                        } else if (pathObject.getParent() instanceof PathDetectionObject) {
                            colorFill = ColorToolsAwt.getTranslucentColor(colorFill);
                        } else if (pathObject instanceof PathTileObject && pathClass == null && color != null && color.getRGB() == PathPrefs.colorTileProperty().get()) {
                            // Don't fill in empty, unclassified tiles
                            // DisplayHelpers.getMoreTranslucentColor(colorFill);
                            colorFill = null;
                        }
                    }
                    // Color colorStroke = doOutline ? (colorFill == null ? color : (downsample > overlayOptions.strokeThinThicknessProperty().get() ? null : DisplayHelpers.darkenColor(color))) : null;
                    Color colorStroke = doOutline ? (colorFill == null ? color : ColorToolsAwt.darkenColor(color)) : null;
                    // For thick lines, antialiasing is very noticeable... less so for thin lines (of which there may be a huge number)
                    if (isDetectedObject) {
                        // Detections inside detections get half the line width
                        if (pathObject.getParent() instanceof PathDetectionObject)
                            stroke = getCachedStroke(PathPrefs.detectionStrokeThicknessProperty().get() / 2.0);
                        else
                            stroke = getCachedStroke(PathPrefs.detectionStrokeThicknessProperty().get());
                    } else {
                        double thicknessScale = downsample * (isSelected && !PathPrefs.useSelectedColorProperty().get() ? 1.6 : 1);
                        float thickness = (float) (PathPrefs.annotationStrokeThicknessProperty().get() * thicknessScale);
                        if (isSelected && pathObject.getParent() == null && PathPrefs.selectionModeProperty().get()) {
                            stroke = getCachedStrokeDashed(thickness);
                        } else {
                            stroke = getCachedStroke(thickness);
                        }
                    }
                    g.setStroke(stroke);
                    boolean paintSymbols = overlayOptions.getDetectionDisplayMode() == DetectionDisplayMode.CENTROIDS && pathObject.isDetection() && !pathObject.isTile();
                    if (paintSymbols) {
                        pathROI = PathObjectTools.getROI(pathObject, true);
                        double x = pathROI.getCentroidX();
                        double y = pathROI.getCentroidY();
                        double radius = PathPrefs.detectionStrokeThicknessProperty().get() * 2.0;
                        if (pathObject.getParent() instanceof PathDetectionObject)
                            radius /= 2.0;
                        Shape shape;
                        int nSubclasses = 0;
                        if (pathClass != null) {
                            nSubclasses = PathClassTools.splitNames(pathClass).size();
                        }
                        switch(nSubclasses) {
                            case 0:
                                var ellipse = localEllipse2D.get();
                                ellipse.setFrame(x - radius, y - radius, radius * 2, radius * 2);
                                shape = ellipse;
                                break;
                            case 1:
                                var rect = localRect2D.get();
                                rect.setFrame(x - radius, y - radius, radius * 2, radius * 2);
                                shape = rect;
                                break;
                            case 2:
                                var triangle = localPath2D.get();
                                double sqrt3 = Math.sqrt(3.0);
                                triangle.reset();
                                triangle.moveTo(x, y - radius * 2.0 / sqrt3);
                                triangle.lineTo(x - radius, y + radius / sqrt3);
                                triangle.lineTo(x + radius, y + radius / sqrt3);
                                triangle.closePath();
                                shape = triangle;
                                break;
                            case 3:
                                var plus = localPath2D.get();
                                plus.reset();
                                plus.moveTo(x, y - radius);
                                plus.lineTo(x, y + radius);
                                plus.moveTo(x - radius, y);
                                plus.lineTo(x + radius, y);
                                shape = plus;
                                break;
                            default:
                                var cross = localPath2D.get();
                                cross.reset();
                                radius /= Math.sqrt(2);
                                cross.moveTo(x - radius, y - radius);
                                cross.lineTo(x + radius, y + radius);
                                cross.moveTo(x + radius, y - radius);
                                cross.lineTo(x - radius, y + radius);
                                shape = cross;
                                break;
                        }
                        paintShape(shape, g, colorStroke, stroke, colorFill);
                    } else if (pathObject instanceof PathCellObject) {
                        PathCellObject cell = (PathCellObject) pathObject;
                        if (overlayOptions.getShowCellBoundaries())
                            paintROI(pathROI, g, colorStroke, stroke, colorFill, downsample);
                        if (overlayOptions.getShowCellNuclei())
                            paintROI(cell.getNucleusROI(), g, colorStroke, stroke, colorFill, downsample);
                        painted = true;
                    } else {
                        if ((overlayOptions.getFillAnnotations() && pathObject.isAnnotation() && pathObject.getPathClass() != PathClassFactory.getPathClass(StandardPathClasses.REGION) && (pathObject.getPathClass() != null || !pathObject.hasChildren())) || (pathObject.isTMACore() && overlayOptions.getShowTMACoreLabels()))
                            paintROI(pathROI, g, colorStroke, stroke, ColorToolsAwt.getMoreTranslucentColor(colorStroke), downsample);
                        else
                            paintROI(pathROI, g, colorStroke, stroke, colorFill, downsample);
                        painted = true;
                    }
                }
            }
        }
    }
    // Paint the children, if necessary
    if (paintChildren) {
        for (PathObject childObject : pathObject.getChildObjectsAsArray()) {
            // Only call the painting method if required
            ROI childROI = childObject.getROI();
            if ((childROI != null && boundsDisplayed.intersects(childROI.getBoundsX(), childROI.getBoundsY(), childROI.getBoundsWidth(), childROI.getBoundsHeight())) || childObject.hasChildren())
                painted = paintObject(childObject, paintChildren, g, boundsDisplayed, overlayOptions, selectionModel, downsample) | painted;
        }
    }
    return painted;
}
Also used : BasicStroke(java.awt.BasicStroke) Stroke(java.awt.Stroke) PathDetectionObject(qupath.lib.objects.PathDetectionObject) Shape(java.awt.Shape) RectangularShape(java.awt.geom.RectangularShape) Color(java.awt.Color) EllipseROI(qupath.lib.roi.EllipseROI) PointsROI(qupath.lib.roi.PointsROI) RectangleROI(qupath.lib.roi.RectangleROI) LineROI(qupath.lib.roi.LineROI) ROI(qupath.lib.roi.interfaces.ROI) ParallelTileObject(qupath.lib.plugins.ParallelTileObject) PathClass(qupath.lib.objects.classes.PathClass) PathTileObject(qupath.lib.objects.PathTileObject) PathObject(qupath.lib.objects.PathObject) MeasurementMapper(qupath.lib.gui.tools.MeasurementMapper) LineROI(qupath.lib.roi.LineROI) PathCellObject(qupath.lib.objects.PathCellObject)

Example 2 with PathCellObject

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

the class IJExtension method extractOverlay.

/**
 * Extract an ImageJ overlay for the specified region.
 * @param hierarchy
 * @param request
 * @param options options to control which objects are being displayed
 * @param filter optional additional filter used to determine which objects will be included (may be used in combination with options)
 * @return
 */
public static Overlay extractOverlay(PathObjectHierarchy hierarchy, RegionRequest request, OverlayOptions options, Predicate<PathObject> filter) {
    Overlay overlay = new Overlay();
    double downsample = request.getDownsample();
    double xOrigin = -request.getX() / downsample;
    double yOrigin = -request.getY() / downsample;
    // TODO: Permit filling/unfilling ROIs
    for (PathObject child : hierarchy.getObjectsForRegion(PathObject.class, request, null)) {
        if (filter != null && !filter.test(child))
            continue;
        if (child.hasROI()) {
            // Check if this is displayed - skip it not
            if (options != null && ((child instanceof PathDetectionObject && !options.getShowDetections()) || (child instanceof PathAnnotationObject && !options.getShowAnnotations()) || (child instanceof TMACoreObject && !options.getShowTMAGrid())))
                continue;
            boolean isCell = child instanceof PathCellObject;
            Color color = ColorToolsAwt.getCachedColor(ColorToolsFX.getDisplayedColorARGB(child));
            if (!(isCell && (options == null || !options.getShowCellBoundaries()))) {
                Roi roi = IJTools.convertToIJRoi(child.getROI(), xOrigin, yOrigin, downsample);
                roi.setStrokeColor(color);
                roi.setName(child.getDisplayedName());
                // roi.setStrokeWidth(2);
                overlay.add(roi);
            }
            if (isCell && (options == null || options.getShowCellNuclei())) {
                ROI nucleus = ((PathCellObject) child).getNucleusROI();
                if (nucleus == null)
                    continue;
                Roi roi = IJTools.convertToIJRoi(((PathCellObject) child).getNucleusROI(), xOrigin, yOrigin, downsample);
                roi.setStrokeColor(color);
                roi.setName(child.getDisplayedName() + " - nucleus");
                overlay.add(roi);
            }
        }
    }
    return overlay;
}
Also used : PathDetectionObject(qupath.lib.objects.PathDetectionObject) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) TMACoreObject(qupath.lib.objects.TMACoreObject) Color(java.awt.Color) Overlay(ij.gui.Overlay) Roi(ij.gui.Roi) ROI(qupath.lib.roi.interfaces.ROI) PathCellObject(qupath.lib.objects.PathCellObject)

Example 3 with PathCellObject

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

the class PathObjectIOTest method test_IOObjectsGeoJSONImpl.

private void test_IOObjectsGeoJSONImpl(boolean keepMeasurements, GeoJsonExportOptions... options) throws IOException {
    ROI roiDetection = ROIs.createRectangleROI(0, 0, 10, 10, ImagePlane.getDefaultPlane());
    ROI roiAnnotation = ROIs.createRectangleROI(100, 100, 10, 10, ImagePlane.getDefaultPlane());
    ROI roiCell1 = ROIs.createRectangleROI(25, 25, 25, 25, ImagePlane.getDefaultPlane());
    ROI roiCell2 = ROIs.createRectangleROI(12, 12, 5, 5, ImagePlane.getDefaultPlane());
    ROI roiTile = ROIs.createRectangleROI(100, 100, 10, 10, ImagePlane.getDefaultPlane());
    MeasurementList mlDetection = MeasurementListFactory.createMeasurementList(16, MeasurementList.MeasurementListType.GENERAL);
    MeasurementList mlCell = MeasurementListFactory.createMeasurementList(16, MeasurementList.MeasurementListType.GENERAL);
    PathObject myPDO = PathObjects.createDetectionObject(roiDetection, PathClassFactory.getPathClass("PathClassTest1", ColorTools.BLACK), mlDetection);
    PathObject myPAO = PathObjects.createAnnotationObject(roiAnnotation, PathClassFactory.getPathClass("PathClassTest1", ColorTools.BLACK));
    PathObject myPCO = PathObjects.createCellObject(roiCell1, roiCell2, PathClassFactory.getPathClass("PathClassTest2", ColorTools.GREEN), mlCell);
    PathObject myPTO = PathObjects.createTileObject(roiTile, PathClassFactory.getPathClass("PathClassTest2", ColorTools.GREEN), null);
    PathObject myTMA = PathObjects.createTMACoreObject(25, 25, 25, false);
    Collection<PathObject> objs = Arrays.asList(myPDO, myPCO, myPAO, myPTO, myTMA);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    // Add measurements
    mlDetection.addMeasurement("TestMeasurement1", 5.0);
    mlDetection.addMeasurement("TestMeasurement2", 10.0);
    mlCell.addMeasurement("TestMeasurement3", 15.0);
    mlCell.addMeasurement("TestMeasurement4", 20.0);
    // Export to GeoJSON
    PathIO.exportObjectsAsGeoJSON(bos, objs, options);
    // Import from GeoJSON
    List<PathObject> objsBack = new ArrayList<>(PathIO.readObjectsFromGeoJSON(new ByteArrayInputStream(bos.toByteArray())));
    assertEquals(objs.size(), objsBack.size());
    // Array to count number of each PathObject type
    int[] countCheck = new int[] { 0, 0, 0, 0, 0 };
    for (PathObject po : objsBack) {
        if (po == null)
            continue;
        // Test whether po has a ROI
        assertTrue(po.hasROI());
        if (po.isTile()) {
            assertEquals(po.getPathClass(), PathClassFactory.getPathClass("PathClassTest2", ColorTools.GREEN));
            assertSameROIs(po.getROI(), roiTile);
            assertFalse(po.hasMeasurements());
            countCheck[0]++;
        } else if (po.isCell()) {
            assertEquals(po.getPathClass(), PathClassFactory.getPathClass("PathClassTest2", ColorTools.GREEN));
            assertSameROIs(po.getROI(), roiCell1);
            assertSameROIs(((PathCellObject) po).getNucleusROI(), roiCell2);
            if (keepMeasurements) {
                assertTrue(po.hasMeasurements());
                assertSameMeasurements(po.getMeasurementList(), myPCO.getMeasurementList());
            } else
                assertFalse(po.hasMeasurements());
            countCheck[1]++;
        } else if (po.isDetection()) {
            assertEquals(po.getPathClass(), PathClassFactory.getPathClass("PathClassTest1", ColorTools.BLACK));
            assertSameROIs(po.getROI(), roiDetection);
            if (keepMeasurements) {
                assertTrue(po.hasMeasurements());
                assertSameMeasurements(po.getMeasurementList(), myPDO.getMeasurementList());
            } else
                assertFalse(po.hasMeasurements());
            countCheck[2]++;
        } else if (po.isAnnotation()) {
            assertEquals(po.getPathClass(), PathClassFactory.getPathClass("PathClassTest1", ColorTools.BLACK));
            assertSameROIs(po.getROI(), roiAnnotation);
            assertFalse(po.hasMeasurements());
            countCheck[3]++;
        } else if (po.isTMACore()) {
            assertFalse(po.hasMeasurements());
            assertSameROIs(po.getROI(), myTMA.getROI());
            countCheck[4]++;
        }
    }
    assertArrayEquals(countCheck, new int[] { 1, 1, 1, 1, 1 });
}
Also used : PathObject(qupath.lib.objects.PathObject) ByteArrayInputStream(java.io.ByteArrayInputStream) MeasurementList(qupath.lib.measurements.MeasurementList) ArrayList(java.util.ArrayList) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ROI(qupath.lib.roi.interfaces.ROI) PathCellObject(qupath.lib.objects.PathCellObject)

Example 4 with PathCellObject

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

the class ObjectMeasurements method addIntensityMeasurements.

/**
 * Measure all channels of an image for one individual object or cell.
 * All compartments are measured where possible (nucleus, cytoplasm, membrane and full cell).
 * <p>
 * Note: This implementation is likely to change in the future, to enable neighboring cells to be
 * measured more efficiently.
 *
 * @param server the server containing the pixels (and channels) to be measured
 * @param pathObject the cell to measure (the {@link MeasurementList} will be updated)
 * @param downsample resolution at which to request pixels
 * @param measurements requested measurements to make
 * @param compartments the cell compartments to measure; ignored if the object is not a cell
 * @throws IOException
 */
public static void addIntensityMeasurements(ImageServer<BufferedImage> server, PathObject pathObject, double downsample, Collection<Measurements> measurements, Collection<Compartments> compartments) throws IOException {
    var roi = pathObject.getROI();
    int pad = (int) Math.ceil(downsample * 2);
    var request = RegionRequest.createInstance(server.getPath(), downsample, roi).pad2D(pad, pad).intersect2D(0, 0, server.getWidth(), server.getHeight());
    var pathImage = IJTools.convertToImagePlus(server, request);
    var imp = pathImage.getImage();
    Map<String, ImageProcessor> channels = new LinkedHashMap<>();
    var serverChannels = server.getMetadata().getChannels();
    if (server.isRGB() && imp.getStackSize() == 1 && imp.getProcessor() instanceof ColorProcessor) {
        ColorProcessor cp = (ColorProcessor) imp.getProcessor();
        for (int i = 0; i < serverChannels.size(); i++) {
            channels.put(serverChannels.get(i).getName(), cp.getChannel(i + 1, null));
        }
    } else {
        assert imp.getStackSize() == serverChannels.size();
        for (int i = 0; i < imp.getStackSize(); i++) {
            channels.put(serverChannels.get(i).getName(), imp.getStack().getProcessor(i + 1));
        }
    }
    ByteProcessor bpCell = new ByteProcessor(imp.getWidth(), imp.getHeight());
    bpCell.setValue(1.0);
    var roiIJ = IJTools.convertToIJRoi(roi, pathImage);
    bpCell.fill(roiIJ);
    if (pathObject instanceof PathCellObject) {
        var cell = (PathCellObject) pathObject;
        ByteProcessor bpNucleus = new ByteProcessor(imp.getWidth(), imp.getHeight());
        if (cell.getNucleusROI() != null) {
            bpNucleus.setValue(1.0);
            var roiNucleusIJ = IJTools.convertToIJRoi(cell.getNucleusROI(), pathImage);
            bpNucleus.fill(roiNucleusIJ);
        }
        measureCells(bpNucleus, bpCell, Map.of(1.0, cell), channels, compartments, measurements);
    } else {
        var imgLabels = new PixelImageIJ(bpCell);
        for (var entry : channels.entrySet()) {
            var img = new PixelImageIJ(entry.getValue());
            measureObjects(img, imgLabels, new PathObject[] { pathObject }, entry.getKey(), measurements);
        }
    }
}
Also used : ByteProcessor(ij.process.ByteProcessor) ImageProcessor(ij.process.ImageProcessor) ColorProcessor(ij.process.ColorProcessor) PixelImageIJ(qupath.imagej.tools.PixelImageIJ) LinkedHashMap(java.util.LinkedHashMap) PathCellObject(qupath.lib.objects.PathCellObject)

Example 5 with PathCellObject

use of qupath.lib.objects.PathCellObject 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);
            }
        }
    });
}
Also used : Arrays(java.util.Arrays) ImageServer(qupath.lib.images.servers.ImageServer) ByteProcessor(ij.process.ByteProcessor) Length(org.locationtech.jts.algorithm.Length) MinimumBoundingCircle(org.locationtech.jts.algorithm.MinimumBoundingCircle) ImageProcessor(ij.process.ImageProcessor) IJTools(qupath.imagej.tools.IJTools) LoggerFactory(org.slf4j.LoggerFactory) StatisticalSummary(org.apache.commons.math3.stat.descriptive.StatisticalSummary) PixelImageIJ(qupath.imagej.tools.PixelImageIJ) MeasurementList(qupath.lib.measurements.MeasurementList) EllipseROI(qupath.lib.roi.EllipseROI) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) AffineTransformation(org.locationtech.jts.geom.util.AffineTransformation) LinkedHashSet(java.util.LinkedHashSet) ColorProcessor(ij.process.ColorProcessor) Logger(org.slf4j.Logger) BufferedImage(java.awt.image.BufferedImage) GeneralTools(qupath.lib.common.GeneralTools) RegionRequest(qupath.lib.regions.RegionRequest) SimpleImage(qupath.lib.analysis.images.SimpleImage) Collection(java.util.Collection) Set(java.util.Set) IOException(java.io.IOException) Polygonal(org.locationtech.jts.geom.Polygonal) Area(org.locationtech.jts.algorithm.Area) Lineal(org.locationtech.jts.geom.Lineal) PathObject(qupath.lib.objects.PathObject) ROI(qupath.lib.roi.interfaces.ROI) FloatProcessor(ij.process.FloatProcessor) DescriptiveStatistics(org.apache.commons.math3.stat.descriptive.DescriptiveStatistics) PixelCalibration(qupath.lib.images.servers.PixelCalibration) MinimumDiameter(org.locationtech.jts.algorithm.MinimumDiameter) Polygon(org.locationtech.jts.geom.Polygon) Geometry(org.locationtech.jts.geom.Geometry) PathCellObject(qupath.lib.objects.PathCellObject) Collections(java.util.Collections) PixelCalibration(qupath.lib.images.servers.PixelCalibration) PathCellObject(qupath.lib.objects.PathCellObject)

Aggregations

PathCellObject (qupath.lib.objects.PathCellObject)8 ROI (qupath.lib.roi.interfaces.ROI)7 MeasurementList (qupath.lib.measurements.MeasurementList)5 PixelCalibration (qupath.lib.images.servers.PixelCalibration)4 PathObject (qupath.lib.objects.PathObject)4 BufferedImage (java.awt.image.BufferedImage)3 LinkedHashMap (java.util.LinkedHashMap)3 RegionRequest (qupath.lib.regions.RegionRequest)3 ByteProcessor (ij.process.ByteProcessor)2 ColorProcessor (ij.process.ColorProcessor)2 ImageProcessor (ij.process.ImageProcessor)2 Color (java.awt.Color)2 ArrayList (java.util.ArrayList)2 PixelImageIJ (qupath.imagej.tools.PixelImageIJ)2 PathAnnotationObject (qupath.lib.objects.PathAnnotationObject)2 PathDetectionObject (qupath.lib.objects.PathDetectionObject)2 TMACoreObject (qupath.lib.objects.TMACoreObject)2 EllipseROI (qupath.lib.roi.EllipseROI)2 Overlay (ij.gui.Overlay)1 Roi (ij.gui.Roi)1