Search in sources :

Example 66 with Patch

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

the class DistortionCorrectionTask method run.

public static final void run(final CorrectDistortionFromSelectionParam p, final List<Patch> patches, final Displayable active, final Layer layer, final Worker worker) {
    /* no multiple inheritance, so p cannot be an Align.ParamOptimize, working around legacy by copying data into one ... */
    final Align.ParamOptimize ap = new Align.ParamOptimize();
    ap.sift.set(p.sift);
    ap.desiredModelIndex = p.desiredModelIndex;
    ap.expectedModelIndex = p.expectedModelIndex;
    ap.maxEpsilon = p.maxEpsilon;
    ap.minInlierRatio = p.minInlierRatio;
    ap.rod = p.rod;
    ap.identityTolerance = p.identityTolerance;
    ap.lambda = p.lambdaRegularize;
    ap.maxIterations = p.maxIterationsOptimize;
    ap.maxPlateauwidth = p.maxPlateauwidthOptimize;
    ap.minNumInliers = p.minNumInliers;
    ap.regularize = p.regularize;
    ap.regularizerModelIndex = p.regularizerIndex;
    ap.rejectIdentity = p.rejectIdentity;
    /**
     * Get all patches that will be affected.
     */
    final List<Patch> allPatches = new ArrayList<Patch>();
    for (final Layer l : layer.getParent().getLayers().subList(p.firstLayerIndex, p.lastLayerIndex + 1)) for (final Displayable d : l.getDisplayables(Patch.class)) allPatches.add((Patch) d);
    /**
     * Unset the coordinate transforms of all patches if desired.
     */
    if (p.clearTransform) {
        if (worker != null)
            worker.setTaskName("Clearing present transforms");
        setCoordinateTransform(allPatches, null, Runtime.getRuntime().availableProcessors());
        Display.repaint();
    }
    if (worker != null)
        worker.setTaskName("Establishing SIFT correspondences");
    final List<AbstractAffineTile2D<?>> tiles = new ArrayList<AbstractAffineTile2D<?>>();
    final List<AbstractAffineTile2D<?>> fixedTiles = new ArrayList<AbstractAffineTile2D<?>>();
    final List<Patch> fixedPatches = new ArrayList<Patch>();
    if (active != null && active instanceof Patch)
        fixedPatches.add((Patch) active);
    Align.tilesFromPatches(ap, patches, fixedPatches, tiles, fixedTiles);
    final List<AbstractAffineTile2D<?>[]> tilePairs = new ArrayList<AbstractAffineTile2D<?>[]>();
    if (p.tilesAreInPlace)
        AbstractAffineTile2D.pairOverlappingTiles(tiles, tilePairs);
    else
        AbstractAffineTile2D.pairTiles(tiles, tilePairs);
    AbstractAffineTile2D<?> fixedTile = null;
    if (fixedTiles.size() > 0)
        fixedTile = fixedTiles.get(0);
    else
        fixedTile = tiles.get(0);
    Align.connectTilePairs(ap, tiles, tilePairs, p.maxNumThreadsSift, p.multipleHypotheses);
    /**
     * Shift all local coordinates into the original image frame
     */
    for (final AbstractAffineTile2D<?> tile : tiles) {
        final Rectangle box = tile.getPatch().getCoordinateTransformBoundingBox();
        for (final PointMatch m : tile.getMatches()) {
            final double[] l = m.getP1().getL();
            final double[] w = m.getP1().getW();
            l[0] += box.x;
            l[1] += box.y;
            w[0] = l[0];
            w[1] = l[1];
        }
    }
    if (Thread.currentThread().isInterrupted())
        return;
    final List<Set<Tile<?>>> graphs = AbstractAffineTile2D.identifyConnectedGraphs(tiles);
    if (graphs.size() > 1)
        Utils.log("Could not interconnect all images with correspondences.  ");
    final List<AbstractAffineTile2D<?>> interestingTiles;
    /**
     * Find largest graph.
     */
    Set<Tile<?>> largestGraph = null;
    for (final Set<Tile<?>> graph : graphs) if (largestGraph == null || largestGraph.size() < graph.size())
        largestGraph = graph;
    interestingTiles = new ArrayList<AbstractAffineTile2D<?>>();
    for (final Tile<?> t : largestGraph) interestingTiles.add((AbstractAffineTile2D<?>) t);
    if (Thread.currentThread().isInterrupted())
        return;
    Utils.log("Estimating lens model:");
    /* initialize with pure affine */
    Align.optimizeTileConfiguration(ap, interestingTiles, fixedTiles);
    /* measure the current error */
    double e = 0;
    int n = 0;
    for (final AbstractAffineTile2D<?> t : interestingTiles) for (final PointMatch pm : t.getMatches()) {
        e += pm.getDistance();
        ++n;
    }
    e /= n;
    double dEpsilon_i = 0;
    double epsilon_i = e;
    double dEpsilon_0 = 0;
    NonLinearTransform lensModel = null;
    Utils.log("0: epsilon = " + e);
    /* Store original point locations */
    final HashMap<Point, Point> originalPoints = new HashMap<Point, Point>();
    for (final AbstractAffineTile2D<?> t : interestingTiles) for (final PointMatch pm : t.getMatches()) originalPoints.put(pm.getP1(), pm.getP1().clone());
    /* ad hoc conditions to terminate iteration:
		 * small improvement ( 1/1000) relative to first iteration
		 * less than 20 iterations
		 * at least 2 iterations */
    for (int i = 1; i < 20 && (i < 2 || dEpsilon_i <= dEpsilon_0 / 1000); ++i) {
        if (Thread.currentThread().isInterrupted())
            return;
        /* Some data shuffling for the lens correction interface */
        final List<PointMatchCollectionAndAffine> matches = new ArrayList<PointMatchCollectionAndAffine>();
        for (final AbstractAffineTile2D<?>[] tilePair : tilePairs) {
            final AffineTransform a = tilePair[0].createAffine();
            a.preConcatenate(tilePair[1].getModel().createInverseAffine());
            final Collection<PointMatch> commonMatches = new ArrayList<PointMatch>();
            tilePair[0].commonPointMatches(tilePair[1], commonMatches);
            final Collection<PointMatch> originalCommonMatches = new ArrayList<PointMatch>();
            for (final PointMatch pm : commonMatches) originalCommonMatches.add(new PointMatch(originalPoints.get(pm.getP1()), originalPoints.get(pm.getP2())));
            matches.add(new PointMatchCollectionAndAffine(a, originalCommonMatches));
        }
        if (worker != null)
            worker.setTaskName("Estimating lens distortion correction");
        lensModel = Distortion_Correction.createInverseDistortionModel(matches, p.dimension, p.lambda, (int) fixedTile.getWidth(), (int) fixedTile.getHeight());
        /* update local points */
        for (final AbstractAffineTile2D<?> t : interestingTiles) for (final PointMatch pm : t.getMatches()) {
            final Point currentPoint = pm.getP1();
            final Point originalPoint = originalPoints.get(currentPoint);
            final double[] l = currentPoint.getL();
            final double[] lo = originalPoint.getL();
            l[0] = lo[0];
            l[1] = lo[1];
            lensModel.applyInPlace(l);
        }
        /* re-optimize */
        Align.optimizeTileConfiguration(ap, interestingTiles, fixedTiles);
        /* measure the current error */
        e = 0;
        n = 0;
        for (final AbstractAffineTile2D<?> t : interestingTiles) for (final PointMatch pm : t.getMatches()) {
            e += pm.getDistance();
            ++n;
        }
        e /= n;
        dEpsilon_i = e - epsilon_i;
        epsilon_i = e;
        if (i == 1)
            dEpsilon_0 = dEpsilon_i;
        Utils.log(i + ": epsilon = " + e);
        Utils.log(i + ": delta epsilon = " + dEpsilon_i);
    }
    if (lensModel != null) {
        if (p.visualize) {
            if (Thread.currentThread().isInterrupted())
                return;
            if (worker != null)
                worker.setTaskName("Visualizing lens distortion correction");
            lensModel.visualizeSmall(p.lambda);
        }
        if (worker != null)
            worker.setTaskName("Applying lens distortion correction");
        appendCoordinateTransform(allPatches, lensModel, Runtime.getRuntime().availableProcessors());
        Utils.log("Done.");
    } else
        Utils.log("No lens model found.");
}
Also used : Set(java.util.Set) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) PointMatchCollectionAndAffine(lenscorrection.Distortion_Correction.PointMatchCollectionAndAffine) Displayable(ini.trakem2.display.Displayable) Align(mpicbg.trakem2.align.Align) AbstractAffineTile2D(mpicbg.trakem2.align.AbstractAffineTile2D) Tile(mpicbg.models.Tile) Point(mpicbg.models.Point) Layer(ini.trakem2.display.Layer) Point(mpicbg.models.Point) PointMatch(mpicbg.models.PointMatch) AffineTransform(java.awt.geom.AffineTransform) Patch(ini.trakem2.display.Patch)

