Search in sources :

Example 1 with RegionRequest

use of qupath.lib.regions.RegionRequest in project qupath by qupath.

the class Commands method promptToExportImageRegion.

/**
 * Prompt to export the current image region selected in the viewer.
 * @param viewer the viewer containing the image to export
 * @param renderedImage if true, export the rendered (RGB) image rather than original pixel values
 */
public static void promptToExportImageRegion(QuPathViewer viewer, boolean renderedImage) {
    if (viewer == null || viewer.getServer() == null) {
        Dialogs.showErrorMessage("Export image region", "No viewer & image selected!");
        return;
    }
    ImageServer<BufferedImage> server = viewer.getServer();
    if (renderedImage)
        server = RenderedImageServer.createRenderedServer(viewer);
    PathObject pathObject = viewer.getSelectedObject();
    ROI roi = pathObject == null ? null : pathObject.getROI();
    double regionWidth = roi == null ? server.getWidth() : roi.getBoundsWidth();
    double regionHeight = roi == null ? server.getHeight() : roi.getBoundsHeight();
    // Create a dialog
    GridPane pane = new GridPane();
    int row = 0;
    pane.add(new Label("Export format"), 0, row);
    ComboBox<ImageWriter<BufferedImage>> comboImageType = new ComboBox<>();
    Function<ImageWriter<BufferedImage>, String> fun = (ImageWriter<BufferedImage> writer) -> writer.getName();
    comboImageType.setCellFactory(p -> GuiTools.createCustomListCell(fun));
    comboImageType.setButtonCell(GuiTools.createCustomListCell(fun));
    var writers = ImageWriterTools.getCompatibleWriters(server, null);
    comboImageType.getItems().setAll(writers);
    comboImageType.setTooltip(new Tooltip("Choose export image format"));
    if (writers.contains(lastWriter))
        comboImageType.getSelectionModel().select(lastWriter);
    else
        comboImageType.getSelectionModel().selectFirst();
    comboImageType.setMaxWidth(Double.MAX_VALUE);
    GridPane.setHgrow(comboImageType, Priority.ALWAYS);
    pane.add(comboImageType, 1, row++);
    TextArea textArea = new TextArea();
    textArea.setPrefRowCount(2);
    textArea.setEditable(false);
    textArea.setWrapText(true);
    // textArea.setPadding(new Insets(15, 0, 0, 0));
    comboImageType.setOnAction(e -> textArea.setText(((ImageWriter<BufferedImage>) comboImageType.getValue()).getDetails()));
    textArea.setText(((ImageWriter<BufferedImage>) comboImageType.getValue()).getDetails());
    pane.add(textArea, 0, row++, 2, 1);
    var label = new Label("Downsample factor");
    pane.add(label, 0, row);
    TextField tfDownsample = new TextField();
    label.setLabelFor(tfDownsample);
    pane.add(tfDownsample, 1, row++);
    tfDownsample.setTooltip(new Tooltip("Amount to scale down image - choose 1 to export at full resolution (note: for large images this may not succeed for memory reasons)"));
    ObservableDoubleValue downsample = Bindings.createDoubleBinding(() -> {
        try {
            return Double.parseDouble(tfDownsample.getText());
        } catch (NumberFormatException e) {
            return Double.NaN;
        }
    }, tfDownsample.textProperty());
    // Define a sensible limit for non-pyramidal images
    long maxPixels = 10000 * 10000;
    Label labelSize = new Label();
    labelSize.setMinWidth(400);
    labelSize.setTextAlignment(TextAlignment.CENTER);
    labelSize.setContentDisplay(ContentDisplay.CENTER);
    labelSize.setAlignment(Pos.CENTER);
    labelSize.setMaxWidth(Double.MAX_VALUE);
    labelSize.setTooltip(new Tooltip("Estimated size of exported image"));
    pane.add(labelSize, 0, row++, 2, 1);
    labelSize.textProperty().bind(Bindings.createStringBinding(() -> {
        if (!Double.isFinite(downsample.get())) {
            labelSize.setStyle("-fx-text-fill: red;");
            return "Invalid downsample value!  Must be >= 1";
        } else {
            long w = (long) (regionWidth / downsample.get() + 0.5);
            long h = (long) (regionHeight / downsample.get() + 0.5);
            String warning = "";
            var writer = comboImageType.getSelectionModel().getSelectedItem();
            boolean supportsPyramid = writer == null ? false : writer.supportsPyramidal();
            if (!supportsPyramid && w * h > maxPixels) {
                labelSize.setStyle("-fx-text-fill: red;");
                warning = " (too big!)";
            } else if (w < 5 || h < 5) {
                labelSize.setStyle("-fx-text-fill: red;");
                warning = " (too small!)";
            } else
                labelSize.setStyle(null);
            return String.format("Output image size: %d x %d pixels%s", w, h, warning);
        }
    }, downsample, comboImageType.getSelectionModel().selectedIndexProperty()));
    tfDownsample.setText(Double.toString(exportDownsample.get()));
    PaneTools.setMaxWidth(Double.MAX_VALUE, labelSize, textArea, tfDownsample, comboImageType);
    PaneTools.setHGrowPriority(Priority.ALWAYS, labelSize, textArea, tfDownsample, comboImageType);
    pane.setVgap(5);
    pane.setHgap(5);
    if (!Dialogs.showConfirmDialog("Export image region", pane))
        return;
    var writer = comboImageType.getSelectionModel().getSelectedItem();
    boolean supportsPyramid = writer == null ? false : writer.supportsPyramidal();
    int w = (int) (regionWidth / downsample.get() + 0.5);
    int h = (int) (regionHeight / downsample.get() + 0.5);
    if (!supportsPyramid && w * h > maxPixels) {
        Dialogs.showErrorNotification("Export image region", "Requested export region too large - try selecting a smaller region, or applying a higher downsample factor");
        return;
    }
    if (downsample.get() < 1 || !Double.isFinite(downsample.get())) {
        Dialogs.showErrorMessage("Export image region", "Downsample factor must be >= 1!");
        return;
    }
    exportDownsample.set(downsample.get());
    // Now that we know the output, we can create a new server to ensure it is downsampled as the necessary resolution
    if (renderedImage && downsample.get() != server.getDownsampleForResolution(0))
        server = new RenderedImageServer.Builder(viewer).downsamples(downsample.get()).build();
    // selectedImageType.set(comboImageType.getSelectionModel().getSelectedItem());
    // Create RegionRequest
    RegionRequest request = null;
    if (pathObject != null && pathObject.hasROI())
        request = RegionRequest.createInstance(server.getPath(), exportDownsample.get(), roi);
    // Create a sensible default file name, and prompt for the actual name
    String ext = writer.getDefaultExtension();
    String writerName = writer.getName();
    String defaultName = GeneralTools.getNameWithoutExtension(new File(ServerTools.getDisplayableImageName(server)));
    if (roi != null) {
        defaultName = String.format("%s (%s, x=%d, y=%d, w=%d, h=%d)", defaultName, GeneralTools.formatNumber(request.getDownsample(), 2), request.getX(), request.getY(), request.getWidth(), request.getHeight());
    }
    File fileOutput = Dialogs.promptToSaveFile("Export image region", null, defaultName, writerName, ext);
    if (fileOutput == null)
        return;
    try {
        if (request == null) {
            if (exportDownsample.get() == 1.0)
                writer.writeImage(server, fileOutput.getAbsolutePath());
            else
                writer.writeImage(ImageServers.pyramidalize(server, exportDownsample.get()), fileOutput.getAbsolutePath());
        } else
            writer.writeImage(server, request, fileOutput.getAbsolutePath());
        lastWriter = writer;
    } catch (IOException e) {
        Dialogs.showErrorMessage("Export region", e);
    }
}
Also used : ObservableDoubleValue(javafx.beans.value.ObservableDoubleValue) TextArea(javafx.scene.control.TextArea) Label(javafx.scene.control.Label) ImageWriter(qupath.lib.images.writers.ImageWriter) BufferedImage(java.awt.image.BufferedImage) TextField(javafx.scene.control.TextField) GridPane(javafx.scene.layout.GridPane) ComboBox(javafx.scene.control.ComboBox) Tooltip(javafx.scene.control.Tooltip) IOException(java.io.IOException) RectangleROI(qupath.lib.roi.RectangleROI) ROI(qupath.lib.roi.interfaces.ROI) PolygonROI(qupath.lib.roi.PolygonROI) PathObject(qupath.lib.objects.PathObject) RegionRequest(qupath.lib.regions.RegionRequest) File(java.io.File)

