Search in sources :

Example 16 with LayerSet

use of ini.trakem2.display.LayerSet in project TrakEM2 by trakem2.

the class Display3D method removeFrom3D.

/**
 * Remove all basic type children contained in {@code pt} and its children, recursively.
 *
 * @param pt
 */
public static void removeFrom3D(final ProjectThing pt) {
    final HashSet<ProjectThing> hs = pt.findBasicTypeChildren();
    if (null == hs || 0 == hs.size()) {
        Utils.logAll("Nothing to remove from 3D.");
        return;
    }
    // Ignore Profile instances ("profile_list" takes care of them)
    for (final ProjectThing child : hs) {
        if (child.getByType().equals("profile"))
            continue;
        // Find the LayerSet
        LayerSet lset = null;
        if (child.getType().equals("profile_list")) {
            if (!child.hasChildren())
                continue;
            for (final ProjectThing p : child.getChildren()) {
                if (null != p.getObject() && p.getObject() instanceof Profile) {
                    lset = ((Displayable) p.getObject()).getLayerSet();
                    break;
                }
            }
            if (null == lset)
                continue;
        } else if (child.getType().equals("profile")) {
            // Taken care of by "profile list"
            continue;
        } else {
            final Displayable d = (Displayable) child.getObject();
            if (null == d) {
                Utils.log("Null object for ProjectThing " + child);
                continue;
            }
            lset = d.getLayerSet();
        }
        if (null == lset) {
            Utils.log("No LayerSet found for " + child);
            continue;
        }
        final Display3D d3d = getDisplay(lset);
        if (null == d3d) {
            Utils.log("No Display 3D found for " + child);
            // no Display3D window open
            continue;
        }
        final String oldTitle = d3d.ht_pt_meshes.remove(child);
        if (null == oldTitle) {
            Utils.log("Could not find a title for " + child);
            continue;
        }
        Utils.log("Removed from 3D view: " + oldTitle);
        d3d.getUniverse().removeContent(oldTitle);
    }
}
Also used : ProjectThing(ini.trakem2.tree.ProjectThing)

Example 17 with LayerSet

use of ini.trakem2.display.LayerSet in project TrakEM2 by trakem2.

the class ManualAlignMode method apply.