Example 67 with Patch

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

the class DisplayCanvas method keyPressed.

@Override
public void keyPressed(final KeyEvent ke) {
    final Displayable active = display.getActive();
    if (null != freehandProfile && ProjectToolbar.getToolId() == ProjectToolbar.PENCIL && ke.getKeyCode() == KeyEvent.VK_ESCAPE && null != freehandProfile) {
        freehandProfile.abort();
        ke.consume();
        return;
    }
    final int keyCode = ke.getKeyCode();
    try {
        // Enable tagging system for any alphanumeric key:
        if (!input_disabled && null != active && active instanceof Tree<?> && ProjectToolbar.isDataEditTool(ProjectToolbar.getToolId())) {
            if (tagging) {
                if (KeyEvent.VK_0 == keyCode && KeyEvent.VK_0 != last_keyCode) {
                // do nothing: keep tagging as true
                } else {
                    // last step of tagging: a char after t or after t and a number (and the char itself can be a number)
                    tagging = false;
                }
                active.keyPressed(ke);
                return;
            } else if (KeyEvent.VK_T == keyCode) {
                tagging = true;
                active.keyPressed(ke);
                return;
            }
        }
    } finally {
        last_keyCode = keyCode;
    }
    tagging = false;
    if (ke.isConsumed())
        return;
    if (!zoom_and_pan) {
        if (KeyEvent.VK_ESCAPE == keyCode) {
            cancelAnimations();
        }
        return;
    }
    final int keyChar = ke.getKeyChar();
    boolean used = false;
    switch(keyChar) {
        case '+':
        case '=':
            zoomIn();
            used = true;
            break;
        case '-':
        case '_':
            zoomOut();
            used = true;
            break;
        default:
            break;
    }
    if (used) {
        // otherwise ImageJ would use it!
        ke.consume();
        return;
    }
    if (input_disabled) {
        if (KeyEvent.VK_ESCAPE == keyCode) {
            // cancel last job if any
            if (Utils.checkYN("Really cancel job?")) {
                display.getProject().getLoader().quitJob(null);
                display.repairGUI();
            }
        }
        ke.consume();
        // only zoom is enabled, above
        return;
    }
    if (KeyEvent.VK_S == keyCode && 0 == ke.getModifiers() && display.getProject().getLoader().isAsynchronous()) {
        display.getProject().getLoader().saveTask(display.getProject(), "Save");
        ke.consume();
        return;
    } else if (KeyEvent.VK_F == keyCode && Utils.isControlDown(ke)) {
        Search.showWindow();
        ke.consume();
        return;
    }
    // if display is not read-only, check for other keys:
    switch(keyChar) {
        case '<':
        case // select next Layer up
        ',':
            // repaints as well
            display.previousLayer(ke.getModifiers());
            ke.consume();
            return;
        case '>':
        case // select next Layer down
        '.':
            display.nextLayer(ke.getModifiers());
            ke.consume();
            return;
    }
    if (null == active && null != imp.getRoi() && KeyEvent.VK_A != keyCode) {
        // control+a and a roi should select under roi
        IJ.getInstance().keyPressed(ke);
        return;
    }
    // end here if display is read-only
    if (display.isReadOnly()) {
        ke.consume();
        display.repaintAll();
        return;
    }
    if (KeyEvent.VK_ENTER == keyCode) {
        if (isTransforming()) {
            applyTransform();
            ke.consume();
            return;
        } else {
            IJ.getInstance().toFront();
            ke.consume();
            return;
        }
    }
    // check preconditions (or the keys are meaningless). Allow 'enter' to
    // bring forward the ImageJ window, and 'v' to paste a patch.
    /*if (null == active && KeyEvent.VK_ENTER != keyCode && KeyEvent.VK_V != keyCode && KeyEvent) {
			return;
		}*/
    final Layer layer = display.getLayer();
    final int mod = ke.getModifiers();
    switch(keyCode) {
        case KeyEvent.VK_COMMA:
        case // select next Layer up
        0xbc:
            display.nextLayer(ke.getModifiers());
            break;
        case KeyEvent.VK_PERIOD:
        case // select next Layer down
        0xbe:
            display.previousLayer(ke.getModifiers());
            break;
        case KeyEvent.VK_Z:
            // UNDO: shift+z or ctrl+z
            if (0 == (mod ^ Event.SHIFT_MASK) || 0 == (mod ^ Utils.getControlModifier())) {
                Bureaucrat.createAndStart(new Worker.Task("Undo") {

                    @Override
                    public void exec() {
                        if (isTransforming())
                            display.getMode().undoOneStep();
                        else
                            display.getLayerSet().undoOneStep();
                        Display.repaint(display.getLayerSet());
                    }
                }, display.getProject());
                ke.consume();
            // REDO: alt+z or ctrl+shift+z
            } else if (0 == (mod ^ Event.ALT_MASK) || 0 == (mod ^ (Event.SHIFT_MASK | Utils.getControlModifier()))) {
                Bureaucrat.createAndStart(new Worker.Task("Redo") {

                    @Override
                    public void exec() {
                        if (isTransforming())
                            display.getMode().redoOneStep();
                        else
                            display.getLayerSet().redoOneStep();
                        Display.repaint(display.getLayerSet());
                    }
                }, display.getProject());
                ke.consume();
            }
            // else, the 'z' command restores the image using ImageJ internal undo
            break;
        case KeyEvent.VK_T:
            // Enable with any tool to the left of the PENCIL
            if (null != active && !isTransforming() && ProjectToolbar.getToolId() < ProjectToolbar.PENCIL) {
                ProjectToolbar.setTool(ProjectToolbar.SELECT);
                if (0 == ke.getModifiers()) {
                    display.setMode(new AffineTransformMode(display));
                } else if (Event.SHIFT_MASK == ke.getModifiers()) {
                    for (final Displayable d : display.getSelection().getSelected()) {
                        if (d.isLinked()) {
                            Utils.showMessage("Can't enter manual non-linear transformation mode:\nat least one image is linked.");
                            return;
                        }
                    }
                    display.setMode(new NonLinearTransformMode(display));
                }
                ke.consume();
            }
            // else, let ImageJ grab the ROI into the Manager, if any
            break;
        case KeyEvent.VK_A:
            if (0 == (ke.getModifiers() ^ Utils.getControlModifier())) {
                final Roi roi = getFakeImagePlus().getRoi();
                if (null != roi)
                    display.getSelection().selectAll(roi, true);
                else
                    display.getSelection().selectAllVisible();
                Display.repaint(display.getLayer(), display.getSelection().getBox(), 0);
                ke.consume();
                // INSIDE the 'if' block, so that it can bleed to the default block which forwards to active!
                break;
            } else if (null != active) {
                active.keyPressed(ke);
                if (ke.isConsumed())
                    break;
            // TODO this is just a hack really. Should just fall back to default switch option.
            // The whole keyPressed method needs revision: should not break from it when not using the key.
            }
            break;
        case // cancel transformation
        KeyEvent.VK_ESCAPE:
            if (isTransforming())
                cancelTransform();
            else {
                // deselect
                display.select(null);
                // repaint out the brush if present
                if (ProjectToolbar.BRUSH == ProjectToolbar.getToolId()) {
                    repaint(old_brush_box, 0);
                }
            }
            ke.consume();
            break;
        case KeyEvent.VK_SPACE:
            if (0 == ke.getModifiers()) {
                if (null != active) {
                    invalidateVolatile();
                    if (Math.abs(active.getAlpha() - 0.5f) > 0.001f)
                        active.setAlpha(0.5f);
                    else
                        active.setAlpha(1.0f);
                    display.setTransparencySlider(active.getAlpha());
                    Display.repaint();
                    ke.consume();
                }
            } else {
                // ;)
                final int kem = ke.getModifiers();
                if (0 != (kem & KeyEvent.SHIFT_MASK) && 0 != (kem & KeyEvent.ALT_MASK) && 0 != (kem & KeyEvent.CTRL_MASK)) {
                    Utils.showMessage("A mathematician, like a painter or poet,\nis a maker of patterns.\nIf his patterns are more permanent than theirs,\nit is because they are made with ideas\n \nG. H. Hardy.");
                    ke.consume();
                }
            }
            break;
        case KeyEvent.VK_S:
            if (ke.isAltDown()) {
                snapping = true;
                ke.consume();
            } else if (dragging) {
                // ignore improper 's' that open ImageJ's save dialog (linux problem ... in macosx, a single dialog opens with lots of 'ssss...' in the text field)
                ke.consume();
            }
            break;
        case KeyEvent.VK_H:
            handleHide(ke);
            ke.consume();
            break;
        case KeyEvent.VK_J:
            if (!display.getSelection().isEmpty()) {
                display.adjustMinAndMaxGUI();
                ke.consume();
            }
            break;
        case KeyEvent.VK_F1:
        case KeyEvent.VK_F2:
        case KeyEvent.VK_F3:
        case KeyEvent.VK_F4:
        case KeyEvent.VK_F5:
        case KeyEvent.VK_F6:
        case KeyEvent.VK_F7:
        case KeyEvent.VK_F8:
        case KeyEvent.VK_F9:
        case KeyEvent.VK_F10:
        case KeyEvent.VK_F11:
        case KeyEvent.VK_F12:
            ProjectToolbar.keyPressed(ke);
            ke.consume();
            break;
        case KeyEvent.VK_M:
            if (0 == ke.getModifiers() && ProjectToolbar.getToolId() == ProjectToolbar.SELECT) {
                display.getSelection().measure();
                ke.consume();
            }
            break;
    }
    switch(keyChar) {
        case ':':
        case ';':
            if (null != active && active instanceof ZDisplayable) {
                if (null != display.getProject().getProjectTree().tryAddNewConnector(active, true)) {
                    ProjectToolbar.setTool(ProjectToolbar.PEN);
                }
                ke.consume();
            }
            break;
    }
    if (ke.isConsumed())
        return;
    if (null != active) {
        if (display.getMode().getClass() == DefaultMode.class) {
            active.keyPressed(ke);
        }
        if (ke.isConsumed())
            return;
    }
    // Else:
    switch(keyCode) {
        case KeyEvent.VK_G:
            if (browseToNodeLayer(ke.isShiftDown())) {
                ke.consume();
            }
            break;
        case KeyEvent.VK_I:
            if (ke.isAltDown()) {
                if (ke.isShiftDown())
                    display.importImage();
                else
                    display.importNextImage();
                ke.consume();
            }
            break;
        case // as in Inkscape
        KeyEvent.VK_PAGE_UP:
            if (null != active) {
                update_graphics = true;
                layer.getParent().addUndoMoveStep(active);
                layer.getParent().move(LayerSet.UP, active);
                layer.getParent().addUndoMoveStep(active);
                Display.repaint(layer, active, 5);
                Display.updatePanelIndex(layer, active);
                ke.consume();
            }
            break;
        case // as in Inkscape
        KeyEvent.VK_PAGE_DOWN:
            if (null != active) {
                update_graphics = true;
                layer.getParent().addUndoMoveStep(active);
                layer.getParent().move(LayerSet.DOWN, active);
                layer.getParent().addUndoMoveStep(active);
                Display.repaint(layer, active, 5);
                Display.updatePanelIndex(layer, active);
                ke.consume();
            }
            break;
        case // as in Inkscape
        KeyEvent.VK_HOME:
            if (null != active) {
                update_graphics = true;
                layer.getParent().addUndoMoveStep(active);
                layer.getParent().move(LayerSet.TOP, active);
                layer.getParent().addUndoMoveStep(active);
                Display.repaint(layer, active, 5);
                Display.updatePanelIndex(layer, active);
                ke.consume();
            }
            break;
        case // as in Inkscape
        KeyEvent.VK_END:
            if (null != active) {
                update_graphics = true;
                layer.getParent().addUndoMoveStep(active);
                layer.getParent().move(LayerSet.BOTTOM, active);
                layer.getParent().addUndoMoveStep(active);
                Display.repaint(layer, active, 5);
                Display.updatePanelIndex(layer, active);
                ke.consume();
            }
            break;
        case KeyEvent.VK_V:
            if (0 == ke.getModifiers()) {
                if (null == active || active.getClass() == Patch.class) {
                    // paste a new image
                    final ImagePlus clipboard = ImagePlus.getClipboard();
                    if (null != clipboard) {
                        final ImagePlus imp = new ImagePlus(clipboard.getTitle() + "_" + System.currentTimeMillis(), clipboard.getProcessor().crop());
                        final Object info = clipboard.getProperty("Info");
                        if (null != info)
                            imp.setProperty("Info", (String) info);
                        final double x = srcRect.x + srcRect.width / 2 - imp.getWidth() / 2;
                        final double y = srcRect.y + srcRect.height / 2 - imp.getHeight() / 2;
                        // save the image somewhere:
                        final Patch pa = display.getProject().getLoader().addNewImage(imp, x, y);
                        display.getLayer().add(pa);
                        ke.consume();
                    }
                // TODO there isn't much ImageJ integration in the pasting. Can't paste to a selected image, for example.
                } else {
                    // Each type may know how to paste data from the copy buffer into itself:
                    active.keyPressed(ke);
                    ke.consume();
                }
            }
            break;
        case KeyEvent.VK_P:
            if (0 == ke.getModifiers()) {
                display.getLayerSet().color_cues = !display.getLayerSet().color_cues;
                Display.repaint(display.getLayerSet());
                ke.consume();
            }
            break;
        case KeyEvent.VK_F:
            if (0 == (ke.getModifiers() ^ KeyEvent.SHIFT_MASK)) {
                // toggle visibility of tags
                display.getLayerSet().paint_tags = !display.getLayerSet().paint_tags;
                Display.repaint();
                ke.consume();
            } else if (0 == (ke.getModifiers() ^ KeyEvent.ALT_MASK)) {
                // toggle visibility of edge arrows
                display.getLayerSet().paint_arrows = !display.getLayerSet().paint_arrows;
                Display.repaint();
                ke.consume();
            } else if (0 == ke.getModifiers()) {
                // toggle visibility of edge confidence boxes
                display.getLayerSet().paint_edge_confidence_boxes = !display.getLayerSet().paint_edge_confidence_boxes;
                Display.repaint();
                ke.consume();
            }
            break;
        case KeyEvent.VK_DELETE:
            if (0 == ke.getModifiers()) {
                display.getSelection().deleteAll();
            }
            break;
        case KeyEvent.VK_B:
            if (0 == ke.getModifiers() && null != active && active.getClass() == Profile.class) {
                display.duplicateLinkAndSendTo(active, 0, active.getLayer().getParent().previous(layer));
                ke.consume();
            }
            break;
        case KeyEvent.VK_N:
            if (0 == ke.getModifiers() && null != active && active.getClass() == Profile.class) {
                display.duplicateLinkAndSendTo(active, 1, active.getLayer().getParent().next(layer));
                ke.consume();
            }
            break;
        case KeyEvent.VK_1:
        case KeyEvent.VK_2:
        case KeyEvent.VK_3:
        case KeyEvent.VK_4:
        case KeyEvent.VK_5:
        case KeyEvent.VK_6:
        case KeyEvent.VK_7:
        case KeyEvent.VK_8:
        case KeyEvent.VK_9:
            // run a plugin, if any
            if (null != Utils.launchTPlugIn(ke, "Display", display.getProject(), display.getActive())) {
                ke.consume();
                break;
            }
    }
    if (!(keyCode == KeyEvent.VK_UNDEFINED || keyChar == KeyEvent.CHAR_UNDEFINED) && !ke.isConsumed() && null != active && active instanceof Patch) {
        // TODO should allow forwarding for all, not just Patch
        // forward to ImageJ for a final try
        IJ.getInstance().keyPressed(ke);
        repaint(active, 5);
        ke.consume();
    }
// Utils.log2("keyCode, keyChar: " + keyCode + ", " + keyChar + " ref: " + KeyEvent.VK_UNDEFINED + ", " + KeyEvent.CHAR_UNDEFINED);
}
Also used : Roi(ij.gui.Roi) ImagePlus(ij.ImagePlus) Point(java.awt.Point) Worker(ini.trakem2.utils.Worker)

