Search in sources :

Example 11 with PixelCalibration

use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.

the class RefineAnnotationsPlugin method getTasks.

@Override
protected Collection<Runnable> getTasks(final PluginRunner<T> runner) {
    Collection<? extends PathObject> parentObjects = getParentObjects(runner);
    if (parentObjects == null || parentObjects.isEmpty())
        return Collections.emptyList();
    // Add a single task, to avoid multithreading - which may complicate setting parents
    List<Runnable> tasks = new ArrayList<>(1);
    PathObjectHierarchy hierarchy = getHierarchy(runner);
    double minFragmentSize;
    double maxHoleSize, maxHoleSizeTemp;
    ImageServer<T> server = getServer(runner);
    PixelCalibration cal = server.getPixelCalibration();
    if (cal.hasPixelSizeMicrons()) {
        double pixelAreaMicrons = cal.getPixelWidthMicrons() * cal.getPixelHeightMicrons();
        minFragmentSize = params.getDoubleParameterValue("minFragmentSizeMicrons") / pixelAreaMicrons;
        maxHoleSizeTemp = params.getDoubleParameterValue("maxHoleSizeMicrons") / pixelAreaMicrons;
    } else {
        minFragmentSize = params.getDoubleParameterValue("minFragmentSizePixels");
        maxHoleSizeTemp = params.getDoubleParameterValue("maxHoleSizePixels");
    }
    // Handle negative values
    if (maxHoleSizeTemp < 0)
        maxHoleSize = Double.POSITIVE_INFINITY;
    else
        maxHoleSize = maxHoleSizeTemp;
    // Want to reset selection
    PathObject selected = hierarchy.getSelectionModel().getSelectedObject();
    Collection<PathObject> previousSelection = new ArrayList<>(hierarchy.getSelectionModel().getSelectedObjects());
    tasks.add(() -> {
        List<PathObject> toRemove = new ArrayList<>();
        Map<PathROIObject, ROI> toUpdate = new HashMap<>();
        for (PathObject pathObject : parentObjects) {
            ROI roiOrig = pathObject.getROI();
            if (roiOrig == null || !roiOrig.isArea())
                continue;
            ROI roiUpdated = RoiTools.removeSmallPieces(roiOrig, minFragmentSize, maxHoleSize);
            if (roiUpdated == null || roiUpdated.isEmpty())
                toRemove.add(pathObject);
            else if (roiOrig != roiUpdated && pathObject instanceof PathROIObject) {
                toUpdate.put((PathROIObject) pathObject, roiUpdated);
            }
        }
        if (toRemove.isEmpty() && toUpdate.isEmpty())
            return;
        hierarchy.getSelectionModel().clearSelection();
        if (!toRemove.isEmpty())
            hierarchy.removeObjects(toRemove, true);
        if (!toUpdate.isEmpty()) {
            hierarchy.removeObjects(toUpdate.keySet(), true);
            toUpdate.forEach((p, r) -> p.setROI(r));
            hierarchy.addPathObjects(toUpdate.keySet());
        }
        hierarchy.getSelectionModel().selectObjects(previousSelection);
        hierarchy.getSelectionModel().setSelectedObject(selected, true);
    });
    return tasks;
}
Also used : PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) PixelCalibration(qupath.lib.images.servers.PixelCalibration) PathROIObject(qupath.lib.objects.PathROIObject) ROI(qupath.lib.roi.interfaces.ROI) PathObject(qupath.lib.objects.PathObject)

Example 12 with PixelCalibration

use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.

the class IntensityFeaturesPlugin method getPreferredTileSizePixels.

private static ImmutableDimension getPreferredTileSizePixels(final ImageServer<BufferedImage> server, final ParameterList params) {
    // Determine tile size
    int tileWidth, tileHeight;
    PixelCalibration cal = server.getPixelCalibration();
    if (cal.hasPixelSizeMicrons()) {
        double tileSize = params.getDoubleParameterValue("tileSizeMicrons");
        tileWidth = (int) Math.round(tileSize / cal.getPixelWidthMicrons());
        tileHeight = (int) Math.round(tileSize / cal.getPixelHeightMicrons());
    } else {
        tileWidth = (int) Math.round(params.getDoubleParameterValue("tileSizePixels"));
        tileHeight = tileWidth;
    }
    return ImmutableDimension.getInstance(tileWidth, tileHeight);
}
Also used : PixelCalibration(qupath.lib.images.servers.PixelCalibration)

Example 13 with PixelCalibration

use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.

the class DelaunayTools method createGeometryExtractor.