Example 2 with RegionRequest

use of qupath.lib.regions.RegionRequest in project qupath by qupath.

the class TMAGridView method initializeData.

private void initializeData(ImageData<BufferedImage> imageData) {
    if (this.imageData != imageData) {
        if (this.imageData != null)
            this.imageData.getHierarchy().removePathObjectListener(this);
        this.imageData = imageData;
        if (imageData != null) {
            imageData.getHierarchy().addPathObjectListener(this);
        }
    }
    if (imageData == null || imageData.getHierarchy().getTMAGrid() == null) {
        model.setImageData(null, Collections.emptyList());
        grid.getItems().clear();
        return;
    }
    // Request all core thumbnails now
    List<TMACoreObject> cores = imageData.getHierarchy().getTMAGrid().getTMACoreList();
    ImageServer<BufferedImage> server = imageData.getServer();
    CountDownLatch latch = new CountDownLatch(cores.size());
    for (TMACoreObject core : cores) {
        ROI roi = core.getROI();
        if (roi != null) {
            qupath.submitShortTask(() -> {
                RegionRequest request = createRegionRequest(core);
                if (cache.containsKey(request)) {
                    latch.countDown();
                    return;
                }
                BufferedImage img;
                try {
                    img = server.readBufferedImage(request);
                } catch (IOException e) {
                    logger.debug("Unable to get tile for " + request, e);
                    latch.countDown();
                    return;
                }
                Image imageNew = SwingFXUtils.toFXImage(img, null);
                if (imageNew != null) {
                    cache.put(request, imageNew);
                // Platform.runLater(() -> updateGridDisplay());
                }
                latch.countDown();
            });
        } else
            latch.countDown();
    }
    long startTime = System.currentTimeMillis();
    try {
        latch.await(10, TimeUnit.SECONDS);
    } catch (InterruptedException e1) {
        if (latch.getCount() > 0)
            logger.warn("Loaded {} cores in 10 seconds", cores.size() - latch.getCount());
    }
    logger.info("Countdown complete in {} seconds", (System.currentTimeMillis() - startTime) / 1000.0);
    model.setImageData(imageData, cores);
    backingList.setAll(cores);
    String m = measurement.getValue();
    sortCores(backingList, model, m, descending.get());
    filteredList.setPredicate(p -> {
        return !(p.isMissing() || Double.isNaN(model.getNumericValue(p, m)));
    });
    grid.getItems().setAll(filteredList);
}
Also used : TMACoreObject(qupath.lib.objects.TMACoreObject) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) BufferedImage(java.awt.image.BufferedImage) Image(javafx.scene.image.Image) ROI(qupath.lib.roi.interfaces.ROI) RegionRequest(qupath.lib.regions.RegionRequest) BufferedImage(java.awt.image.BufferedImage)

