Search in sources :

Example 1 with BooleanParameter

use of qupath.lib.plugins.parameters.BooleanParameter in project qupath by qupath.

the class PixelClassifierUI method promptToCreateObjects.

/**
 * Prompt the user to create objects directly from the pixels of an {@link ImageServer}.
 * Often, the {@link ImageServer} has been created by applying a {@link PixelClassifier}.
 *
 * @param imageData the {@link ImageData} to which objects should be added
 * @param classifier the {@link ImageServer} used to generate objects
 * @param classifierName the name of the classifier; if not null and the command runs to completion, it will be logged in the history
 * 						 workflow of the {@link ImageData} for later scripting.
 * @return true if changes were made, false otherwise
 */
public static boolean promptToCreateObjects(ImageData<BufferedImage> imageData, PixelClassifier classifier, String classifierName) {
    Objects.requireNonNull(imageData);
    Objects.requireNonNull(classifier);
    // Check what is selected
    List<SelectionChoice> choices = buildChoiceList(imageData.getHierarchy(), SelectionChoice.FULL_IMAGE, SelectionChoice.CURRENT_SELECTION, SelectionChoice.ANNOTATIONS, SelectionChoice.TMA);
    SelectionChoice defaultChoice;
    if (choices.contains(SelectionChoice.CURRENT_SELECTION))
        defaultChoice = SelectionChoice.CURRENT_SELECTION;
    else if (choices.contains(SelectionChoice.ANNOTATIONS))
        defaultChoice = SelectionChoice.ANNOTATIONS;
    else
        defaultChoice = choices.get(0);
    var parentChoice = Dialogs.showChoiceDialog("Pixel classifier", "Choose parent objects", choices, defaultChoice);
    if (parentChoice == null)
        return false;
    var outputObjectTypes = Arrays.asList("Annotation", "Detection");
    // To avoid confusing the user unnecessarily, if we *only* have ignored classes then set default for includeIgnored to true
    var labels = classifier.getMetadata().getClassificationLabels();
    boolean allIgnored = !labels.isEmpty() && labels.values().stream().allMatch(p -> p == null || PathClassTools.isIgnoredClass(p));
    boolean includeIgnored = allIgnored;
    var cal = imageData.getServer().getPixelCalibration();
    var units = cal.unitsMatch2D() ? cal.getPixelWidthUnit() + "^2" : cal.getPixelWidthUnit() + "x" + cal.getPixelHeightUnit();
    ParameterList params;
    if (lastCreateObjectParams != null) {
        params = lastCreateObjectParams.duplicate();
        params.setHiddenParameters(false, params.getKeyValueParameters(true).keySet().toArray(String[]::new));
        ((BooleanParameter) params.getParameters().get("includeIgnored")).setValue(includeIgnored);
    } else {
        params = new ParameterList().addChoiceParameter("objectType", "New object type", "Annotation", outputObjectTypes, "Define the type of objects that will be created").addDoubleParameter("minSize", "Minimum object size", 0, units, "Minimum size of a region to keep (smaller regions will be dropped)").addDoubleParameter("minHoleSize", "Minimum hole size", 0, units, "Minimum size of a hole to keep (smaller holes will be filled)").addBooleanParameter("doSplit", "Split objects", false, "Split multi-part regions into separate objects").addBooleanParameter("clearExisting", "Delete existing objects", false, "Delete any existing objects within the selected object before adding new objects (or entire image if no object is selected)").addBooleanParameter("includeIgnored", "Create objects for ignored classes", includeIgnored, "Create objects for classifications that are usually ignored (e.g. \"Ignore*\", \"Region*\")").addBooleanParameter("selectNew", "Set new objects to selected", false, "Set the newly-created objects to be selected");
    }
    if (!Dialogs.showParameterDialog("Create objects", params))
        return false;
    boolean createDetections = params.getChoiceParameterValue("objectType").equals("Detection");
    boolean doSplit = params.getBooleanParameterValue("doSplit");
    includeIgnored = params.getBooleanParameterValue("includeIgnored");
    double minSize = params.getDoubleParameterValue("minSize");
    double minHoleSize = params.getDoubleParameterValue("minHoleSize");
    boolean clearExisting = params.getBooleanParameterValue("clearExisting");
    boolean selectNew = params.getBooleanParameterValue("selectNew");
    lastCreateObjectParams = params;
    parentChoice.handleSelection(imageData);
    List<CreateObjectOptions> options = new ArrayList<>();
    if (doSplit)
        options.add(CreateObjectOptions.SPLIT);
    if (clearExisting)
        options.add(CreateObjectOptions.DELETE_EXISTING);
    if (includeIgnored)
        options.add(CreateObjectOptions.INCLUDE_IGNORED);
    else if (allIgnored) {
        Dialogs.showErrorMessage(title, "Cannot create objects - all class names have an asterisk to show they should be 'ignored'!");
        return false;
    }
    if (selectNew)
        options.add(CreateObjectOptions.SELECT_NEW);
    var optionsArray = options.toArray(CreateObjectOptions[]::new);
    String optionsString = "";
    if (!options.isEmpty())
        optionsString = ", " + options.stream().map(o -> "\"" + o.name() + "\"").collect(Collectors.joining(", "));
    try {
        if (createDetections) {
            if (PixelClassifierTools.createDetectionsFromPixelClassifier(imageData, classifier, minSize, minHoleSize, optionsArray)) {
                if (classifierName != null) {
                    imageData.getHistoryWorkflow().addStep(new DefaultScriptableWorkflowStep("Pixel classifier create detections", String.format("createDetectionsFromPixelClassifier(\"%s\", %s, %s)", classifierName, minSize, minHoleSize + optionsString)));
                }
                return true;
            }
        } else {
            if (PixelClassifierTools.createAnnotationsFromPixelClassifier(imageData, classifier, minSize, minHoleSize, optionsArray)) {
                if (classifierName != null) {
                    imageData.getHistoryWorkflow().addStep(new DefaultScriptableWorkflowStep("Pixel classifier create annotations", String.format("createAnnotationsFromPixelClassifier(\"%s\", %s, %s)", classifierName, minSize, minHoleSize + optionsString)));
                }
                return true;
            }
        }
    } catch (IOException e) {
        Dialogs.showErrorMessage(title, e);
    }
    return false;
}
Also used : Button(javafx.scene.control.Button) CreateObjectOptions(qupath.opencv.ml.pixel.PixelClassifierTools.CreateObjectOptions) Arrays(java.util.Arrays) ImageServer(qupath.lib.images.servers.ImageServer) PathTileObject(qupath.lib.objects.PathTileObject) BooleanBinding(javafx.beans.binding.BooleanBinding) CheckMenuItem(javafx.scene.control.CheckMenuItem) LoggerFactory(org.slf4j.LoggerFactory) Side(javafx.geometry.Side) ImageWriter(qupath.lib.images.writers.ImageWriter) ParameterList(qupath.lib.plugins.parameters.ParameterList) ComboBox(javafx.scene.control.ComboBox) ContextMenu(javafx.scene.control.ContextMenu) Map(java.util.Map) PixelClassifierTools(qupath.opencv.ml.pixel.PixelClassifierTools) Pane(javafx.scene.layout.Pane) MenuItem(javafx.scene.control.MenuItem) BufferedImage(java.awt.image.BufferedImage) Collectors(java.util.stream.Collectors) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathDetectionObject(qupath.lib.objects.PathDetectionObject) PathObject(qupath.lib.objects.PathObject) Objects(java.util.Objects) List(java.util.List) BooleanProperty(javafx.beans.property.BooleanProperty) Project(qupath.lib.projects.Project) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) GuiTools(qupath.lib.gui.tools.GuiTools) RegionFilter(qupath.lib.gui.viewer.RegionFilter) BorderPane(javafx.scene.layout.BorderPane) StringProperty(javafx.beans.property.StringProperty) PathCellObject(qupath.lib.objects.PathCellObject) SaveResourcePaneBuilder(qupath.process.gui.commands.ui.SaveResourcePaneBuilder) ObjectExpression(javafx.beans.binding.ObjectExpression) PathClassTools(qupath.lib.objects.classes.PathClassTools) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) Bindings(javafx.beans.binding.Bindings) ArrayList(java.util.ArrayList) StandardRegionFilters(qupath.lib.gui.viewer.RegionFilter.StandardRegionFilters) LinkedHashMap(java.util.LinkedHashMap) Dialogs(qupath.lib.gui.dialogs.Dialogs) Tooltip(javafx.scene.control.Tooltip) ImageData(qupath.lib.images.ImageData) Logger(org.slf4j.Logger) StringExpression(javafx.beans.binding.StringExpression) ImageWriterTools(qupath.lib.images.writers.ImageWriterTools) Commands(qupath.lib.gui.commands.Commands) IOException(java.io.IOException) TMACoreObject(qupath.lib.objects.TMACoreObject) OverlayOptions(qupath.lib.gui.viewer.OverlayOptions) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) PixelClassifier(qupath.lib.classifiers.pixel.PixelClassifier) BooleanParameter(qupath.lib.plugins.parameters.BooleanParameter) Collections(java.util.Collections) PaneTools(qupath.lib.gui.tools.PaneTools) ArrayList(java.util.ArrayList) IOException(java.io.IOException) BooleanParameter(qupath.lib.plugins.parameters.BooleanParameter) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) ParameterList(qupath.lib.plugins.parameters.ParameterList) CreateObjectOptions(qupath.opencv.ml.pixel.PixelClassifierTools.CreateObjectOptions)

Aggregations

BufferedImage (java.awt.image.BufferedImage)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 Objects (java.util.Objects)1 Collectors (java.util.stream.Collectors)1 Bindings (javafx.beans.binding.Bindings)1 BooleanBinding (javafx.beans.binding.BooleanBinding)1 ObjectExpression (javafx.beans.binding.ObjectExpression)1 StringExpression (javafx.beans.binding.StringExpression)1 BooleanProperty (javafx.beans.property.BooleanProperty)1 SimpleBooleanProperty (javafx.beans.property.SimpleBooleanProperty)1 StringProperty (javafx.beans.property.StringProperty)1 Side (javafx.geometry.Side)1 Button (javafx.scene.control.Button)1 CheckMenuItem (javafx.scene.control.CheckMenuItem)1