private static Function<PathObject, Collection<Coordinate>> createGeometryExtractor(PixelCalibration cal, boolean preferNucleus, double densifyFactor, double erosion) {
    PrecisionModel precision = calibrated(cal) ? null : GeometryTools.getDefaultFactory().getPrecisionModel();
    AffineTransformation transform = calibrated(cal) ? AffineTransformation.scaleInstance(cal.getPixelWidth().doubleValue(), cal.getPixelHeight().doubleValue()) : null;
    return p -> {
        var roi = PathObjectTools.getROI(p, preferNucleus);
        if (roi == null || roi.isEmpty())
            return Collections.emptyList();
        var geom = roi.getGeometry();
        if (transform != null)
            geom = transform.transform(geom);
        // Shared boundaries can be problematic, so try to buffer away from these
        double buffer = -Math.abs(erosion);
        if (buffer < 0 && geom instanceof Polygonal) {
            var geomBefore = geom;
            geom = GeometryTools.attemptOperation(geom, g -> g.buffer(buffer));
            // Do not permit Geometry to disappear
            if (geom.isEmpty()) {
                geom = geomBefore;
            }
        }
        // Therefore we take extra care in case empty geometries are being generated accidentally.
        if (precision != null) {
            var geom2 = GeometryTools.attemptOperation(geom, g -> GeometryPrecisionReducer.reduce(g, precision));
            if (!geom2.isEmpty())
                geom = geom2;
        }
        if (densifyFactor > 0) {
            var geom2 = GeometryTools.attemptOperation(geom, g -> Densifier.densify(g, densifyFactor));
            if (!geom2.isEmpty())
                geom = geom2;
        }
        // if (!(geom instanceof Polygon))
        // logger.warn("Unexpected Geometry: {}", geom);
        // Making precise is essential! Otherwise there can be small artifacts occurring
        var coords = geom.getCoordinates();
        var output = new LinkedHashSet<Coordinate>();
        var p2 = precision;
        Coordinate lastCoordinate = null;
        if (p2 == null)
            p2 = GeometryTools.getDefaultFactory().getPrecisionModel();
        // Add coordinates, unless they are extremely close to an existing coordinate
        int n = coords.length;
        if (n == 0) {
            logger.warn("Empty Geometry found for {}", p);
            return Collections.emptyList();
        }
        double minDistance = densifyFactor * 0.5;
        var firstCoordinate = coords[0];
        while (n > 2 && firstCoordinate.distance(coords[n - 1]) < minDistance) n--;
        for (int i = 0; i < n; i++) {
            var c = coords[i];
            p2.makePrecise(c);
            if (i == 0 || c.distance(lastCoordinate) > minDistance) {
                output.add(c);
                lastCoordinate = c;
            }
        }
        return output;
    };
}
Also used : IncrementalDelaunayTriangulator(org.locationtech.jts.triangulate.IncrementalDelaunayTriangulator) LoggerFactory(org.slf4j.LoggerFactory) Coordinate(org.locationtech.jts.geom.Coordinate) HashMap(java.util.HashMap) PathClassFactory(qupath.lib.objects.classes.PathClassFactory) DelaunayTriangulationBuilder(org.locationtech.jts.triangulate.DelaunayTriangulationBuilder) Function(java.util.function.Function) ArrayList(java.util.ArrayList) QuadEdge(org.locationtech.jts.triangulate.quadedge.QuadEdge) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) BiPredicate(java.util.function.BiPredicate) LastFoundQuadEdgeLocator(org.locationtech.jts.triangulate.quadedge.LastFoundQuadEdgeLocator) GeometryPrecisionReducer(org.locationtech.jts.precision.GeometryPrecisionReducer) QuadEdgeSubdivision(org.locationtech.jts.triangulate.quadedge.QuadEdgeSubdivision) Map(java.util.Map) GeometryTools(qupath.lib.roi.GeometryTools) AffineTransformation(org.locationtech.jts.geom.util.AffineTransformation) GeometryCombiner(org.locationtech.jts.geom.util.GeometryCombiner) LinkedHashSet(java.util.LinkedHashSet) RoiTools(qupath.lib.roi.RoiTools) GeometryFactory(org.locationtech.jts.geom.GeometryFactory) Logger(org.slf4j.Logger) QuadEdgeLocator(org.locationtech.jts.triangulate.quadedge.QuadEdgeLocator) Collection(java.util.Collection) Densifier(org.locationtech.jts.densify.Densifier) PathObjects(qupath.lib.objects.PathObjects) Quadtree(org.locationtech.jts.index.quadtree.Quadtree) PathClass(qupath.lib.objects.classes.PathClass) Set(java.util.Set) Polygonal(org.locationtech.jts.geom.Polygonal) 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) PixelCalibration(qupath.lib.images.servers.PixelCalibration) Polygon(org.locationtech.jts.geom.Polygon) ImagePlane(qupath.lib.regions.ImagePlane) Geometry(org.locationtech.jts.geom.Geometry) PrecisionModel(org.locationtech.jts.geom.PrecisionModel) ArrayDeque(java.util.ArrayDeque) Comparator(java.util.Comparator) Collections(java.util.Collections) Envelope(org.locationtech.jts.geom.Envelope) Vertex(org.locationtech.jts.triangulate.quadedge.Vertex) Polygonal(org.locationtech.jts.geom.Polygonal) Coordinate(org.locationtech.jts.geom.Coordinate) AffineTransformation(org.locationtech.jts.geom.util.AffineTransformation) PrecisionModel(org.locationtech.jts.geom.PrecisionModel)

