Search in sources :

Example 1 with DialogButton

use of qupath.lib.gui.dialogs.Dialogs.DialogButton 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 2 with DialogButton

use of qupath.lib.gui.dialogs.Dialogs.DialogButton in project qupath by qupath.

the class LegacyDetectionClassifierCommand method run.

@Override
public void run() {
    if (dialog == null) {
        dialog = new Stage();
        if (qupath != null)
            dialog.initOwner(qupath.getStage());
        dialog.setTitle(name);
        BorderPane pane = new BorderPane();
        RTreesClassifier defaultClassifier = new RTreesClassifier();
        List<OpenCvClassifier<?>> classifierList = Arrays.asList(defaultClassifier, new DTreesClassifier(), new BoostClassifier(), new BayesClassifier(), new KNearestClassifier(), new SVMClassifier(), new NeuralNetworksClassifier());
        Collections.sort(classifierList, (c1, c2) -> c1.getName().compareTo(c2.getName()));
        panel = new ClassifierBuilderPane<>(qupath, classifierList, defaultClassifier);
        pane.setCenter(panel.getPane());
        ScrollPane scrollPane = new ScrollPane(pane);
        scrollPane.setFitToWidth(true);
        scrollPane.setFitToHeight(true);
        dialog.setScene(new Scene(scrollPane));
    }
    dialog.setOnCloseRequest(e -> {
        // If we don't have a classifier yet, just remove completely
        if (panel.getSelectedFeatures().isEmpty()) {
            resetPanel();
            return;
        }
        // If we have a classifier, give option to hide
        DialogButton button = Dialogs.showYesNoCancelDialog("Classifier builder", "Retain classifier for later use?");
        if (button == DialogButton.CANCEL)
            e.consume();
        else if (button == DialogButton.NO) {
            resetPanel();
        }
    });
    dialog.show();
    dialog.setMinWidth(dialog.getWidth());
    if (dialog.getHeight() < javafx.stage.Screen.getPrimary().getVisualBounds().getHeight()) {
        dialog.setMinHeight(dialog.getHeight() / 2);
    }
// if (dialog.getHeight() < javafx.stage.Screen.getPrimary().getVisualBounds().getHeight())
// dialog.setResizable(false);
}
Also used : BoostClassifier(qupath.opencv.classify.BoostClassifier) DialogButton(qupath.lib.gui.dialogs.Dialogs.DialogButton) BorderPane(javafx.scene.layout.BorderPane) DTreesClassifier(qupath.opencv.classify.DTreesClassifier) KNearestClassifier(qupath.opencv.classify.KNearestClassifier) Scene(javafx.scene.Scene) RTreesClassifier(qupath.opencv.classify.RTreesClassifier) BayesClassifier(qupath.opencv.classify.BayesClassifier) SVMClassifier(qupath.opencv.classify.SVMClassifier) NeuralNetworksClassifier(qupath.opencv.classify.NeuralNetworksClassifier) ScrollPane(javafx.scene.control.ScrollPane) Stage(javafx.stage.Stage) OpenCvClassifier(qupath.opencv.classify.OpenCvClassifier)

Example 3 with DialogButton

use of qupath.lib.gui.dialogs.Dialogs.DialogButton in project qupath by qupath.

the class DefaultScriptEditor method promptToClose.

boolean promptToClose(final ScriptTab tab) {
    int ind = listScripts.getItems().indexOf(tab);
    if (ind < 0)
        return false;
    // Check if we need to save
    if (tab.isModifiedProperty().get() && tab.hasScript()) {
        // TODO: Consider that this previously had a different parent for the dialog... and probably should
        DialogButton option = Dialogs.showYesNoCancelDialog("Close " + tab.getName(), String.format("Save %s before closing?", tab.getName()));
        if (option == DialogButton.CANCEL)
            return false;
        if (option == DialogButton.YES) {
            if (!save(tab, false))
                return false;
        }
    }
    // Update selection, or close window if all scripts have been closed
    listScripts.getItems().remove(ind);
    if (ind >= listScripts.getItems().size())
        ind--;
    if (ind < 0) {
        dialog.close();
        dialog = null;
    } else
        listScripts.getSelectionModel().select(ind);
    return true;
}
Also used : DialogButton(qupath.lib.gui.dialogs.Dialogs.DialogButton)

Example 4 with DialogButton

use of qupath.lib.gui.dialogs.Dialogs.DialogButton in project qupath by qupath.

the class QuPathGUI method promptToSaveChangesOrCancel.

/**
 * Show a prompt to save changes for an ImageData.
 * <p>
 * Note the return value indicates whether the user cancelled or not, rather than whether the data
 * was saved or not.
 *
 * @param dialogTitle
 * @param imageData
 * @return true if the prompt 'succeeded' (i.e. user chose 'Yes' or 'No'), false if it was cancelled.
 */
