Search in sources :

Example 1 with UriResource

use of qupath.lib.io.UriResource in project qupath by qupath.

the class QP method loadObjectClassifier.

/**
 * Load an object classifier for a project or file path.
 *
 * @param names the names of the classifier within the current project, or file paths to a classifier to load from disk.
 * 				If more than one name is provided, a composite classifier is created (applying each classifier in sequence).
 * @return the requested {@link ObjectClassifier}
 * @throws IllegalArgumentException if the classifier cannot be found
 */
public static ObjectClassifier<BufferedImage> loadObjectClassifier(String... names) throws IllegalArgumentException {
    var project = getProject();
    List<ObjectClassifier<BufferedImage>> classifiers = new ArrayList<>();
    for (String name : names) {
        ObjectClassifier<BufferedImage> classifier = null;
        Exception exception = null;
        if (project != null) {
            try {
                var objectClassifiers = project.getObjectClassifiers();
                if (objectClassifiers.contains(name))
                    classifier = objectClassifiers.get(name);
            } catch (Exception e) {
                exception = e;
                logger.debug("Object classifier '{}' not found in project", name);
            }
        }
        if (classifier == null) {
            try {
                var path = Paths.get(name);
                if (Files.exists(path))
                    classifier = ObjectClassifiers.readClassifier(path);
            } catch (Exception e) {
                exception = e;
                logger.debug("Object classifier '{}' cannot be read from file", name);
            }
        }
        if (classifier == null) {
            throw new IllegalArgumentException("Unable to find object classifier " + name, exception);
        }
        // Try to fix URIs, if we can
        if (classifier instanceof UriResource) {
            UriUpdater.fixUris((UriResource) classifier, project);
        }
        if (names.length == 1)
            return classifier;
        else
            classifiers.add(classifier);
    }
    return ObjectClassifiers.createCompositeClassifier(classifiers);
}
Also used : UriResource(qupath.lib.io.UriResource) PathObjectClassifier(qupath.lib.classifiers.PathObjectClassifier) ObjectClassifier(qupath.lib.classifiers.object.ObjectClassifier) ArrayList(java.util.ArrayList) BufferedImage(java.awt.image.BufferedImage) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) NoSuchElementException(java.util.NoSuchElementException)

Example 2 with UriResource

use of qupath.lib.io.UriResource in project qupath by qupath.

the class QP method loadPixelClassifier.

/**
 * Load a pixel classifier for a project or file path.
 *
 * @param name the name of the classifier within the current project, or file path to a classifier to load from disk.
 * @return the requested {@link PixelClassifier}
 * @throws IllegalArgumentException if the classifier cannot be found
 */
public static PixelClassifier loadPixelClassifier(String name) throws IllegalArgumentException {
    var project = getProject();
    Exception exception = null;
    PixelClassifier pixelClassifier = null;
    if (project != null) {
        try {
            var pixelClassifiers = project.getPixelClassifiers();
            if (pixelClassifiers.contains(name))
                pixelClassifier = pixelClassifiers.get(name);
        } catch (Exception e) {
            exception = e;
            logger.debug("Pixel classifier '{}' not found in project", name);
        }
    }
    try {
        var path = Paths.get(name);
        if (Files.exists(path))
            pixelClassifier = PixelClassifiers.readClassifier(path);
    } catch (Exception e) {
        exception = e;
        logger.debug("Pixel classifier '{}' cannot be read from file", name);
    }
    if (pixelClassifier == null)
        throw new IllegalArgumentException("Unable to find pixel classifier " + name, exception);
    // Fix URIs if we need to
    if (pixelClassifier instanceof UriResource) {
        UriUpdater.fixUris((UriResource) pixelClassifier, project);
    }
    return pixelClassifier;
}
Also used : UriResource(qupath.lib.io.UriResource) PixelClassifier(qupath.lib.classifiers.pixel.PixelClassifier) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) NoSuchElementException(java.util.NoSuchElementException)

Example 3 with UriResource

use of qupath.lib.io.UriResource in project qupath by qupath.

the class LoadResourceCommand method run.

