Search in sources :

Example 31 with ImageData

use of qupath.lib.images.ImageData in project qupath by qupath.

the class Commands method promptToSimplifySelectedAnnotations.

/**
 * Show a prompt to selected annotations in a hierarchy.
 * @param imageData the current image data
 * @param altitudeThreshold default altitude value for simplification
 */
public static void promptToSimplifySelectedAnnotations(ImageData<?> imageData, double altitudeThreshold) {
    PathObjectHierarchy hierarchy = imageData.getHierarchy();
    List<PathObject> pathObjects = hierarchy.getSelectionModel().getSelectedObjects().stream().filter(p -> p.isAnnotation() && p.hasROI() && p.isEditable() && !p.getROI().isPoint()).collect(Collectors.toList());
    if (pathObjects.isEmpty()) {
        Dialogs.showErrorMessage("Simplify annotations", "No unlocked shape annotations selected!");
        return;
    }
    String input = Dialogs.showInputDialog("Simplify shape", "Set altitude threshold in pixels.\nHigher values give simpler shapes.", Double.toString(altitudeThreshold));
    if (input == null || !(input instanceof String) || ((String) input).trim().length() == 0)
        return;
    try {
        altitudeThreshold = Double.parseDouble(((String) input).trim());
    } catch (NumberFormatException e) {
        logger.error("Could not parse altitude threshold from {}", input);
        return;
    }
    if (altitudeThreshold <= 0) {
        Dialogs.showErrorMessage("Simplify shape", "Amplitude threshold should be greater than zero!");
        return;
    }
    long startTime = System.currentTimeMillis();
    for (var pathObject : pathObjects) {
        ROI pathROI = pathObject.getROI();
        if (pathROI instanceof PolygonROI) {
            PolygonROI polygonROI = (PolygonROI) pathROI;
            pathROI = ShapeSimplifier.simplifyPolygon(polygonROI, altitudeThreshold);
        } else {
            pathROI = ShapeSimplifier.simplifyShape(pathROI, altitudeThreshold);
        }
        ((PathAnnotationObject) pathObject).setROI(pathROI);
    }
    long endTime = System.currentTimeMillis();
    logger.debug("Shapes simplified in " + (endTime - startTime) + " ms");
    hierarchy.fireObjectsChangedEvent(hierarchy, pathObjects);
}
Also used : Arrays(java.util.Arrays) ServerTools(qupath.lib.images.servers.ServerTools) PathTileObject(qupath.lib.objects.PathTileObject) StackPane(javafx.scene.layout.StackPane) ImageWriter(qupath.lib.images.writers.ImageWriter) ParameterList(qupath.lib.plugins.parameters.ParameterList) ImageRegion(qupath.lib.regions.ImageRegion) Map(java.util.Map) PathObjects(qupath.lib.objects.PathObjects) Screen(javafx.stage.Screen) WorkflowStep(qupath.lib.plugins.workflow.WorkflowStep) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) Project(qupath.lib.projects.Project) ShapeFeatures(qupath.lib.analysis.features.ObjectMeasurements.ShapeFeatures) MeasurementMapPane(qupath.lib.gui.panes.MeasurementMapPane) BorderPane(javafx.scene.layout.BorderPane) StringProperty(javafx.beans.property.StringProperty) RectangleROI(qupath.lib.roi.RectangleROI) CheckBoxListCell(javafx.scene.control.cell.CheckBoxListCell) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) Supplier(java.util.function.Supplier) Bindings(javafx.beans.binding.Bindings) ViewTrackerControlPane(qupath.lib.gui.viewer.recording.ViewTrackerControlPane) Projects(qupath.lib.projects.Projects) ArrayList(java.util.ArrayList) CheckListView(org.controlsfx.control.CheckListView) ROIs(qupath.lib.roi.ROIs) ShapeSimplifier(qupath.lib.roi.ShapeSimplifier) TextAlignment(javafx.scene.text.TextAlignment) PathClassPane(qupath.lib.gui.panes.PathClassPane) GridPane(javafx.scene.layout.GridPane) Files(java.nio.file.Files) GeneralTools(qupath.lib.common.GeneralTools) RegionRequest(qupath.lib.regions.RegionRequest) Window(java.awt.Window) DistanceTools(qupath.lib.analysis.DistanceTools) IOException(java.io.IOException) File(java.io.File) OverlayOptions(qupath.lib.gui.viewer.OverlayOptions) PathObjectTools(qupath.lib.objects.PathObjectTools) ROI(qupath.lib.roi.interfaces.ROI) QP(qupath.lib.scripting.QP) GridLines(qupath.lib.gui.viewer.GridLines) PathPrefs(qupath.lib.gui.prefs.PathPrefs) RenderedImageServer(qupath.lib.gui.images.servers.RenderedImageServer) PaneTools(qupath.lib.gui.tools.PaneTools) PathIO(qupath.lib.io.PathIO) Button(javafx.scene.control.Button) Pos(javafx.geometry.Pos) ImageServer(qupath.lib.images.servers.ImageServer) CombineOp(qupath.lib.roi.RoiTools.CombineOp) LoggerFactory(org.slf4j.LoggerFactory) ObservableDoubleValue(javafx.beans.value.ObservableDoubleValue) ComboBox(javafx.scene.control.ComboBox) ImageServers(qupath.lib.images.servers.ImageServers) PolygonROI(qupath.lib.roi.PolygonROI) QuPathGUI(qupath.lib.gui.QuPathGUI) Pane(javafx.scene.layout.Pane) TextField(javafx.scene.control.TextField) BufferedImage(java.awt.image.BufferedImage) Collection(java.util.Collection) Collectors(java.util.stream.Collectors) PathDetectionObject(qupath.lib.objects.PathDetectionObject) PathObject(qupath.lib.objects.PathObject) QuPathViewer(qupath.lib.gui.viewer.QuPathViewer) Priority(javafx.scene.layout.Priority) List(java.util.List) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) ProjectIO(qupath.lib.projects.ProjectIO) GuiTools(qupath.lib.gui.tools.GuiTools) TMASummaryViewer(qupath.lib.gui.tma.TMASummaryViewer) ImagePlane(qupath.lib.regions.ImagePlane) PathCellObject(qupath.lib.objects.PathCellObject) Scene(javafx.scene.Scene) WorkflowCommandLogView(qupath.lib.gui.panes.WorkflowCommandLogView) TextArea(javafx.scene.control.TextArea) ButtonType(javafx.scene.control.ButtonType) Action(org.controlsfx.control.action.Action) HashMap(java.util.HashMap) DoubleProperty(javafx.beans.property.DoubleProperty) Function(java.util.function.Function) Dialogs(qupath.lib.gui.dialogs.Dialogs) Insets(javafx.geometry.Insets) ActionTools(qupath.lib.gui.ActionTools) Tooltip(javafx.scene.control.Tooltip) WeakHashMap(java.util.WeakHashMap) ImageData(qupath.lib.images.ImageData) RoiTools(qupath.lib.roi.RoiTools) Modality(javafx.stage.Modality) Logger(org.slf4j.Logger) Label(javafx.scene.control.Label) Iterator(java.util.Iterator) ImageWriterTools(qupath.lib.images.writers.ImageWriterTools) TMACoreObject(qupath.lib.objects.TMACoreObject) Stage(javafx.stage.Stage) Collections(java.util.Collections) ContentDisplay(javafx.scene.control.ContentDisplay) DialogButton(qupath.lib.gui.dialogs.Dialogs.DialogButton) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PolygonROI(qupath.lib.roi.PolygonROI) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) RectangleROI(qupath.lib.roi.RectangleROI) ROI(qupath.lib.roi.interfaces.ROI) PolygonROI(qupath.lib.roi.PolygonROI)