@Override
public boolean apply() {
    // Check there's more than one layer
    if (m.size() < 2) {
        Utils.showMessage("Need more than one layer to align!");
        return false;
    }
    // Check that the current layer is one of the layers with landmarks.
    // Will be used as reference
    final Layer ref_layer = display.getLayer();
    if (null == m.get(ref_layer)) {
        Utils.showMessage("Please scroll to a layer with landmarks,\nto be used as reference.");
        return false;
    }
    // Check that all layers have the same number of landmarks
    int n_landmarks = -1;
    for (final Map.Entry<Layer, Landmarks> e : m.entrySet()) {
        final Landmarks lm = e.getValue();
        if (-1 == n_landmarks) {
            n_landmarks = lm.points.size();
            continue;
        }
        if (n_landmarks != lm.points.size()) {
            Utils.showMessage("Can't apply: there are different amounts of landmarks per layer.\nSee the log window.");
            for (final Map.Entry<Layer, Landmarks> ee : m.entrySet()) {
                Utils.log(ee.getValue().points.size() + " landmarks in layer " + ee.getKey());
            }
            return false;
        }
    }
    // Sort Layers by Z
    final TreeMap<Layer, Landmarks> sorted = new TreeMap<Layer, Landmarks>(new Comparator<Layer>() {

        @Override
        public boolean equals(final Object ob) {
            return this == ob;
        }

        @Override
        public int compare(final Layer l1, final Layer l2) {
            // Ascending order
            final double dz = l1.getZ() - l2.getZ();
            if (dz < 0)
                return -1;
            else if (dz > 0)
                return 1;
            else
                return 0;
        }
    });
    sorted.putAll(m);
    int iref = 0;
    for (final Layer la : sorted.keySet()) {
        if (la != ref_layer)
            iref++;
        else
            break;
    }
    // Ok, now ask for a model
    final GenericDialog gd = new GenericDialog("Model");
    gd.addChoice("Model:", Align.Param.modelStrings, Align.Param.modelStrings[1]);
    gd.addCheckbox("Propagate to first layer", 0 != iref);
    ((Component) gd.getCheckboxes().get(0)).setEnabled(0 != iref);
    gd.addCheckbox("Propagate to last layer", sorted.size() - 1 != iref);
    ((Component) gd.getCheckboxes().get(1)).setEnabled(sorted.size() - 1 != iref);
    gd.showDialog();
    if (gd.wasCanceled())
        return false;
    final int model_index = gd.getNextChoiceIndex();
    final boolean propagate_to_first = gd.getNextBoolean();
    final boolean propagate_to_last = gd.getNextBoolean();
    int min;
    // Create a model as desired
    final AbstractAffineModel2D<?> model;
    switch(model_index) {
        case 0:
            min = 1;
            model = new TranslationModel2D();
            break;
        case 1:
            min = 2;
            model = new RigidModel2D();
            break;
        case 2:
            min = 2;
            model = new SimilarityModel2D();
            break;
        case 3:
            min = 3;
            model = new AffineModel2D();
            break;
        default:
            Utils.log("Unknown model index!");
            return false;
    }
    if (n_landmarks < min) {
        Utils.showMessage("Need at least " + min + " landmarks for a " + Align.Param.modelStrings[model_index] + " model");
        return false;
    }
    Bureaucrat.createAndStart(new Worker.Task("Aligning layers with landmarks") {

        @Override
        public void exec() {
            // Find layers with landmarks, in increasing Z.
            // Match in pairs.
            // So, get two submaps: from ref_layer to first, and from ref_layer to last
            // strictly lower Z than ref_layer
            final SortedMap<Layer, Landmarks> first_chunk_ = new TreeMap<Layer, Landmarks>(sorted.headMap(ref_layer));
            // .. so add ref_layer
            first_chunk_.put(ref_layer, m.get(ref_layer));
            // equal or larger Z than ref_layer
            final SortedMap<Layer, Landmarks> second_chunk = sorted.tailMap(ref_layer);
            final SortedMap<Layer, Landmarks> first_chunk;
            // Reverse order of first_chunk
            if (first_chunk_.size() > 1) {
                final SortedMap<Layer, Landmarks> fc = new TreeMap<Layer, Landmarks>(new Comparator<Layer>() {

                    @Override
                    public boolean equals(final Object ob) {
                        return this == ob;
                    }

                    @Override
                    public int compare(final Layer l1, final Layer l2) {
                        // Descending order
                        final double dz = l2.getZ() - l1.getZ();
                        if (dz < 0)
                            return -1;
                        else if (dz > 0)
                            return 1;
                        else
                            return 0;
                    }
                });
                fc.putAll(first_chunk_);
                first_chunk = fc;
            } else {
                first_chunk = first_chunk_;
            }
            final LayerSet ls = ref_layer.getParent();
            final Collection<Layer> affected_layers = new HashSet<Layer>(m.keySet());
            // Gather all Patch instances that will be affected
            final ArrayList<Patch> patches = new ArrayList<Patch>();
            for (final Layer la : m.keySet()) patches.addAll(la.getAll(Patch.class));
            if (propagate_to_first && first_chunk.size() > 1) {
                final Collection<Layer> affected = ls.getLayers().subList(0, ls.indexOf(first_chunk.lastKey()));
                for (final Layer la : affected) {
                    patches.addAll(la.getAll(Patch.class));
                }
                affected_layers.addAll(affected);
            }
            if (propagate_to_last && second_chunk.size() > 1) {
                final Collection<Layer> affected = ls.getLayers().subList(ls.indexOf(second_chunk.lastKey()) + 1, ls.size());
                for (final Layer la : affected) {
                    patches.addAll(la.getAll(Patch.class));
                }
            }
            // Transform segmentations along with patches
            AlignTask.transformPatchesAndVectorData(patches, new Runnable() {

                @Override
                public void run() {
                    // Apply!
                    // TODO: when adding non-linear transforms, use this single line for undo instead of all below:
                    // (these transforms may be non-linear as well, which alter mipmaps.)
                    // ls.addTransformStepWithData(affected_layers);
                    // Setup undo:
                    // Find all images in the range of affected layers,
                    // plus all Displayable of those layers (but Patch instances in a separate DoTransforms step,
                    // to avoid adding a "data" undo for them, which would recreate mipmaps when undone).
                    // plus all ZDisplayable that paint in those layers
                    final HashSet<Displayable> ds = new HashSet<Displayable>();
                    final ArrayList<Displayable> patches = new ArrayList<Displayable>();
                    for (final Layer layer : affected_layers) {
                        for (final Displayable d : layer.getDisplayables()) {
                            if (d.getClass() == Patch.class) {
                                patches.add(d);
                            } else {
                                ds.add(d);
                            }
                        }
                    }
                    for (final ZDisplayable zd : ls.getZDisplayables()) {
                        for (final Layer layer : affected_layers) {
                            if (zd.paintsAt(layer)) {
                                ds.add((Displayable) zd);
                                break;
                            }
                        }
                    }
                    if (ds.size() > 0) {
                        final Displayable.DoEdits step = ls.addTransformStepWithData(ds);
                        if (patches.size() > 0) {
                            final ArrayList<DoStep> a = new ArrayList<DoStep>();
                            a.add(new Displayable.DoTransforms().addAll(patches));
                            step.addDependents(a);
                        }
                    }
                    if (first_chunk.size() > 1) {
                        final AffineTransform aff = align(first_chunk, model);
                        if (propagate_to_first) {
                            for (final Layer la : ls.getLayers().subList(0, ls.indexOf(first_chunk.lastKey()))) {
                                // exclusive last
                                la.apply(Patch.class, aff);
                            }
                        }
                    }
                    if (second_chunk.size() > 1) {
                        final AffineTransform aff = align(second_chunk, model);
                        if (propagate_to_last) {
                            for (final Layer la : ls.getLayers().subList(ls.indexOf(second_chunk.lastKey()) + 1, ls.size())) {
                                // exclusive last
                                la.apply(Patch.class, aff);
                            }
                        }
                    }
                    Display.repaint();
                    // Store current state
                    if (ds.size() > 0) {
                        final Displayable.DoEdits step2 = ls.addTransformStepWithData(ds);
                        if (patches.size() > 0) {
                            final ArrayList<DoStep> a2 = new ArrayList<DoStep>();
                            a2.add(new Displayable.DoTransforms().addAll(patches));
                            step2.addDependents(a2);
                        }
                    }
                }
            });
        }
    }, display.getProject());
    return true;
}
Also used : ArrayList(java.util.ArrayList) Comparator(java.util.Comparator) RigidModel2D(mpicbg.models.RigidModel2D) GenericDialog(ij.gui.GenericDialog) AbstractAffineModel2D(mpicbg.models.AbstractAffineModel2D) AffineModel2D(mpicbg.models.AffineModel2D) Worker(ini.trakem2.utils.Worker) SimilarityModel2D(mpicbg.models.SimilarityModel2D) Component(java.awt.Component) HashSet(java.util.HashSet) TreeMap(java.util.TreeMap) Point(mpicbg.models.Point) SortedMap(java.util.SortedMap) Collection(java.util.Collection) AffineTransform(java.awt.geom.AffineTransform) TranslationModel2D(mpicbg.models.TranslationModel2D) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap)

Example 18 with LayerSet

use of ini.trakem2.display.LayerSet in project TrakEM2 by trakem2.

the class ImageJCommandListener method commandExecuting.