@Override
public void run() {
    String title = resourceType.getDialogTitle();
    var cachedServers = new WeakHashMap<ImageData<BufferedImage>, ImageServer<BufferedImage>>();
    var overlay = PixelClassificationOverlay.create(qupath.getOverlayOptions(), cachedServers, new ColorModelRenderer(null));
    overlay.setMaxThreads(nThreads);
    for (var viewer : qupath.getViewers()) viewer.setCustomPixelLayerOverlay(overlay);
    var comboClassifiers = new ComboBox<String>();
    try {
        updateAvailableItems(comboClassifiers.getItems());
    } catch (IOException e) {
        logger.error(e.getLocalizedMessage(), e);
    }
    var selectedResource = Bindings.createObjectBinding(() -> {
        String name = comboClassifiers.getSelectionModel().getSelectedItem();
        cachedServers.clear();
        if (name != null) {
            try {
                var project = qupath.getProject();
                var manager = resourceType.getManager(project);
                S resource;
                if (manager != null && manager.contains(name))
                    resource = manager.get(name);
                else
                    resource = extras.get(name);
                if (resource instanceof UriResource) {
                    UriUpdater.fixUris((UriResource) resource, project);
                }
                return resource;
            } catch (Exception ex) {
                // TODO: Investigate why this is triggered twice
                Dialogs.showErrorNotification(resourceType.getDialogTitle(), ex);
            }
        }
        return null;
    }, comboClassifiers.getSelectionModel().selectedItemProperty());
    var label = new Label(resourceType.choosePrompt());
    label.setLabelFor(comboClassifiers);
    selectedResource.addListener((v, o, n) -> {
        cachedServers.clear();
        updateServers(n, cachedServers);
    });
    // Add file chooser
    var menu = new ContextMenu();
    var miLoadClassifier = new MenuItem("Import from files");
    miLoadClassifier.setOnAction(e -> {
        List<File> files = Dialogs.promptForMultipleFiles(title, null, resourceType.filePrompt(), "json");
        if (files == null || files.isEmpty())
            return;
        try {
            addExternalJson(files, resourceType.getManager(qupath.getProject()), extras);
            updateAvailableItems(comboClassifiers.getItems());
        } catch (IOException ex) {
            Dialogs.showErrorMessage(title, ex);
        }
    });
    var miOpenAsText = new MenuItem("Show as text");
    miOpenAsText.setOnAction(e -> {
        var name = comboClassifiers.getSelectionModel().getSelectedItem();
        var resource = selectedResource.get();
        if (resource == null)
            return;
        try {
            // Pass the resource class, since it can be required for including the appropriate JSON properties
            var json = GsonTools.getInstance(true).toJson(resource, resourceType.getResourceClass());
            if (!name.endsWith(".json"))
                name = name + ".json";
            // Show in script editor if possible; this may include better formatting and syntax highlighting
            var scriptEditor = qupath == null ? null : qupath.getScriptEditor();
            if (scriptEditor != null)
                scriptEditor.showScript(name, json);
            else
                Dialogs.showTextWindow(qupath.getStage(), name, json, Modality.NONE, false);
        } catch (Exception ex) {
            Dialogs.showErrorMessage("Show model as text", "Unable to create a text representation of '" + name + "', sorry!");
        }
    });
    miOpenAsText.disableProperty().bind(selectedResource.isNull());
    // Enable setting number of threads
    var miThreads = new MenuItem("Set parallel threads");
    miThreads.setOnAction(e -> {
        var params = new ParameterList().addIntParameter("nThreads", "Number of parallel threads", nThreads, null, "Number of threads to use for live prediction");
        if (!Dialogs.showParameterDialog("Set parallel threads", params))
            return;
        // var result = Dialogs.showInputDialog("Set parallel threads", "Number of threads to use for live prediction", (double)nThreads);
        var val = params.getIntParameterValue("nThreads");
        if (val == nThreads)
            return;
        if (val < 0)
            nThreads = PathPrefs.numCommandThreadsProperty().get();
        else
            nThreads = Math.max(1, val);
        if (overlay != null)
            overlay.setMaxThreads(nThreads);
    });
    menu.getItems().addAll(miLoadClassifier, miOpenAsText, new SeparatorMenuItem(), miThreads);
    var btnLoadExistingClassifier = GuiTools.createMoreButton(menu, Side.RIGHT);
    var classifierName = new SimpleStringProperty(null);
    classifierName.bind(comboClassifiers.getSelectionModel().selectedItemProperty());
    var pane = new GridPane();
    pane.setPadding(new Insets(10.0));
    pane.setHgap(5);
    pane.setVgap(10);
    pane.setPrefWidth(350.0);
    int row = 0;
    PaneTools.addGridRow(pane, row++, 0, "Choose model to apply to the current image", label, comboClassifiers, btnLoadExistingClassifier);
    PaneTools.setToExpandGridPaneWidth(comboClassifiers);
    if (resourceType.getResourceClass().equals(PixelClassifier.class)) {
        var labelRegion = new Label("Region");
        var comboRegionFilter = PixelClassifierUI.createRegionFilterCombo(qupath.getOverlayOptions());
        @SuppressWarnings("unchecked") var tilePane = PixelClassifierUI.createPixelClassifierButtons(qupath.imageDataProperty(), (ObjectExpression<PixelClassifier>) selectedResource, classifierName);
        PaneTools.addGridRow(pane, row++, 0, "Control where the pixel classification is applied during preview", labelRegion, comboRegionFilter, comboRegionFilter);
        PaneTools.addGridRow(pane, row++, 0, "Apply pixel classification", tilePane, tilePane, tilePane);
        PaneTools.setToExpandGridPaneWidth(tilePane);
    } else if (resourceType.getResourceClass().equals(DensityMapBuilder.class)) {
        @SuppressWarnings("unchecked") var buttonPane = DensityMapUI.createButtonPane(qupath, qupath.imageDataProperty(), (ObjectExpression<DensityMapBuilder>) selectedResource, classifierName, Bindings.createObjectBinding(() -> overlay), false);
        PaneTools.addGridRow(pane, row++, 0, null, buttonPane, buttonPane, buttonPane);
        PaneTools.setToExpandGridPaneWidth(buttonPane);
    }
    // Handle drag and drop
    pane.setOnDragOver(e -> {
        e.acceptTransferModes(TransferMode.COPY);
        e.consume();
    });
    pane.setOnDragDropped(e -> {
        logger.trace("File(s) dragged onto pane");
        Dragboard dragboard = e.getDragboard();
        if (dragboard.hasFiles()) {
            try {
                addExternalJson(dragboard.getFiles(), resourceType.getManager(qupath.getProject()), extras);
                updateAvailableItems(comboClassifiers.getItems());
            } catch (Exception ex) {
                Dialogs.showErrorMessage(title, ex);
            }
        }
    });
    var stage = new Stage();
    stage.setTitle(title);
    stage.setScene(new Scene(pane));
    stage.initOwner(qupath.getStage());
    stage.sizeToScene();
    stage.setResizable(false);
    stage.show();
    stage.setOnHiding(e -> {
        if (overlay != null)
            overlay.stop();
        logger.debug("Resetting overlay");
        for (var viewer : qupath.getViewers()) {
            if (viewer.getCustomPixelLayerOverlay() == overlay)
                viewer.resetCustomPixelLayerOverlay();
        }
    });
    stage.focusedProperty().addListener((v, o, n) -> {
        if (n && overlay != null) {
            for (var viewer : qupath.getViewers()) viewer.setCustomPixelLayerOverlay(overlay);
        }
        // Make sure we have all the servers we need - but don't reset existing ones
        updateServers(selectedResource.get(), cachedServers);
    });
    overlay.setLivePrediction(true);
}
Also used : UriResource(qupath.lib.io.UriResource) Insets(javafx.geometry.Insets) Label(javafx.scene.control.Label) ContextMenu(javafx.scene.control.ContextMenu) BufferedImage(java.awt.image.BufferedImage) Stage(javafx.stage.Stage) Dragboard(javafx.scene.input.Dragboard) GridPane(javafx.scene.layout.GridPane) ComboBox(javafx.scene.control.ComboBox) DensityMapBuilder(qupath.lib.analysis.heatmaps.DensityMaps.DensityMapBuilder) MenuItem(javafx.scene.control.MenuItem) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) IOException(java.io.IOException) SimpleStringProperty(javafx.beans.property.SimpleStringProperty) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) Scene(javafx.scene.Scene) IOException(java.io.IOException) ColorModelRenderer(qupath.lib.gui.images.stores.ColorModelRenderer) PixelClassifier(qupath.lib.classifiers.pixel.PixelClassifier) ParameterList(qupath.lib.plugins.parameters.ParameterList) File(java.io.File) ObjectExpression(javafx.beans.binding.ObjectExpression) WeakHashMap(java.util.WeakHashMap)

Aggregations

IOException (java.io.IOException)3 UriResource (qupath.lib.io.UriResource)3 BufferedImage (java.awt.image.BufferedImage)2 FileNotFoundException (java.io.FileNotFoundException)2 NoSuchElementException (java.util.NoSuchElementException)2 PixelClassifier (qupath.lib.classifiers.pixel.PixelClassifier)2 File (java.io.File)1 ArrayList (java.util.ArrayList)1 WeakHashMap (java.util.WeakHashMap)1 ObjectExpression (javafx.beans.binding.ObjectExpression)1 SimpleStringProperty (javafx.beans.property.SimpleStringProperty)1 Insets (javafx.geometry.Insets)1 Scene (javafx.scene.Scene)1 ComboBox (javafx.scene.control.ComboBox)1 ContextMenu (javafx.scene.control.ContextMenu)1 Label (javafx.scene.control.Label)1 MenuItem (javafx.scene.control.MenuItem)1 SeparatorMenuItem (javafx.scene.control.SeparatorMenuItem)1 Dragboard (javafx.scene.input.Dragboard)1 GridPane (javafx.scene.layout.GridPane)1