Example 32 with ImageData

use of qupath.lib.images.ImageData in project qupath by qupath.

the class GuiTools method createAnnotationsMenuImpl.

private static void createAnnotationsMenuImpl(QuPathGUI qupath, Object menu) {
    // Add annotation options
    CheckMenuItem miLockAnnotations = new CheckMenuItem("Lock");
    CheckMenuItem miUnlockAnnotations = new CheckMenuItem("Unlock");
    miLockAnnotations.setOnAction(e -> setSelectedAnnotationLock(qupath.getImageData(), true));
    miUnlockAnnotations.setOnAction(e -> setSelectedAnnotationLock(qupath.getImageData(), false));
    MenuItem miSetProperties = new MenuItem("Set properties");
    miSetProperties.setOnAction(e -> {
        var hierarchy = qupath.getViewer().getHierarchy();
        if (hierarchy != null)
            GuiTools.promptToSetActiveAnnotationProperties(hierarchy);
    });
    var actionInsertInHierarchy = qupath.createImageDataAction(imageData -> Commands.insertSelectedObjectsInHierarchy(imageData));
    actionInsertInHierarchy.setText("Insert in hierarchy");
    var miInsertHierarchy = ActionTools.createMenuItem(actionInsertInHierarchy);
    var actionMerge = qupath.createImageDataAction(imageData -> Commands.mergeSelectedAnnotations(imageData));
    actionMerge.setText("Merge selected");
    var actionSubtract = qupath.createImageDataAction(imageData -> Commands.combineSelectedAnnotations(imageData, CombineOp.SUBTRACT));
    actionSubtract.setText("Subtract selected");
    var actionIntersect = qupath.createImageDataAction(imageData -> Commands.combineSelectedAnnotations(imageData, CombineOp.INTERSECT));
    actionIntersect.setText("Intersect selected");
    var actionInverse = qupath.createImageDataAction(imageData -> Commands.makeInverseAnnotation(imageData));
    actionInverse.setText("Make inverse");
    Menu menuCombine = MenuTools.createMenu("Edit multiple", actionMerge, // TODO: Make this less ambiguous!
    actionSubtract, actionIntersect);
    Menu menuEdit = MenuTools.createMenu("Edit single", actionInverse, qupath.createPluginAction("Split", SplitAnnotationsPlugin.class, null));
    // Menu menuPoints = MenuTools.createMenu(
    // "Points",
    // QuPathGUI.createCommandAction(new MergePointsCommand(qupath, true), "Merge all points for class"),
    // QuPathGUI.createCommandAction(new MergePointsCommand(qupath, true), "Merge selected points for class")
    // );
    MenuItem separator = new SeparatorMenuItem();
    Runnable validator = () -> {
        var imageData = qupath.getImageData();
        PathObject selected = null;
        Collection<PathObject> allSelected = Collections.emptyList();
        boolean allSelectedAnnotations = false;
        boolean hasSelectedAnnotation = false;
        if (imageData != null) {
            selected = imageData.getHierarchy().getSelectionModel().getSelectedObject();
            allSelected = new ArrayList<>(imageData.getHierarchy().getSelectionModel().getSelectedObjects());
            hasSelectedAnnotation = selected != null && selected.isAnnotation();
            allSelectedAnnotations = allSelected.stream().allMatch(p -> p.isAnnotation());
        }
        miLockAnnotations.setDisable(!hasSelectedAnnotation);
        miUnlockAnnotations.setDisable(!hasSelectedAnnotation);
        if (hasSelectedAnnotation) {
            boolean isLocked = selected.isLocked();
            miLockAnnotations.setSelected(isLocked);
            miUnlockAnnotations.setSelected(!isLocked);
        }
        miSetProperties.setDisable(!hasSelectedAnnotation);
        miInsertHierarchy.setVisible(selected != null);
        menuEdit.setVisible(hasSelectedAnnotation);
        menuCombine.setVisible(allSelectedAnnotations && allSelected.size() > 1);
        separator.setVisible(menuEdit.isVisible() || menuCombine.isVisible());
    };
    List<MenuItem> items;
    if (menu instanceof Menu) {
        Menu m = (Menu) menu;
        items = m.getItems();
        m.setOnMenuValidation(e -> validator.run());
    } else if (menu instanceof ContextMenu) {
        ContextMenu m = (ContextMenu) menu;
        items = m.getItems();
        m.setOnShowing(e -> validator.run());
    } else
        throw new IllegalArgumentException("Menu must be either a standard Menu or a ContextMenu!");
    MenuTools.addMenuItems(items, miLockAnnotations, miUnlockAnnotations, miSetProperties, miInsertHierarchy, separator, menuEdit, menuCombine);
}
Also used : CheckComboBox(org.controlsfx.control.CheckComboBox) UnaryOperator(java.util.function.UnaryOperator) TextFormatter(javafx.scene.control.TextFormatter) PathRootObject(qupath.lib.objects.PathRootObject) ParameterList(qupath.lib.plugins.parameters.ParameterList) PointsROI(qupath.lib.roi.PointsROI) Matcher(java.util.regex.Matcher) Action(java.awt.Desktop.Action) ColorTools(qupath.lib.common.ColorTools) GraphicsContext(javafx.scene.canvas.GraphicsContext) Canvas(javafx.scene.canvas.Canvas) Screen(javafx.stage.Screen) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) Platform(javafx.application.Platform) CountDownLatch(java.util.concurrent.CountDownLatch) Transparency(java.awt.Transparency) Clipboard(javafx.scene.input.Clipboard) SimpleDoubleProperty(javafx.beans.property.SimpleDoubleProperty) StringProperty(javafx.beans.property.StringProperty) Callable(java.util.concurrent.Callable) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) DefaultColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains.DefaultColorDeconvolutionStains) Bindings(javafx.beans.binding.Bindings) NumberFormat(java.text.NumberFormat) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Slider(javafx.scene.control.Slider) SplitAnnotationsPlugin(qupath.lib.plugins.objects.SplitAnnotationsPlugin) GridPane(javafx.scene.layout.GridPane) Color(javafx.scene.paint.Color) GeneralTools(qupath.lib.common.GeneralTools) Commands(qupath.lib.gui.commands.Commands) Node(javafx.scene.Node) CheckBox(javafx.scene.control.CheckBox) IOException(java.io.IOException) File(java.io.File) PathObjectTools(qupath.lib.objects.PathObjectTools) Menu(javafx.scene.control.Menu) ROI(qupath.lib.roi.interfaces.ROI) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) ObservableValue(javafx.beans.value.ObservableValue) Image(javafx.scene.image.Image) Button(javafx.scene.control.Button) ImageServer(qupath.lib.images.servers.ImageServer) CombineOp(qupath.lib.roi.RoiTools.CombineOp) DoubleBinding(javafx.beans.binding.DoubleBinding) ListCell(javafx.scene.control.ListCell) CheckMenuItem(javafx.scene.control.CheckMenuItem) LoggerFactory(org.slf4j.LoggerFactory) RenderingHints(java.awt.RenderingHints) Side(javafx.geometry.Side) ContextMenu(javafx.scene.control.ContextMenu) URI(java.net.URI) QuPathGUI(qupath.lib.gui.QuPathGUI) TextField(javafx.scene.control.TextField) MenuItem(javafx.scene.control.MenuItem) BufferedImage(java.awt.image.BufferedImage) Collection(java.util.Collection) Spinner(javafx.scene.control.Spinner) Collectors(java.util.stream.Collectors) StainVector(qupath.lib.color.StainVector) PathObject(qupath.lib.objects.PathObject) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) QuPathViewer(qupath.lib.gui.viewer.QuPathViewer) List(java.util.List) Robot(javafx.scene.robot.Robot) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) Pattern(java.util.regex.Pattern) ClipboardContent(javafx.scene.input.ClipboardContent) Scene(javafx.scene.Scene) ListView(javafx.scene.control.ListView) TextArea(javafx.scene.control.TextArea) ParsePosition(java.text.ParsePosition) DoubleProperty(javafx.beans.property.DoubleProperty) ColorDeconvolutionHelper(qupath.lib.color.ColorDeconvolutionHelper) Function(java.util.function.Function) Dialogs(qupath.lib.gui.dialogs.Dialogs) ColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains) SwingUtilities(javax.swing.SwingUtilities) Graphics2D(java.awt.Graphics2D) ActionTools(qupath.lib.gui.ActionTools) Tooltip(javafx.scene.control.Tooltip) ColorPicker(javafx.scene.control.ColorPicker) ImageData(qupath.lib.images.ImageData) Desktop(java.awt.Desktop) ObjectProperty(javafx.beans.property.ObjectProperty) Logger(org.slf4j.Logger) Label(javafx.scene.control.Label) WritableImage(javafx.scene.image.WritableImage) TMACoreObject(qupath.lib.objects.TMACoreObject) DoubleSpinnerValueFactory(javafx.scene.control.SpinnerValueFactory.DoubleSpinnerValueFactory) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) Stage(javafx.stage.Stage) SpinnerValueFactory(javafx.scene.control.SpinnerValueFactory) SwingFXUtils(javafx.embed.swing.SwingFXUtils) Window(javafx.stage.Window) Collections(java.util.Collections) ArrayList(java.util.ArrayList) CheckMenuItem(javafx.scene.control.CheckMenuItem) MenuItem(javafx.scene.control.MenuItem) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) ContextMenu(javafx.scene.control.ContextMenu) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) CheckMenuItem(javafx.scene.control.CheckMenuItem) PathObject(qupath.lib.objects.PathObject) Collection(java.util.Collection) Menu(javafx.scene.control.Menu) ContextMenu(javafx.scene.control.ContextMenu) SplitAnnotationsPlugin(qupath.lib.plugins.objects.SplitAnnotationsPlugin)

Aggregations

ImageData (qupath.lib.images.ImageData)32 BufferedImage (java.awt.image.BufferedImage)27 Collectors (java.util.stream.Collectors)26 Logger (org.slf4j.Logger)26 LoggerFactory (org.slf4j.LoggerFactory)26 List (java.util.List)25 ArrayList (java.util.ArrayList)23 IOException (java.io.IOException)21 PathObject (qupath.lib.objects.PathObject)21 File (java.io.File)19 Collection (java.util.Collection)19 Dialogs (qupath.lib.gui.dialogs.Dialogs)19 ImageServer (qupath.lib.images.servers.ImageServer)19 Collections (java.util.Collections)17 Map (java.util.Map)17 GeneralTools (qupath.lib.common.GeneralTools)17 QuPathGUI (qupath.lib.gui.QuPathGUI)17 Arrays (java.util.Arrays)16 PathPrefs (qupath.lib.gui.prefs.PathPrefs)15 Bindings (javafx.beans.binding.Bindings)14