Example 3 with RegionRequest

use of qupath.lib.regions.RegionRequest in project qupath by qupath.

the class ContourTracing method traceGeometries.

/**
 * Trace one or more geometries in an image.
 * @param server
 * @param regionRequest optional region defining the area within which geometries should be traced
 * @param clipArea optional clip region, intersected with the created geometries (may be null)
 * @param thresholds min/max thresholds (inclusive) to apply to each channel to generate objects
 * @return
 * @throws IOException
 */
public static Map<Integer, Geometry> traceGeometries(ImageServer<BufferedImage> server, RegionRequest regionRequest, Geometry clipArea, ChannelThreshold... thresholds) throws IOException {
    RegionRequest region = regionRequest;
    if (region == null) {
        if (clipArea == null) {
            region = RegionRequest.createInstance(server, server.getDownsampleForResolution(0));
        } else {
            var env = clipArea.getEnvelopeInternal();
            region = RegionRequest.createInstance(server.getPath(), server.getDownsampleForResolution(0), GeometryTools.envelopToRegion(env, 0, 0));
        }
    } else if (clipArea != null) {
        // Ensure we don't compute more than we need to
        var env = clipArea.getEnvelopeInternal();
        region = region.intersect2D(GeometryTools.envelopToRegion(env, region.getZ(), region.getT()));
    }
    Collection<TileRequest> tiles = server.getTileRequestManager().getTileRequests(region);
    if (thresholds.length == 0 || tiles.isEmpty())
        return Collections.emptyMap();
    // If the region downsample doesn't match the tile requests, the scaling may be off
    // One way to resolve that (without requiring the region to be read in one go) is to generate new tile requests for a pyramidalized server at the correct resolution
    double downsample = region.getDownsample();
    if (Math.abs(tiles.iterator().next().getDownsample() - downsample) > 1e-3) {
        server = ImageServers.pyramidalize(server, downsample);
        tiles = server.getTileRequestManager().getTileRequests(region);
    }
    return traceGeometriesImpl(server, tiles, clipArea, thresholds);
// TODO: Consider restricting parallelization
// int nThreads = Math.min(Math.max(1, Math.max(thresholds.length, tiles.size())), Runtime.getRuntime().availableProcessors());
// var pool = new ForkJoinPool(nThreads);
// var task = pool.submit(() -> traceGeometriesImpl(server, tiles, clipArea, thresholds));
// pool.shutdown();
// try {
// return task.get();
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (ExecutionException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
Also used : TileRequest(qupath.lib.images.servers.TileRequest) RegionRequest(qupath.lib.regions.RegionRequest)

Example 4 with RegionRequest

use of qupath.lib.regions.RegionRequest in project qupath by qupath.

the class EstimateStainVectorsCommand method promptToEstimateStainVectors.

public static void promptToEstimateStainVectors(ImageData<BufferedImage> imageData) {
    if (imageData == null) {
        Dialogs.showNoImageError(TITLE);
        return;
    }
    if (imageData == null || !imageData.isBrightfield() || imageData.getServer() == null || !imageData.getServer().isRGB()) {
        Dialogs.showErrorMessage(TITLE, "No brightfield, RGB image selected!");
        return;
    }
    ColorDeconvolutionStains stains = imageData.getColorDeconvolutionStains();
    if (stains == null || !stains.getStain(3).isResidual()) {
        Dialogs.showErrorMessage(TITLE, "Sorry, stain editing is only possible for brightfield, RGB images with 2 stains");
        return;
    }
    PathObject pathObject = imageData.getHierarchy().getSelectionModel().getSelectedObject();
    ROI roi = pathObject == null ? null : pathObject.getROI();
    if (roi == null)
        roi = ROIs.createRectangleROI(0, 0, imageData.getServer().getWidth(), imageData.getServer().getHeight(), ImagePlane.getDefaultPlane());
    double downsample = Math.max(1, Math.sqrt((roi.getBoundsWidth() * roi.getBoundsHeight()) / MAX_PIXELS));
    RegionRequest request = RegionRequest.createInstance(imageData.getServerPath(), downsample, roi);
    BufferedImage img = null;
    try {
        img = imageData.getServer().readBufferedImage(request);
    } catch (IOException e) {
        Dialogs.showErrorMessage("Estimate stain vectors", e);
        logger.error("Unable to obtain pixels for " + request.toString(), e);
    }
    // Apply small amount of smoothing to reduce compression artefacts
    img = EstimateStainVectors.smoothImage(img);
    // Check modes for background
    int[] rgb = img.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth());
    int[] rgbMode = EstimateStainVectors.getModeRGB(rgb);
    int rMax = rgbMode[0];
    int gMax = rgbMode[1];
    int bMax = rgbMode[2];
    // Check if the background values may need to be changed
    if (rMax != stains.getMaxRed() || gMax != stains.getMaxGreen() || bMax != stains.getMaxBlue()) {
        DialogButton response = Dialogs.showYesNoCancelDialog(TITLE, String.format("Modal RGB values %d, %d, %d do not match current background values - do you want to use the modal values?", rMax, gMax, bMax));
        if (response == DialogButton.CANCEL)
            return;
        else if (response == DialogButton.YES) {
            stains = stains.changeMaxValues(rMax, gMax, bMax);
            imageData.setColorDeconvolutionStains(stains);
        }
    }
    ColorDeconvolutionStains stainsUpdated = null;
    logger.info("Requesting region for stain vector editing: ", request);
    try {
        stainsUpdated = showStainEditor(img, stains);
    } catch (Exception e) {
        Dialogs.showErrorMessage(TITLE, "Error with stain estimation: " + e.getLocalizedMessage());
        logger.error("{}", e.getLocalizedMessage(), e);
        // JOptionPane.showMessageDialog(qupath.getFrame(), "Error with stain estimation: " + e.getLocalizedMessage(), "Estimate stain vectors", JOptionPane.ERROR_MESSAGE, null);
        return;
    }
    if (!stains.equals(stainsUpdated)) {
        String suggestedName;
        String collectiveNameBefore = stainsUpdated.getName();
        if (collectiveNameBefore.endsWith("default"))
            suggestedName = collectiveNameBefore.substring(0, collectiveNameBefore.lastIndexOf("default")) + "estimated";
        else
            suggestedName = collectiveNameBefore;
        String newName = Dialogs.showInputDialog(TITLE, "Set name for stain vectors", suggestedName);
        if (newName == null)
            return;
        if (!newName.isBlank())
            stainsUpdated = stainsUpdated.changeName(newName);
        imageData.setColorDeconvolutionStains(stainsUpdated);
    }
}
Also used : DialogButton(qupath.lib.gui.dialogs.Dialogs.DialogButton) PathObject(qupath.lib.objects.PathObject) IOException(java.io.IOException) ROI(qupath.lib.roi.interfaces.ROI) RegionRequest(qupath.lib.regions.RegionRequest) BufferedImage(java.awt.image.BufferedImage) IOException(java.io.IOException) ColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains)