Example 68 with Patch

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

the class Display method importNextImage.

protected Bureaucrat importNextImage() {
    final Worker worker = new // / all this verbosity is what happens when functions are not first class citizens. I could abstract it away by passing a string name "importImage" and invoking it with reflection, but that is an even bigger PAIN
    Worker(// / all this verbosity is what happens when functions are not first class citizens. I could abstract it away by passing a string name "importImage" and invoking it with reflection, but that is an even bigger PAIN
    "Import image") {

        @Override
        public void run() {
            startedWorking();
            try {
                final Rectangle srcRect = canvas.getSrcRect();
                // - imp.getWidth() / 2;
                final int x = srcRect.x + srcRect.width / 2;
                // - imp.getHeight()/ 2;
                final int y = srcRect.y + srcRect.height / 2;
                final Patch p = project.getLoader().importNextImage(project, x, y);
                if (null == p) {
                    Utils.showMessage("Could not open next image.");
                    finishedWorking();
                    return;
                }
                Display.this.getLayerSet().addLayerContentStep(layer);
                // will add it to the proper Displays
                layer.add(p);
                Display.this.getLayerSet().addLayerContentStep(layer);
            } catch (final Exception e) {
                IJError.print(e);
            }
            finishedWorking();
        }
    };
    return Bureaucrat.createAndStart(worker, getProject());
}
Also used : Rectangle(java.awt.Rectangle) Worker(ini.trakem2.utils.Worker) Point(java.awt.Point) NoninvertibleTransformException(java.awt.geom.NoninvertibleTransformException)