Example 14 with PixelCalibration

use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.

the class ClassificationResolution method getDefaultResolutions.

/**
 * Get a list of default resolutions to show, derived from {@link PixelCalibration} objects.
 * @param imageData
 * @param selected
 * @return
 */
public static List<ClassificationResolution> getDefaultResolutions(ImageData<?> imageData, ClassificationResolution selected) {
    var temp = new ArrayList<ClassificationResolution>();
    PixelCalibration cal = imageData.getServer().getPixelCalibration();
    int scale = 1;
    for (String name : resolutionNames) {
        var newResolution = new ClassificationResolution(name, cal.createScaledInstance(scale, scale, 1));
        if (Objects.equals(selected, newResolution))
            temp.add(selected);
        else
            temp.add(newResolution);
        scale *= 2;
    }
    if (selected == null)
        selected = temp.get(0);
    else if (!temp.contains(selected))
        temp.add(selected);
    return temp;
}
Also used : ArrayList(java.util.ArrayList) PixelCalibration(qupath.lib.images.servers.PixelCalibration)

Example 15 with PixelCalibration

use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.

the class PixelClassifierPane method addResolution.

private boolean addResolution() {
    var imageData = qupath.getImageData();
    ImageServer<BufferedImage> server = imageData == null ? null : imageData.getServer();
    if (server == null) {
        Dialogs.showNoImageError("Add resolution");
        return false;
    }
    String units = null;
    Double pixelSize = null;
    PixelCalibration cal = server.getPixelCalibration();
    if (cal.hasPixelSizeMicrons()) {
        pixelSize = Dialogs.showInputDialog("Add resolution", "Enter requested pixel size in " + GeneralTools.micrometerSymbol(), 1.0);
        units = PixelCalibration.MICROMETER;
    } else {
        pixelSize = Dialogs.showInputDialog("Add resolution", "Enter requested downsample factor", 1.0);
    }
    if (pixelSize == null)
        return false;
    ClassificationResolution res;
    if (PixelCalibration.MICROMETER.equals(units)) {
        double scale = pixelSize / cal.getAveragedPixelSizeMicrons();
        res = new ClassificationResolution("Custom", cal.createScaledInstance(scale, scale, 1));
    } else
        res = new ClassificationResolution("Custom", cal.createScaledInstance(pixelSize, pixelSize, 1));
    List<ClassificationResolution> temp = new ArrayList<>(resolutions);
    temp.add(res);
    Collections.sort(temp, Comparator.comparingDouble((ClassificationResolution w) -> w.cal.getAveragedPixelSize().doubleValue()));
    resolutions.setAll(temp);
    comboResolutions.getSelectionModel().select(res);
    return true;
}
Also used : ArrayList(java.util.ArrayList) PixelCalibration(qupath.lib.images.servers.PixelCalibration) BufferedImage(java.awt.image.BufferedImage)

Aggregations

PixelCalibration (qupath.lib.images.servers.PixelCalibration)31 BufferedImage (java.awt.image.BufferedImage)9 ArrayList (java.util.ArrayList)8 ROI (qupath.lib.roi.interfaces.ROI)8 RegionRequest (qupath.lib.regions.RegionRequest)7 MeasurementList (qupath.lib.measurements.MeasurementList)6 PathObject (qupath.lib.objects.PathObject)6 Calibration (ij.measure.Calibration)5 PathCellObject (qupath.lib.objects.PathCellObject)5 ParameterList (qupath.lib.plugins.parameters.ParameterList)5 List (java.util.List)4 Collection (java.util.Collection)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ImagePlus (ij.ImagePlus)2 ByteProcessor (ij.process.ByteProcessor)2 FloatProcessor (ij.process.FloatProcessor)2 ImageProcessor (ij.process.ImageProcessor)2 Graphics2D (java.awt.Graphics2D)2 LinkedHashMap (java.util.LinkedHashMap)2