// I know, I could create a hashtable and then map methods of this class to each command key ... this is just easier, and performance-wise nobody cares
// Or even a hastable with String command keys and then a number as value, and use a gigantic switch block. So much pain to write. WHAT I REALLY WANT is a switch that takes a String and is fast because it has its own hash setup.
public String commandExecuting(final String command) {
    // Utils.log2("Command: " + command);
    // 1 - check source
    ImagePlus current = WindowManager.getCurrentImage();
    // not a trakem2 display: continue happily
    if (!(current instanceof FakeImagePlus))
        return command;
    // 2 - identify project
    final FakeImagePlus fimp = (FakeImagePlus) current;
    final Display display = fimp.getDisplay();
    final LayerSet layer_set = display.getLayer().getParent();
    final Project project = display.getProject();
    final ProjectTree ptree = project.getProjectTree();
    final Displayable active = display.getActive();
    final Selection selection = display.getSelection();
    // FILE menu
    if (command.equals("Save")) {
        project.save();
        return null;
    } else // EDIT menu
    if (command.equals("Undo")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Cut")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Copy")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Copy to System")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Paste")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Clear")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Clear Outside")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Fill")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Draw")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Invert")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else // EDIT - SELECTION menu
    if (command.equals("Select All")) {
        if (ProjectToolbar.SELECT == Toolbar.getToolId()) {
            selection.selectAll();
            return null;
        }
        return command;
    } else if (command.equals("Select None")) {
        if (ProjectToolbar.SELECT == Toolbar.getToolId()) {
            display.select(null);
            return null;
        }
        return command;
    } else if (command.equals("Restore Selection")) {
        if (ProjectToolbar.SELECT == Toolbar.getToolId()) {
            selection.restore();
            return null;
        }
        return command;
    } else // IMAGE - TYPE menu
    if (command.equals("8-bit")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("16-bit")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("32-bit")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("8-bit Color")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("RGB Color")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("RGB Stack") || command.equals("HSB Stack")) {
        Utils.showMessage("Can't convert to " + command);
        return null;
    } else // IMAGE - ADJUST menu
    if (command.equals("Brightness/Contrast...")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Window/Level...")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Color Balance...")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Threshold...")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Size...")) {
        if (null != active)
            selection.specify();
        return null;
    } else if (command.equals("Canvas Size...")) {
        display.resizeCanvas();
        return null;
    } else // IMAGE menu
    if (command.equals("Show Info...")) {
        // TODO perhaps it should show only for images ...
        if (null == active) {
            ptree.showInfo(project.getRootProjectThing());
        } else {
            ProjectThing pt = project.findProjectThing(active);
            if (null != pt)
                ptree.showInfo(pt);
        }
        return null;
    } else // IMAGE - COLOR menu
    if (in(command, new String[] { "RGB Split", "RGB Merge...", "Stack to RGB", "Make Composite" })) {
        notAvailable(command);
        return null;
    } else if (command.equals("Show LUT")) {
        return setTempCurrentImage(command, active);
    } else if (command.equals("Edit LUT...")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("Average Color")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("RGB to CIELAB")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else if (command.equals("RGB to Luminance")) {
        // TODO forward to the active image, if any
        niy(command);
        return null;
    } else // IMAGE STACK menu
    if (in(command, new String[] { "Add Slice", "Delete Slice" })) {
        Utils.showMessage("Go to the Layer Tree and right-click to add/delete a layer.");
        return null;
    } else if (command.equals("Next Slice [>]")) {
        display.nextLayer(IJ.shiftKeyDown() ? Event.SHIFT_MASK : 0);
        return null;
    } else if (command.equals("Previous Slice [<]")) {
        display.previousLayer(IJ.shiftKeyDown() ? Event.SHIFT_MASK : 0);
        return null;
    } else if (in(command, new String[] { "Set Slice", "Images to Stack", "Stack to Images", "Make Montage..." })) {
        notAvailable(command);
        return null;
    } else if (command.equals("Reslice [/]...")) {
        // TODO
        niy(command);
        return null;
    } else if (command.equals("Z Project...")) {
        // TODO
        niy(command);
        return null;
    } else if (command.equals("3D Project...")) {
        // TODO
        niy(command);
        return null;
    } else if (command.equals("Plot Z-axis Profile")) {
        // TODO
        niy(command);
        return null;
    } else if (command.equals("Start Animation [\\]")) {
        // TODO
        niy(command);
        return null;
    } else if (command.equals("Stop Animation")) {
        // TODO
        niy(command);
        return null;
    } else // IMAGE menu again
    if (command.equals("Crop")) {
        notAvailable(command);
        return null;
    } else if (in(command, new String[] { "Translate...", "Scale..." })) {
        if (null != active)
            selection.specify();
        return null;
    } else if (command.equals("Duplicate...")) {
        if (null != active && active.getClass().equals(Patch.class)) {
            // TODO stacks?
            // 2.5 security factor: for awt in non-1.6.0 machines
            project.getLoader().releaseToFit((long) (project.getLoader().estimateImageFileSize((Patch) active, 0) * 2.5));
            new ImagePlus(active.getTitle(), ((Patch) active).getImageProcessor().duplicate()).show();
        }
        return null;
    } else if (command.equals("Rename...")) {
        if (null != active) {
            active.adjustProperties();
            Display.updateSelection();
        }
        return null;
    } else // IMAGE ROTATE menu
    if (command.equals("Flip Horizontally")) {
        selection.apply(2, new double[] { -1, 1 });
        return null;
    } else if (command.equals("Flip Vertically")) {
        selection.apply(2, new double[] { 1, -1 });
        return null;
    } else if (command.equals("Rotate 90 Degrees Right")) {
        selection.apply(1, new double[] { 90 });
        return null;
    } else if (command.equals("Rotate 90 Degrees Left")) {
        selection.apply(1, new double[] { -90 });
        return null;
    } else if (command.equals("Arbitrarily...")) {
        if (null != active)
            selection.specify();
        return null;
    } else // IMAGE ZOOM menu
    if (command.equals("To Selection")) {
        Roi roi = fimp.getRoi();
        if (null != roi) {
            Rectangle b = roi.getBounds();
            b.x -= b.width / 2;
            b.y -= b.height / 2;
            b.width *= 2;
            b.height *= 2;
            display.getCanvas().showCentered(b);
        }
        return null;
    } else if (command.equals("View 100%")) {
        // TODO
        niy(command);
        return null;
    } else // ANALYZE menu
    if (command.equals("Measure")) {
        // Minimal measurement: area of closed ROIs, length of unclosed ROIs, calibrated.
        Roi roi = fimp.getRoi();
        if (null != roi) {
            Calibration cal = fimp.getCalibration();
            AffineTransform caff = new AffineTransform();
            caff.scale(cal.pixelWidth, cal.pixelHeight);
            if (M.isAreaROI(roi)) {
                Area area = M.getArea(roi);
                area = area.createTransformedArea(caff);
                ResultsTable rt = Utils.createResultsTable("ROI area", new String[] { "area", "perimeter" });
                rt.incrementCounter();
                rt.addLabel("units", cal.getUnit());
                rt.addValue(0, Math.abs(AreaCalculations.area(area.getPathIterator(null))));
                rt.addValue(1, roi.getLength());
                rt.show("ROI area");
            } else {
                ResultsTable rt = Utils.createResultsTable("ROI length", new String[] { "length" });
                rt.incrementCounter();
                rt.addLabel("units", cal.getUnit());
                rt.addValue(0, roi.getLength());
                rt.show("ROI length");
            }
            return null;
        } else if (null != active) {
            // Measure the active displayable
            if (active.getClass() == Patch.class) {
                // measure like 'm' would in ImageJ for an image
                ImagePlus imp = ((Patch) active).getImagePlus();
                imp.setCalibration(active.getLayer().getParent().getCalibrationCopy());
                IJ.run(imp, "Measure", "");
            } else {
                // Call measure like ProjectThing does
                ProjectThing pt = active.getProject().findProjectThing(active);
                if (active instanceof Profile)
                    ((ProjectThing) pt.getParent()).measure();
                else
                    pt.measure();
            }
            return null;
        }
        Utils.log("Draw a ROI or select an object!");
        return null;
    } else if (in(command, new String[] { "Analyze Particles...", "Histogram", "Plot Profile", "Surface Plot...", "Color Inspector 3D", "3D Surface Plot", "Color Histogram" })) {
        return setTempCurrentImage(command, active);
    } else if (command.equals("Label")) {
        notAvailable(command);
        return null;
    } else // PLUGINS menu
    if (command.equals("Volume Viewer")) {
        return runOnVirtualLayerSet(command, layer_set, display);
    } else if (command.equals("3D Viewer")) {
        // it's virtual and non-caching, will appear as a regular ImageJ stack
        layer_set.createLayerStack(Displayable.class, ImagePlus.COLOR_RGB, display.getDisplayChannelAlphas()).getImagePlus().show();
        return command;
    } else // PROCESS menu and submenus
    if (in(command, new String[] { "FFT", "Fast FFT (2D/3D)" })) {
        return setTempCurrentImage(command, active);
    } else if (in(command, new String[] { "Bandpass Filter...", "Custom Filter...", "FD Math...", "Swap Quadrants", "Convolve...", "Gaussian Blur...", "Median...", "Mean...", "Minimum...", "Maximum...", "Unsharp Mask...", "Variance...", "Show Circular Masks...", "Subtract Background..." })) {
        return duplicate(command, active);
    } else if (in(command, new String[] { "Smooth", "Sharpen", "Find Edges", "Enhance Contrast", "Add Noise", "Add Specified Noise...", "Salt and Pepper", "Despeckle", "Remove Outliers...", "North", "Northeast", "East", "Southeast", "South", "Southwest", "West", "Northwest", "Make Binary", "Convert to Mask", "Find Maxima...", "Erode", "Dilate", "Open ", "Close-", "Outline", "Fill Holes", "Skeletonize", "Distance Map", "Ultimate Points", "Watershed", "Add...", "Subtract...", "Multiply...", "Divide...", "AND...", "OR...", "XOR...", "Min...", "Max...", "Gamma...", "Log", "Exp", "Square", "Square Root", "Reciprocal", "NaN Background", "Abs" })) {
        return duplicate(command, active);
    }
    /*else {
			// continue happily
			//Utils.log2("Skipping " + command);
		}*/
    // If it's part of "Save As", ignore it
    Menu menu = Menus.getSaveAsMenu();
    for (int i = menu.getItemCount() - 1; i > -1; i--) {
        if (command.equals(menu.getItem(i).getActionCommand())) {
            notAvailable(command);
            return null;
        }
    }
    // Give it back to ImageJ
    return command;
}
Also used : Rectangle(java.awt.Rectangle) Calibration(ij.measure.Calibration) ImagePlus(ij.ImagePlus) Roi(ij.gui.Roi) Project(ini.trakem2.Project) Area(java.awt.geom.Area) ProjectTree(ini.trakem2.tree.ProjectTree) AffineTransform(java.awt.geom.AffineTransform) ResultsTable(ij.measure.ResultsTable) Menu(java.awt.Menu) ProjectThing(ini.trakem2.tree.ProjectThing)