Example 69 with Patch

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

the class Layer method exportXML.

@Override
public void exportXML(final StringBuilder sb_body, final String indent, final XMLOptions options) {
    final String in = indent + "\t";
    // 1 - open tag
    sb_body.append(indent).append("<t2_layer oid=\"").append(id).append("\"\n").append(in).append(" thickness=\"").append(thickness).append("\"\n").append(in).append(" z=\"").append(z).append("\"\n");
    // TODO this search is linear!
    final LayerThing lt = project.findLayerThing(this);
    String title;
    if (null == lt)
        title = null;
    else
        title = lt.getTitle();
    if (null == title)
        title = "";
    // TODO 'title' should be a property of the Layer, not the LayerThing. Also, the LayerThing should not exist: LayerSet and Layer should be directly presentable in a tree. They are not Things as in "objects of the sample", but rather, structural necessities such as Patch.
    sb_body.append(in).append(" title=\"").append(title).append("\"\n");
    sb_body.append(indent).append(">\n");
    // 2 - export children
    if (null != al_displayables) {
        for (final Displayable d : al_displayables) {
            d.exportXML(sb_body, in, options);
        }
    }
    // 3 - close tag
    sb_body.append(indent).append("</t2_layer>\n");
}
Also used : LayerThing(ini.trakem2.tree.LayerThing)

