Search in sources :

Example 16 with ROI

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

the class PathHierarchyPaintingHelper method paintConnections.

/**
 * Paint connections between objects (e.g. from Delaunay triangulation).
 *
 * @param connections
 * @param hierarchy
 * @param g2d
 * @param color
 * @param downsampleFactor
 */
public static void paintConnections(final PathObjectConnections connections, final PathObjectHierarchy hierarchy, Graphics2D g2d, final Color color, final double downsampleFactor) {
    if (hierarchy == null || connections == null || connections.isEmpty())
        return;
    float alpha = (float) (1f - downsampleFactor / 5);
    alpha = Math.min(alpha, 0.25f);
    float thickness = PathPrefs.detectionStrokeThicknessProperty().get();
    if (alpha < .1f || thickness / downsampleFactor <= 0.5)
        return;
    g2d = (Graphics2D) g2d.create();
    // Shape clipShape = g2d.getClip();
    g2d.setStroke(getCachedStroke(thickness));
    // g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha * .5f));
    // g2d.setColor(ColorToolsAwt.getColorWithOpacity(getPreferredOverlayColor(), 1));
    g2d.setColor(ColorToolsAwt.getColorWithOpacity(color.getRGB(), alpha));
    // g2d.setColor(Color.BLACK);
    Line2D line = new Line2D.Double();
    // We can have trouble whenever two objects are outside the clip, but their connections would be inside it
    // Here, we just enlarge the region (by quite a lot)
    // It's not guaranteed to work, but it usually does... and avoids much expensive computations
    Rectangle bounds = g2d.getClipBounds();
    int factor = 1;
    Rectangle bounds2 = factor > 0 ? new Rectangle(bounds.x - bounds.width * factor, bounds.y - bounds.height * factor, bounds.width * (factor * 2 + 1), bounds.height * (factor * 2 + 1)) : bounds;
    ImageRegion imageRegion = AwtTools.getImageRegion(bounds2, 0, 0);
    // ImageRegion imageRegion = AwtTools.getImageRegion(bounds, 0, 0);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
    // g2d.draw(g2d.getClipBounds());
    Collection<PathObject> pathObjects = hierarchy.getObjectsForRegion(PathDetectionObject.class, imageRegion, null);
    // double threshold = downsampleFactor*downsampleFactor*4;
    for (PathObject pathObject : pathObjects) {
        ROI roi = PathObjectTools.getROI(pathObject, true);
        double x1 = roi.getCentroidX();
        double y1 = roi.getCentroidY();
        for (PathObjectConnectionGroup dt : connections.getConnectionGroups()) {
            for (PathObject siblingObject : dt.getConnectedObjects(pathObject)) {
                ROI roi2 = PathObjectTools.getROI(siblingObject, true);
                double x2 = roi2.getCentroidX();
                double y2 = roi2.getCentroidY();
                if (bounds.intersectsLine(x1, y1, x2, y2)) {
                    line.setLine(x1, y1, x2, y2);
                    g2d.draw(line);
                }
            }
        }
    }
    g2d.dispose();
}
Also used : PathObject(qupath.lib.objects.PathObject) Rectangle(java.awt.Rectangle) ImageRegion(qupath.lib.regions.ImageRegion) PathObjectConnectionGroup(qupath.lib.objects.PathObjectConnectionGroup) Line2D(java.awt.geom.Line2D) 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)

Example 17 with ROI

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

the class QuPathViewer method updateRoiEditor.

private void updateRoiEditor() {
    PathObject pathObjectSelected = getSelectedObject();
    ROI previousROI = roiEditor.getROI();
    ROI newROI = pathObjectSelected != null && pathObjectSelected.isEditable() ? pathObjectSelected.getROI() : null;
    if (previousROI == newROI)
        roiEditor.ensureHandlesUpdated();
    else
        roiEditor.setROI(newROI);
    repaint();
}
Also used : PathObject(qupath.lib.objects.PathObject) RectangleROI(qupath.lib.roi.RectangleROI) ROI(qupath.lib.roi.interfaces.ROI)