Example 19 with LayerSet

use of ini.trakem2.display.LayerSet in project TrakEM2 by trakem2.

the class Loader method insertGrid.

/**
 * Insert grid in layer (with optional stitching)
 *
 * @param layer The Layer to inser the grid into
 * @param dir The base dir of the images to open
 * @param first_image_name name of the first image in the list
 * @param cols The list of columns, containing each an array of String file names in each column.
 * @param bx The top-left X coordinate of the grid to insert
 * @param by The top-left Y coordinate of the grid to insert
 * @param bt_overlap bottom-top overlap of the images
 * @param lr_overlap left-right overlap of the images
 * @param link_images Link images to their neighbors
 * @param stitch_tiles montage option
 * @param cc_percent_overlap tiles overlap
 * @param cc_scale tiles scaling previous to stitching (1 = no scaling)
 * @param min_R regression threshold (minimum acceptable R)
 * @param homogenize_contrast contrast homogenization option
 * @param stitching_rule stitching rule (upper left corner or free)
 */
private void insertGrid(final Layer layer, final String dir_, final String first_image_name, final int n_images, final ArrayList<String[]> cols, final double bx, final double by, final double bt_overlap, final double lr_overlap, final boolean link_images, final boolean stitch_tiles, final boolean homogenize_contrast, final StitchingTEM.PhaseCorrelationParam pc_param, final Worker worker) {
    // create a Worker, then give it to the Bureaucrat
    try {
        String dir = dir_;
        final ArrayList<Patch> al = new ArrayList<Patch>();
        Utils.showProgress(0.0D);
        // less repaints on IJ status bar
        opener.setSilentMode(true);
        int x = 0;
        int y = 0;
        int largest_y = 0;
        ImagePlus img = null;
        // open the selected image, to use as reference for width and height
        // w1nd0wz safe
        dir = dir.replace('\\', '/');
        if (!dir.endsWith("/"))
            dir += "/";
        String path = dir + first_image_name;
        // TODO arbitrary x3 factor
        releaseToFit(new File(path).length() * 3);
        IJ.redirectErrorMessages();
        ImagePlus first_img = openImagePlus(path);
        if (null == first_img) {
            Utils.log("Selected image to open first is null.");
            return;
        }
        if (null == first_img)
            return;
        final int first_image_width = first_img.getWidth();
        final int first_image_height = first_img.getHeight();
        final int first_image_type = first_img.getType();
        // start
        final Patch[][] pall = new Patch[cols.size()][((String[]) cols.get(0)).length];
        int width, height;
        // counter
        int k = 0;
        boolean auto_fix_all = false;
        boolean ignore_all = false;
        boolean resize = false;
        if (!ControlWindow.isGUIEnabled()) {
            // headless mode: autofix all
            auto_fix_all = true;
            resize = true;
        }
        // Accumulate mipmap generation tasks
        final ArrayList<Future<?>> fus = new ArrayList<Future<?>>();
        startLargeUpdate();
        for (int i = 0; i < cols.size(); i++) {
            final String[] rows = (String[]) cols.get(i);
            if (i > 0) {
                x -= lr_overlap;
            }
            for (int j = 0; j < rows.length; j++) {
                if (Thread.currentThread().isInterrupted()) {
                    Display.repaint(layer);
                    rollback();
                    return;
                }
                if (j > 0) {
                    y -= bt_overlap;
                }
                // get file name
                final String file_name = (String) rows[j];
                path = dir + file_name;
                if (null != first_img && file_name.equals(first_image_name)) {
                    img = first_img;
                    // release pointer
                    first_img = null;
                } else {
                    // open image
                    releaseToFit(first_image_width, first_image_height, first_image_type, 1.5f);
                    try {
                        IJ.redirectErrorMessages();
                        img = openImagePlus(path);
                    } catch (final OutOfMemoryError oome) {
                        printMemState();
                        throw oome;
                    }
                }
                if (null == img) {
                    Utils.log("null image! skipping.");
                    pall[i][j] = null;
                    continue;
                }
                width = img.getWidth();
                height = img.getHeight();
                int rw = width;
                int rh = height;
                if (width != first_image_width || height != first_image_height) {
                    int new_width = first_image_width;
                    int new_height = first_image_height;
                    if (!auto_fix_all && !ignore_all) {
                        final GenericDialog gdr = new GenericDialog("Size mismatch!");
                        gdr.addMessage("The size of " + file_name + " is " + width + " x " + height);
                        gdr.addMessage("but the selected image was " + first_image_width + " x " + first_image_height);
                        gdr.addMessage("Adjust to selected image dimensions?");
                        gdr.addNumericField("width: ", (double) first_image_width, 0);
                        // should not be editable ... or at least, explain in some way that the dimensions can be edited just for this image --> done below
                        gdr.addNumericField("height: ", (double) first_image_height, 0);
                        gdr.addMessage("[If dimensions are changed they will apply only to this image]");
                        gdr.addMessage("");
                        final String[] au = new String[] { "fix all", "ignore all" };
                        gdr.addChoice("Automate:", au, au[1]);
                        gdr.addMessage("Cancel == NO    OK = YES");
                        gdr.showDialog();
                        if (gdr.wasCanceled()) {
                            resize = false;
                        // do nothing: don't fix/resize
                        }
                        resize = true;
                        // catch values
                        new_width = (int) gdr.getNextNumber();
                        new_height = (int) gdr.getNextNumber();
                        final int iau = gdr.getNextChoiceIndex();
                        if (new_width != first_image_width || new_height != first_image_height) {
                            auto_fix_all = false;
                        } else {
                            auto_fix_all = (0 == iau);
                        }
                        ignore_all = (1 == iau);
                        if (ignore_all)
                            resize = false;
                    }
                    if (resize) {
                        // resize Patch dimensions
                        rw = first_image_width;
                        rh = first_image_height;
                    }
                }
                // add new Patch at base bx,by plus the x,y of the grid
                // will call back and cache the image
                final Patch patch = new Patch(layer.getProject(), img.getTitle(), bx + x, by + y, img);
                if (width != rw || height != rh)
                    patch.setDimensions(rw, rh, false);
                addedPatchFrom(path, patch);
                if (// prevent it
                homogenize_contrast)
                    // prevent it
                    setMipMapsRegeneration(false);
                else
                    fus.add(regenerateMipMaps(patch));
                // 
                // after the above two lines! Otherwise it will paint fine, but throw exceptions on the way
                layer.add(patch, true);
                // otherwise when reopening it has to fetch all ImagePlus and scale and zip them all! This method though creates the awt and the snap, thus filling up memory and slowing down, but it's worth it.
                patch.updateInDatabase("tiff_snapshot");
                pall[i][j] = patch;
                al.add(patch);
                if (ControlWindow.isGUIEnabled()) {
                    // northwest to prevent screwing up Patch coordinates.
                    layer.getParent().enlargeToFit(patch, LayerSet.NORTHWEST);
                }
                y += img.getHeight();
                Utils.showProgress((double) k / n_images);
                k++;
            }
            x += img.getWidth();
            if (largest_y < y) {
                largest_y = y;
            }
            // resetting!
            y = 0;
        }
        // build list
        final Patch[] pa = new Patch[al.size()];
        int f = 0;
        // list in row-first order
        for (int j = 0; j < pall[0].length; j++) {
            // 'j' is row
            for (int i = 0; i < pall.length; i++) {
                // 'i' is column
                pa[f++] = pall[i][j];
            }
        }
        // optimize repaints: all to background image
        Display.clearSelection(layer);
        // make the first one be top, and the rest under it in left-right and top-bottom order
        for (int j = 0; j < pa.length; j++) {
            layer.moveBottom(pa[j]);
        }
        // make picture
        // getFlatImage(layer, layer.getMinimalBoundingBox(Patch.class), 0.25, 1, ImagePlus.GRAY8, Patch.class, null, false).show();
        // optimize repaints: all to background image
        Display.clearSelection(layer);
        if (homogenize_contrast) {
            if (null != worker)
                worker.setTaskName("Enhancing contrast");
            // 0 - check that all images are of the same type
            int tmp_type = pa[0].getType();
            for (int e = 1; e < pa.length; e++) {
                if (pa[e].getType() != tmp_type) {
                    // can't continue
                    tmp_type = Integer.MAX_VALUE;
                    Utils.log("Can't homogenize histograms: images are not all of the same type.\nFirst offending image is: " + al.get(e));
                    break;
                }
            }
            if (Integer.MAX_VALUE != tmp_type) {
                // checking on error flag
                // Set min and max for all images
                // 1 - fetch statistics for each image
                final ArrayList<ImageStatistics> al_st = new ArrayList<ImageStatistics>();
                // list of Patch ordered by stdDev ASC
                final ArrayList<Patch> al_p = new ArrayList<Patch>();
                int type = -1;
                for (int i = 0; i < pa.length; i++) {
                    if (Thread.currentThread().isInterrupted()) {
                        Display.repaint(layer);
                        rollback();
                        return;
                    }
                    ImagePlus imp = fetchImagePlus(pa[i]);
                    // speed-up trick: extract data from smaller image
                    if (imp.getWidth() > 1024) {
                        releaseToFit(1024, (int) ((imp.getHeight() * 1024) / imp.getWidth()), imp.getType(), 1.1f);
                        // cheap and fast nearest-point resizing
                        imp = new ImagePlus(imp.getTitle(), imp.getProcessor().resize(1024));
                    }
                    if (-1 == type)
                        type = imp.getType();
                    final ImageStatistics i_st = imp.getStatistics();
                    // order by stdDev, from small to big
                    int q = 0;
                    for (final ImageStatistics st : al_st) {
                        q++;
                        if (st.stdDev > i_st.stdDev)
                            break;
                    }
                    if (q == al.size()) {
                        // append at the end. WARNING if importing thousands of images, this is a potential source of out of memory errors. I could just recompute it when I needed it again below
                        al_st.add(i_st);
                        al_p.add(pa[i]);
                    } else {
                        al_st.add(q, i_st);
                        al_p.add(q, pa[i]);
                    }
                }
                // shallow copy of the ordered list
                final ArrayList<Patch> al_p2 = new ArrayList<Patch>(al_p);
                // 2 - discard the first and last 25% (TODO: a proper histogram clustering analysis and histogram examination should apply here)
                if (pa.length > 3) {
                    // under 4 images, use them all
                    int i = 0;
                    while (i <= pa.length * 0.25) {
                        al_p.remove(i);
                        i++;
                    }
                    final int count = i;
                    i = pa.length - 1 - count;
                    while (i > (pa.length * 0.75) - count) {
                        al_p.remove(i);
                        i--;
                    }
                }
                // 3 - compute common histogram for the middle 50% images
                final Patch[] p50 = new Patch[al_p.size()];
                al_p.toArray(p50);
                final StackStatistics stats = new StackStatistics(new PatchStack(p50, 1));
                // 4 - compute autoAdjust min and max values
                // extracting code from ij.plugin.frame.ContrastAdjuster, method autoAdjust
                int autoThreshold = 0;
                double min = 0;
                double max = 0;
                // once for 8-bit and color, twice for 16 and 32-bit (thus the 2501 autoThreshold value)
                final int limit = stats.pixelCount / 10;
                final int[] histogram = stats.histogram;
                // else autoThreshold /= 2;
                if (ImagePlus.GRAY16 == type || ImagePlus.GRAY32 == type)
                    autoThreshold = 2500;
                else
                    autoThreshold = 5000;
                final int threshold = stats.pixelCount / autoThreshold;
                int i = -1;
                boolean found = false;
                int count;
                do {
                    i++;
                    count = histogram[i];
                    if (count > limit)
                        count = 0;
                    found = count > threshold;
                } while (!found && i < 255);
                final int hmin = i;
                i = 256;
                do {
                    i--;
                    count = histogram[i];
                    if (count > limit)
                        count = 0;
                    found = count > threshold;
                } while (!found && i > 0);
                final int hmax = i;
                if (hmax >= hmin) {
                    min = stats.histMin + hmin * stats.binSize;
                    max = stats.histMin + hmax * stats.binSize;
                    if (min == max) {
                        min = stats.min;
                        max = stats.max;
                    }
                }
                // 5 - compute common mean within min,max range
                final double target_mean = getMeanOfRange(stats, min, max);
                Utils.log2("Loader min,max: " + min + ", " + max + ",   target mean: " + target_mean);
                // 6 - apply to all
                for (i = al_p2.size() - 1; i > -1; i--) {
                    // the order is different, thus getting it from the proper list
                    final Patch p = (Patch) al_p2.get(i);
                    final double dm = target_mean - getMeanOfRange((ImageStatistics) al_st.get(i), min, max);
                    // displacing in the opposite direction, makes sense, so that the range is drifted upwards and thus the target 256 range for an awt.Image will be closer to the ideal target_mean
                    p.setMinAndMax(min - dm, max - dm);
                // OBSOLETE and wrong //p.putMinAndMax(fetchImagePlus(p));
                }
                setMipMapsRegeneration(true);
                if (isMipMapsRegenerationEnabled()) {
                    // recreate files
                    for (final Patch p : al) fus.add(regenerateMipMaps(p));
                }
                Display.repaint(layer, new Rectangle(0, 0, (int) layer.getParent().getLayerWidth(), (int) layer.getParent().getLayerHeight()), 0);
            // make picture
            // getFlatImage(layer, layer.getMinimalBoundingBox(Patch.class), 0.25, 1, ImagePlus.GRAY8, Patch.class, null, false).show();
            }
        }
        if (stitch_tiles) {
            // Wait until all mipmaps for the new images have been generated before attempting to register
            Utils.wait(fus);
            // create undo
            layer.getParent().addTransformStep(new HashSet<Displayable>(layer.getDisplayables(Patch.class)));
            // wait until repainting operations have finished (otherwise, calling crop on an ImageProcessor fails with out of bounds exception sometimes)
            if (null != Display.getFront())
                Display.getFront().getCanvas().waitForRepaint();
            if (null != worker)
                worker.setTaskName("Stitching");
            StitchingTEM.stitch(pa, cols.size(), bt_overlap, lr_overlap, true, pc_param).run();
        }
        // link with images on top, bottom, left and right.
        if (link_images) {
            if (null != worker)
                worker.setTaskName("Linking");
            for (int i = 0; i < pall.length; i++) {
                // 'i' is column
                for (int j = 0; j < pall[0].length; j++) {
                    // 'j' is row
                    final Patch p = pall[i][j];
                    // can happen if a slot is empty
                    if (null == p)
                        continue;
                    if (i > 0 && null != pall[i - 1][j])
                        p.link(pall[i - 1][j]);
                    if (i < pall.length - 1 && null != pall[i + 1][j])
                        p.link(pall[i + 1][j]);
                    if (j > 0 && null != pall[i][j - 1])
                        p.link(pall[i][j - 1]);
                    if (j < pall[0].length - 1 && null != pall[i][j + 1])
                        p.link(pall[i][j + 1]);
                }
            }
        }
        commitLargeUpdate();
        // resize LayerSet
        // int new_width = x;
        // int new_height = largest_y;
        // Math.abs(bx) + new_width, Math.abs(by) + new_height);
        layer.getParent().setMinimumDimensions();
        // update indexes
        // so its done once only
        layer.updateInDatabase("stack_index");
        // create panels in all Displays showing this layer
        /* // not needed anymore
Iterator it = al.iterator();
while (it.hasNext()) {
	Display.add(layer, (Displayable)it.next(), false); // don't set it active, don't want to reload the ImagePlus!
}
			 */
        // update Displays
        Display.update(layer);
        layer.recreateBuckets();
    // debug:
    } catch (final Throwable t) {
        IJError.print(t);
        rollback();
        setMipMapsRegeneration(true);
    }
}
Also used : ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) GenericDialog(ij.gui.GenericDialog) ZDisplayable(ini.trakem2.display.ZDisplayable) Displayable(ini.trakem2.display.Displayable) StackStatistics(ij.process.StackStatistics) ImagePlus(ij.ImagePlus) PatchStack(ini.trakem2.imaging.PatchStack) ImageStatistics(ij.process.ImageStatistics) Future(java.util.concurrent.Future) Patch(ini.trakem2.display.Patch) File(java.io.File)