Example 5 with RegionRequest

use of qupath.lib.regions.RegionRequest in project qupath by qupath.

the class TMADataIO method writeTMAData.

/**
 * Write TMA data in a human-readable (and viewable) way, with JPEGs and TXT/CSV files.
 *
 * @param file
 * @param imageData
 * @param overlayOptions
 * @param downsampleFactor The downsample factor used for the TMA cores. If NaN, an automatic downsample value will be selected (&gt;= 1).  If &lt;= 0, no cores are exported.
 */
public static void writeTMAData(File file, final ImageData<BufferedImage> imageData, OverlayOptions overlayOptions, final double downsampleFactor) {
    if (imageData == null || imageData.getHierarchy() == null || imageData.getHierarchy().getTMAGrid() == null) {
        logger.error("No TMA data available to save!");
        return;
    }
    final ImageServer<BufferedImage> server = imageData.getServer();
    String coreExt = imageData.getServer().isRGB() ? ".jpg" : ".tif";
    if (file == null) {
        file = Dialogs.promptToSaveFile("Save TMA data", null, ServerTools.getDisplayableImageName(server), "TMA data", "qptma");
        if (file == null)
            return;
    } else if (file.isDirectory() || (!file.exists() && file.getAbsolutePath().endsWith(File.pathSeparator))) {
        // Put inside the specified directory
        file = new File(file, ServerTools.getDisplayableImageName(server) + TMA_DEARRAYING_DATA_EXTENSION);
        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();
    }
    final File dirData = new File(file + ".data");
    if (!dirData.exists())
        dirData.mkdir();
    // Write basic file info
    String delimiter = "\t";
    TMAGrid tmaGrid = imageData.getHierarchy().getTMAGrid();
    try {
        PrintWriter writer = new PrintWriter(file);
        writer.println(server.getPath());
        writer.println(ServerTools.getDisplayableImageName(server));
        writer.println();
        writer.println("TMA grid width: " + tmaGrid.getGridWidth());
        writer.println("TMA grid height: " + tmaGrid.getGridHeight());
        writer.println("Core name" + delimiter + "X" + delimiter + "Y" + delimiter + "Width" + delimiter + "Height" + delimiter + "Present" + delimiter + TMACoreObject.KEY_UNIQUE_ID);
        for (int row = 0; row < tmaGrid.getGridHeight(); row++) {
            for (int col = 0; col < tmaGrid.getGridWidth(); col++) {
                TMACoreObject core = tmaGrid.getTMACore(row, col);
                if (!core.hasROI()) {
                    writer.println(core.getName() + delimiter + delimiter + delimiter + delimiter);
                    continue;
                }
                ROI pathROI = core.getROI();
                int x = (int) pathROI.getBoundsX();
                int y = (int) pathROI.getBoundsY();
                int w = (int) Math.ceil(pathROI.getBoundsWidth());
                int h = (int) Math.ceil(pathROI.getBoundsHeight());
                String id = core.getUniqueID() == null ? "" : core.getUniqueID();
                writer.println(core.getName() + delimiter + x + delimiter + y + delimiter + w + delimiter + h + delimiter + !core.isMissing() + delimiter + id);
            }
        }
        writer.close();
    } catch (Exception e) {
        logger.error("Error writing TMA data: " + e.getLocalizedMessage(), e);
        return;
    }
    // Save the summary results
    ObservableMeasurementTableData tableData = new ObservableMeasurementTableData();
    tableData.setImageData(imageData, tmaGrid.getTMACoreList());
    SummaryMeasurementTableCommand.saveTableModel(tableData, new File(dirData, "TMA results - " + ServerTools.getDisplayableImageName(server) + ".txt"), Collections.emptyList());
    boolean outputCoreImages = Double.isNaN(downsampleFactor) || downsampleFactor > 0;
    if (outputCoreImages) {
        // Create new overlay options, if we don't have some already
        if (overlayOptions == null) {
            overlayOptions = new OverlayOptions();
            overlayOptions.setFillDetections(true);
        }
        final OverlayOptions options = overlayOptions;
        // Write an overall TMA map (for quickly checking if the dearraying is ok)
        File fileTMAMap = new File(dirData, "TMA map - " + ServerTools.getDisplayableImageName(server) + ".jpg");
        double downsampleThumbnail = Math.max(1, (double) Math.max(server.getWidth(), server.getHeight()) / 1024);
        RegionRequest request = RegionRequest.createInstance(server.getPath(), downsampleThumbnail, 0, 0, server.getWidth(), server.getHeight());
        OverlayOptions optionsThumbnail = new OverlayOptions();
        optionsThumbnail.setShowTMAGrid(true);
        optionsThumbnail.setShowGrid(false);
        optionsThumbnail.setShowAnnotations(false);
        optionsThumbnail.setShowDetections(false);
        try {
            var renderedServer = new RenderedImageServer.Builder(imageData).layers(new TMAGridOverlay(overlayOptions)).downsamples(downsampleThumbnail).build();
            ImageWriterTools.writeImageRegion(renderedServer, request, fileTMAMap.getAbsolutePath());
        // ImageWriters.writeImageRegionWithOverlay(imageData.getServer(), Collections.singletonList(new TMAGridOverlay(overlayOptions, imageData)), request, fileTMAMap.getAbsolutePath());
        } catch (IOException e) {
            logger.warn("Unable to write image overview: " + e.getLocalizedMessage(), e);
        }
        final double downsample = Double.isNaN(downsampleFactor) ? (server.getPixelCalibration().hasPixelSizeMicrons() ? ServerTools.getDownsampleFactor(server, preferredExportPixelSizeMicrons) : 1) : downsampleFactor;
        // Creating a plugin makes it possible to parallelize & show progress easily
        var renderedImageServer = new RenderedImageServer.Builder(imageData).layers(new HierarchyOverlay(null, options, imageData)).downsamples(downsample).build();
        ExportCoresPlugin plugin = new ExportCoresPlugin(dirData, renderedImageServer, downsample, coreExt);
        PluginRunner<BufferedImage> runner;
        var qupath = QuPathGUI.getInstance();
        if (qupath == null || qupath.getImageData() != imageData) {
            runner = new CommandLinePluginRunner<>(imageData);
            plugin.runPlugin(runner, null);
        } else {
            try {
                qupath.runPlugin(plugin, null, false);
            } catch (Exception e) {
                logger.error("Error writing TMA data: " + e.getLocalizedMessage(), e);
            }
        // new Thread(() -> qupath.runPlugin(plugin, null, false)).start();
        // runner = new PluginRunnerFX(QuPathGUI.getInstance());
        // new Thread(() -> plugin.runPlugin(runner, null)).start();
        }
    }
}
Also used : TMACoreObject(qupath.lib.objects.TMACoreObject) DefaultTMAGrid(qupath.lib.objects.hierarchy.DefaultTMAGrid) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) IOException(java.io.IOException) ROI(qupath.lib.roi.interfaces.ROI) RenderedImageServer(qupath.lib.gui.images.servers.RenderedImageServer) BufferedImage(java.awt.image.BufferedImage) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) HierarchyOverlay(qupath.lib.gui.viewer.overlays.HierarchyOverlay) ObservableMeasurementTableData(qupath.lib.gui.measure.ObservableMeasurementTableData) OverlayOptions(qupath.lib.gui.viewer.OverlayOptions) File(java.io.File) RegionRequest(qupath.lib.regions.RegionRequest) TMAGridOverlay(qupath.lib.gui.viewer.overlays.TMAGridOverlay) PrintWriter(java.io.PrintWriter)

Aggregations

RegionRequest (qupath.lib.regions.RegionRequest)37 BufferedImage (java.awt.image.BufferedImage)29 IOException (java.io.IOException)18 ROI (qupath.lib.roi.interfaces.ROI)15 ArrayList (java.util.ArrayList)13 PathObject (qupath.lib.objects.PathObject)10 List (java.util.List)9 Collection (java.util.Collection)8 Collectors (java.util.stream.Collectors)8 PixelCalibration (qupath.lib.images.servers.PixelCalibration)8 Collections (java.util.Collections)7 TMACoreObject (qupath.lib.objects.TMACoreObject)7 Graphics2D (java.awt.Graphics2D)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 LinkedHashMap (java.util.LinkedHashMap)5 Map (java.util.Map)5