Example 18 with ROI

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

the class IJTools method convertToPathObject.

/**
 * Create a {@link PathObject} for a specific ImageJ Roi, using an {@link ImagePlus} to help set properties.
 *
 * @param roi the ImageJ ROI
 * @param downsampleFactor the downsample factor used for rescaling (or 1.0 for no rescaling)
 * @param creator a function
 * @param imp the {@link ImagePlus} associated with this Roi; it is used to determine the xOrigin, yOrigin and image plane
 * @return a {@link PathObject} or null if no object could be created (e.g. the ImageJ roi is null or incompatible)
 *
 * @see #convertToPathObject(Roi, double, double, double, Function, ImagePlane)
 * @since v0.4.0
 */
public static PathObject convertToPathObject(Roi roi, double downsampleFactor, Function<ROI, PathObject> creator, ImagePlus imp) {
    Calibration cal = imp == null ? null : imp.getCalibration();
    var plane = getImagePlane(roi, imp);
    ROI pathROI = IJTools.convertToROI(roi, cal, downsampleFactor, plane);
    if (pathROI == null)
        return null;
    PathObject pathObject = creator.apply(pathROI);
    calibrateObject(pathObject, roi);
    return pathObject;
}
Also used : PathObject(qupath.lib.objects.PathObject) Calibration(ij.measure.Calibration) PixelCalibration(qupath.lib.images.servers.PixelCalibration) EllipseROI(qupath.lib.roi.EllipseROI) PointsROI(qupath.lib.roi.PointsROI) PolygonROI(qupath.lib.roi.PolygonROI) RectangleROI(qupath.lib.roi.RectangleROI) LineROI(qupath.lib.roi.LineROI) PolylineROI(qupath.lib.roi.PolylineROI) ROI(qupath.lib.roi.interfaces.ROI)

Example 19 with ROI

use of qupath.lib.roi.interfaces.ROI 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 20 with ROI

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

the class IJExtension method extractROIWithOverlay.

/**
 * Extract an image region as an ImagePlus, optionally setting ImageJ Rois corresponding to QuPath objects.
 *
 * @param server server from which pixels should be requested
 * @param pathObject the primary object, which may have its ROI set on the image
 * @param hierarchy object hierarchy containing objects whose ROIs should be added to the ImagePlus overlay
 * @param request the region being requested
 * @param setROI if true, the ROI of the pathObject will be set on the image as the 'main' ROI (i.e. not an overlay)
 * @param options options determining which kinds of objects will have ROIs added, to match with the display in the QuPath viewer
 * @return
 * @throws IOException
 */
public static PathImage<ImagePlus> extractROIWithOverlay(ImageServer<BufferedImage> server, PathObject pathObject, PathObjectHierarchy hierarchy, RegionRequest request, boolean setROI, OverlayOptions options) throws IOException {
    ROI pathROI;
    if (pathObject == null || !pathObject.hasROI()) {
        pathROI = ROIs.createRectangleROI(0, 0, server.getWidth(), server.getHeight(), ImagePlane.getDefaultPlane());
    // logger.error("No ROI found to extract!");
    // return null;
    } else
        pathROI = pathObject.getROI();
    // Extract the image
    PathImage<ImagePlus> pathImage = extractROI(server, pathROI, request, setROI);
    if (pathImage == null)
        return pathImage;
    // Add the overlay
    if (hierarchy != null) {
        ImagePlus imp = pathImage.getImage();
        var regionPredicate = PathObjectTools.createImageRegionPredicate(request);
        Overlay overlay = extractOverlay(hierarchy, request, options, p -> p != pathObject && regionPredicate.test(p));
        if (overlay.size() > 0) {
            imp.setOverlay(overlay);
        }
    }
    IJTools.setTitleFromObject(pathImage, pathObject);
    return pathImage;
}
Also used : Overlay(ij.gui.Overlay) ROI(qupath.lib.roi.interfaces.ROI) ImagePlus(ij.ImagePlus)

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