Example 20 with LayerSet

use of ini.trakem2.display.LayerSet in project TrakEM2 by trakem2.

the class Loader method importStack.

/**
 * Imports an image stack from a multitiff file and places each slice in the proper layer, creating new layers as it goes. If the given stack is null, popup a file dialog to choose one
 */
public Bureaucrat importStack(final Layer first_layer, final double x, final double y, final ImagePlus imp_stack_, final boolean ask_for_data, final String filepath_, final boolean one_patch_per_layer_) {
    Utils.log2("Loader.importStack filepath: " + filepath_);
    if (null == first_layer)
        return null;
    final Worker worker = new Worker("import stack") {

        @Override
        public void run() {
            startedWorking();
            try {
                String filepath = filepath_;
                boolean one_patch_per_layer = one_patch_per_layer_;
                /* On drag and drop the stack is not null! */
                // Utils.log2("imp_stack_ is " + imp_stack_);
                ImagePlus[] stks = null;
                boolean choose = false;
                if (null == imp_stack_) {
                    stks = Utils.findOpenStacks();
                    choose = null == stks || stks.length > 0;
                } else {
                    stks = new ImagePlus[] { imp_stack_ };
                }
                ImagePlus imp_stack = null;
                // ask to open a stack if it's null
                if (null == stks) {
                    // choose one
                    imp_stack = openStack();
                } else if (choose) {
                    // choose one from the list
                    final GenericDialog gd = new GenericDialog("Choose one");
                    gd.addMessage("Choose a stack from the list or 'open...' to bring up a file chooser dialog:");
                    final String[] list = new String[stks.length + 1];
                    for (int i = 0; i < list.length - 1; i++) {
                        list[i] = stks[i].getTitle();
                    }
                    list[list.length - 1] = "[  Open stack...  ]";
                    gd.addChoice("choose stack: ", list, list[0]);
                    gd.showDialog();
                    if (gd.wasCanceled()) {
                        finishedWorking();
                        return;
                    }
                    final int i_choice = gd.getNextChoiceIndex();
                    if (list.length - 1 == i_choice) {
                        // the open... command
                        imp_stack = first_layer.getProject().getLoader().openStack();
                    } else {
                        imp_stack = stks[i_choice];
                    }
                } else {
                    imp_stack = imp_stack_;
                }
                // check:
                if (null == imp_stack) {
                    finishedWorking();
                    return;
                }
                final String props = (String) imp_stack.getProperty("Info");
                // check if it's amira labels stack to prevent missimports
                if (null != props && -1 != props.indexOf("Materials {")) {
                    final YesNoDialog yn = new YesNoDialog(IJ.getInstance(), "Warning", "You are importing a stack of Amira labels as a regular image stack. Continue anyway?");
                    if (!yn.yesPressed()) {
                        finishedWorking();
                        return;
                    }
                }
                // String dir = imp_stack.getFileInfo().directory;
                final double layer_width = first_layer.getLayerWidth();
                final double layer_height = first_layer.getLayerHeight();
                final double current_thickness = first_layer.getThickness();
                double thickness = current_thickness;
                boolean expand_layer_set = false;
                boolean lock_stack = false;
                // int anchor = LayerSet.NORTHWEST; //default
                if (ask_for_data) {
                    // ask for slice separation in pixels
                    final GenericDialog gd = new GenericDialog("Slice separation?");
                    gd.addMessage("Please enter the slice thickness, in pixels");
                    // assuming pixelWidth == pixelHeight
                    gd.addNumericField("slice_thickness: ", Math.abs(imp_stack.getCalibration().pixelDepth / imp_stack.getCalibration().pixelHeight), 3);
                    if (layer_width != imp_stack.getWidth() || layer_height != imp_stack.getHeight()) {
                        gd.addCheckbox("Resize canvas to fit stack", true);
                    // gd.addChoice("Anchor: ", LayerSet.ANCHORS, LayerSet.ANCHORS[0]);
                    }
                    gd.addCheckbox("Lock stack", false);
                    final String[] importStackTypes = { "One slice per layer (Patches)", "Image volume (Stack)" };
                    if (imp_stack.getStack().isVirtual()) {
                        one_patch_per_layer = true;
                    }
                    gd.addChoice("Import stack as:", importStackTypes, importStackTypes[0]);
                    ((Component) gd.getChoices().get(0)).setEnabled(!imp_stack.getStack().isVirtual());
                    gd.showDialog();
                    if (gd.wasCanceled()) {
                        if (null == stks) {
                            // flush only if it was not open before
                            flush(imp_stack);
                        }
                        finishedWorking();
                        return;
                    }
                    if (layer_width != imp_stack.getWidth() || layer_height != imp_stack.getHeight()) {
                        expand_layer_set = gd.getNextBoolean();
                    // anchor = gd.getNextChoiceIndex();
                    }
                    lock_stack = gd.getNextBoolean();
                    thickness = gd.getNextNumber();
                    // check provided thickness with that of the first layer:
                    if (thickness != current_thickness) {
                        if (1 == first_layer.getParent().size() && first_layer.isEmpty()) {
                            final YesNoCancelDialog yn = new YesNoCancelDialog(IJ.getInstance(), "Mismatch!", "The current layer's thickness is " + current_thickness + "\nwhich is " + (thickness < current_thickness ? "larger" : "smaller") + " than\nthe desired " + thickness + " for each stack slice.\nAdjust current layer's thickness to " + thickness + " ?");
                            if (yn.cancelPressed()) {
                                // was opened new
                                if (null != imp_stack_)
                                    flush(imp_stack);
                                finishedWorking();
                                return;
                            } else if (yn.yesPressed()) {
                                first_layer.setThickness(thickness);
                            // The rest of layers, created new, will inherit the same thickness
                            }
                        } else {
                            final YesNoDialog yn = new YesNoDialog(IJ.getInstance(), "WARNING", "There's more than one layer or the current layer is not empty\nso the thickness cannot be adjusted. Proceed anyway?");
                            if (!yn.yesPressed()) {
                                finishedWorking();
                                return;
                            }
                        }
                    }
                    one_patch_per_layer = imp_stack.getStack().isVirtual() || 0 == gd.getNextChoiceIndex();
                }
                if (null == imp_stack.getStack()) {
                    Utils.showMessage("Not a stack.");
                    finishedWorking();
                    return;
                }
                // WARNING: there are fundamental issues with calibration, because the Layer thickness is disconnected from the Calibration pixelDepth
                // set LayerSet calibration if there is no calibration
                boolean calibrate = true;
                if (ask_for_data && first_layer.getParent().isCalibrated()) {
                    if (!ControlWindow.isGUIEnabled()) {
                        Utils.log2("Loader.importStack: overriding LayerSet calibration with that of the imported stack.");
                    } else {
                        final YesNoDialog yn = new YesNoDialog("Calibration", "The layer set is already calibrated. Override with the stack calibration values?");
                        if (!yn.yesPressed()) {
                            calibrate = false;
                        }
                    }
                }
                if (calibrate) {
                    first_layer.getParent().setCalibration(imp_stack.getCalibration());
                }
                if (layer_width < imp_stack.getWidth() || layer_height < imp_stack.getHeight()) {
                    expand_layer_set = true;
                }
                if (imp_stack.getStack().isVirtual()) {
                // do nothing
                } else if (null == filepath) {
                    // try to get it from the original FileInfo
                    final FileInfo fi = imp_stack.getOriginalFileInfo();
                    if (null != fi && null != fi.directory && null != fi.fileName) {
                        filepath = fi.directory.replace('\\', '/');
                        if (!filepath.endsWith("/"))
                            filepath += '/';
                        filepath += fi.fileName;
                    }
                    Utils.log2("Getting filepath from FileInfo: " + filepath);
                    // check that file exists, otherwise save a copy in the storage folder
                    if (null == filepath || (!filepath.startsWith("http://") && !new File(filepath).exists())) {
                        filepath = handlePathlessImage(imp_stack);
                    }
                } else {
                    filepath = filepath.replace('\\', '/');
                }
                // Import as Stack ZDisplayable object:
                if (!one_patch_per_layer) {
                    final Stack st = new Stack(first_layer.getProject(), new File(filepath).getName(), x, y, first_layer, filepath);
                    first_layer.getParent().add(st);
                    finishedWorking();
                    return;
                }
                // Place the first slice in the current layer, and then query the parent LayerSet for subsequent layers, and create them if not present.
                final Patch last_patch = Loader.this.importStackAsPatches(first_layer.getProject(), first_layer, x, y, imp_stack, null != imp_stack_ && null != imp_stack_.getCanvas(), filepath);
                if (null != last_patch) {
                    last_patch.setLocked(lock_stack);
                    Display.updateCheckboxes(last_patch.getLinkedGroup(null), DisplayablePanel.LOCK_STATE, true);
                }
                if (expand_layer_set) {
                    last_patch.getLayer().getParent().setMinimumDimensions();
                }
                Utils.log2("props: " + props);
                // check if it's an amira stack, then ask to import labels
                if (null != props && -1 == props.indexOf("Materials {") && -1 != props.indexOf("CoordType")) {
                    final YesNoDialog yn = new YesNoDialog(IJ.getInstance(), "Amira Importer", "Import labels as well?");
                    if (yn.yesPressed()) {
                        // select labels
                        final Collection<AreaList> alis = AmiraImporter.importAmiraLabels(first_layer, last_patch.getX(), last_patch.getY(), imp_stack.getOriginalFileInfo().directory);
                        if (null != alis) {
                            // import all created AreaList as nodes in the ProjectTree under a new imported_segmentations node
                            first_layer.getProject().getProjectTree().insertSegmentations(alis);
                            // link them to the images
                            for (final AreaList ali : alis) {
                                ali.linkPatches();
                            }
                        }
                    }
                }
            // it is safe not to flush the imp_stack, because all its resources are being used anyway (all the ImageProcessor), and it has no awt.Image. Unless it's being shown in ImageJ, and then it will be flushed on its own when the user closes its window.
            } catch (final Exception e) {
                IJError.print(e);
            }
            finishedWorking();
        }
    };
    return Bureaucrat.createAndStart(worker, first_layer.getProject());
}
Also used : AreaList(ini.trakem2.display.AreaList) ImagePlus(ij.ImagePlus) IOException(java.io.IOException) FormatException(loci.formats.FormatException) LazyVirtualStack(ini.trakem2.imaging.LazyVirtualStack) PatchStack(ini.trakem2.imaging.PatchStack) ImageStack(ij.ImageStack) VirtualStack(ij.VirtualStack) Stack(ini.trakem2.display.Stack) FileInfo(ij.io.FileInfo) GenericDialog(ij.gui.GenericDialog) YesNoDialog(ini.trakem2.display.YesNoDialog) Worker(ini.trakem2.utils.Worker) YesNoCancelDialog(ij.gui.YesNoCancelDialog) Component(java.awt.Component) File(java.io.File) Patch(ini.trakem2.display.Patch)

Aggregations

ArrayList (java.util.ArrayList)24 Layer (ini.trakem2.display.Layer)22 LayerSet (ini.trakem2.display.LayerSet)20 HashMap (java.util.HashMap)20 HashSet (java.util.HashSet)19 Rectangle (java.awt.Rectangle)14 Patch (ini.trakem2.display.Patch)13 ImagePlus (ij.ImagePlus)11 GenericDialog (ij.gui.GenericDialog)11 ProjectThing (ini.trakem2.tree.ProjectThing)11 AffineTransform (java.awt.geom.AffineTransform)11 Map (java.util.Map)11 Future (java.util.concurrent.Future)11 Displayable (ini.trakem2.display.Displayable)10 ZDisplayable (ini.trakem2.display.ZDisplayable)10 Area (java.awt.geom.Area)10 Worker (ini.trakem2.utils.Worker)9 Point (java.awt.Point)9 TreeMap (java.util.TreeMap)9 DBObject (ini.trakem2.persistence.DBObject)8