Example 70 with Patch

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

the class Project method destroy.

public boolean destroy() {
    if (null == loader) {
        return true;
    }
    if (loader.hasChanges() && !getBooleanProperty("no_shutdown_hook")) {
        // DBLoader always returns false
        if (ControlWindow.isGUIEnabled()) {
            final YesNoDialog yn = ControlWindow.makeYesNoDialog("TrakEM2", "There are unsaved changes in project " + title + ". Save them?");
            if (yn.yesPressed()) {
                save();
            }
        } else {
            Utils.log2("WARNING: closing project '" + title + "' with unsaved changes.");
        }
    }
    try {
        if (null != autosaving)
            autosaving.cancel(true);
    } catch (Throwable t) {
    }
    al_open_projects.remove(this);
    // flush all memory
    if (null != loader) {
        // the last project is destroyed twice for some reason, if several are open. This is a PATCH
        // and disconnect
        loader.destroy();
        loader = null;
    }
    if (null != layer_set)
        layer_set.destroy();
    // AFTER loader.destroy() call.
    ControlWindow.remove(this);
    if (null != template_tree)
        template_tree.destroy();
    if (null != project_tree)
        project_tree.destroy();
    if (null != layer_tree)
        layer_tree.destroy();
    Polyline.flushTraceCache(this);
    // flag to mean: we're closing
    this.template_tree = null;
    // close all open Displays
    Display.close(this);
    Search.removeTabs(this);
    synchronized (ptcache) {
        ptcache.clear();
    }
    return true;
}
Also used : YesNoDialog(ini.trakem2.display.YesNoDialog)

Aggregations

Patch (ini.trakem2.display.Patch)69 ArrayList (java.util.ArrayList)46 Layer (ini.trakem2.display.Layer)39 ImagePlus (ij.ImagePlus)34 Rectangle (java.awt.Rectangle)28 Point (mpicbg.models.Point)26 HashSet (java.util.HashSet)24 Displayable (ini.trakem2.display.Displayable)23 AffineTransform (java.awt.geom.AffineTransform)20 Loader (ini.trakem2.persistence.Loader)15 File (java.io.File)15 Future (java.util.concurrent.Future)15 NotEnoughDataPointsException (mpicbg.models.NotEnoughDataPointsException)15 PointMatch (mpicbg.models.PointMatch)14 Worker (ini.trakem2.utils.Worker)13 HashMap (java.util.HashMap)13 ExecutorService (java.util.concurrent.ExecutorService)12 ImageProcessor (ij.process.ImageProcessor)11 AffineModel2D (mpicbg.models.AffineModel2D)11 GenericDialog (ij.gui.GenericDialog)10