private boolean promptToSaveChangesOrCancel(String dialogTitle, ImageData<BufferedImage> imageData) {
    var project = getProject();
    var entry = project == null ? null : project.getEntry(imageData);
    File filePrevious = null;
    if (entry == null) {
        String lastPath = imageData.getLastSavedPath();
        filePrevious = lastPath == null ? null : new File(lastPath);
    }
    DialogButton response = DialogButton.YES;
    if (imageData.isChanged()) {
        response = Dialogs.showYesNoCancelDialog(dialogTitle, "Save changes to " + ServerTools.getDisplayableImageName(imageData.getServer()) + "?");
    }
    if (response == DialogButton.CANCEL)
        return false;
    if (response == DialogButton.YES) {
        if (filePrevious == null && entry == null) {
            filePrevious = Dialogs.promptToSaveFile("Save image data", filePrevious, ServerTools.getDisplayableImageName(imageData.getServer()), "QuPath Serialized Data", PathPrefs.getSerializationExtension());
            if (filePrevious == null)
                return false;
        }
        try {
            if (entry != null) {
                entry.saveImageData(imageData);
                // Should make sure we save the project in case metadata has changed as well
                project.syncChanges();
            } else
                PathIO.writeImageData(filePrevious, imageData);
        } catch (IOException e) {
            Dialogs.showErrorMessage("Save ImageData", e);
        }
    }
    return true;
}
Also used : DialogButton(qupath.lib.gui.dialogs.Dialogs.DialogButton) IOException(java.io.IOException) File(java.io.File)

Example 5 with DialogButton

use of qupath.lib.gui.dialogs.Dialogs.DialogButton in project qupath by qupath.

the class RigidObjectEditorCommand method commitChanges.

private void commitChanges(final boolean ignoreChanges) {
    if (this.originalObject == null)
        return;
    // PathObject pathObject = null;
    if (!ignoreChanges) {
        DialogButton option = Dialogs.showYesNoCancelDialog("Affine object editing", "Confirm object changes?");
        if (option == DialogButton.CANCEL)
            return;
        if (option == DialogButton.NO) {
            for (Entry<PathObject, ROI> entry : originalObjectROIs.entrySet()) ((PathROIObject) entry.getKey()).setROI(entry.getValue());
        } else {
            var transform = transformer.transform;
            var values = transform.getMatrixEntries();
            logger.info("Applied ROI transform: {}", String.format("\n %f, %f, %f,\n%f, %f, %f", values[0], values[1], values[2], values[3], values[4], values[5]));
            // Apply clipping now
            for (Entry<PathObject, ROI> entry : originalObjectROIs.entrySet()) {
                ROI roiTransformed = transformer.getTransformedROI(entry.getValue(), true);
                ((PathROIObject) entry.getKey()).setROI(roiTransformed);
            }
            viewer.getHierarchy().fireHierarchyChangedEvent(this, originalObject);
        }
    }
    // Update the mode if the viewer is still active
    qupath.setToolSwitchingEnabled(true);
    if (viewer == qupath.getViewer())
        viewer.setActiveTool(qupath.getSelectedTool());
    viewer.getView().removeEventHandler(MouseEvent.ANY, mouseListener);
    viewer.getCustomOverlayLayers().remove(overlay);
    viewer.removeViewerListener(this);
    // if (pathObject != null)
    // viewer.getHierarchy().addPathObject(pathObject, true);
    // // Ensure the object is selected
    // viewer.setSelectedObject(pathObject);
    viewer = null;
    overlay = null;
    originalObjectROIs.clear();
    originalObject = null;
    transformer = null;
}
Also used : DialogButton(qupath.lib.gui.dialogs.Dialogs.DialogButton) PathObject(qupath.lib.objects.PathObject) PathROIObject(qupath.lib.objects.PathROIObject) PolylineROI(qupath.lib.roi.PolylineROI) ROI(qupath.lib.roi.interfaces.ROI)

Aggregations

DialogButton (qupath.lib.gui.dialogs.Dialogs.DialogButton)5 IOException (java.io.IOException)2 PathObject (qupath.lib.objects.PathObject)2 ROI (qupath.lib.roi.interfaces.ROI)2 BufferedImage (java.awt.image.BufferedImage)1 File (java.io.File)1 Scene (javafx.scene.Scene)1 ScrollPane (javafx.scene.control.ScrollPane)1 BorderPane (javafx.scene.layout.BorderPane)1 Stage (javafx.stage.Stage)1 ColorDeconvolutionStains (qupath.lib.color.ColorDeconvolutionStains)1 PathROIObject (qupath.lib.objects.PathROIObject)1 RegionRequest (qupath.lib.regions.RegionRequest)1 PolylineROI (qupath.lib.roi.PolylineROI)1 BayesClassifier (qupath.opencv.classify.BayesClassifier)1 BoostClassifier (qupath.opencv.classify.BoostClassifier)1 DTreesClassifier (qupath.opencv.classify.DTreesClassifier)1 KNearestClassifier (qupath.opencv.classify.KNearestClassifier)1 NeuralNetworksClassifier (qupath.opencv.classify.NeuralNetworksClassifier)1 OpenCvClassifier (qupath.opencv.classify.OpenCvClassifier)1