Search in sources :

Example 1 with Selection

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

the class AlignTask method alignPatches.

/**
 * @param patches: the list of Patch instances to align, all belonging to the same Layer.
 * @param fixedPatches: the list of Patch instances to keep locked in place, if any.
 * @param m: {@link AlignTask#LINEAR_SIFT_CORRESPONDENCES}, {@link AlignTask#LINEAR_PHASE_CORRELATION} or {@link AlignTask#ELASTIC_BLOCK_CORRESPONDENCES}.
 */
public static final void alignPatches(final List<Patch> patches, final Set<Patch> fixedPatches, final int m) throws Exception {
    if (patches.size() < 2) {
        Utils.log("No images to align.");
        return;
    }
    for (final Patch patch : fixedPatches) {
        if (!patches.contains(patch)) {
            Utils.log("The list of fixed patches contains at least one Patch not included in the list of patches to align!");
            return;
        }
    }
    if (ELASTIC_BLOCK_CORRESPONDENCES == m)
        new ElasticMontage().exec(patches, fixedPatches);
    else if (LINEAR_PHASE_CORRELATION == m) {
        // Montage all given patches, fixedPatches is ignored!
        if (!fixedPatches.isEmpty())
            Utils.log("Ignoring " + fixedPatches.size() + " fixed patches.");
        StitchingTEM.montageWithPhaseCorrelation(patches);
    } else if (LINEAR_SIFT_CORRESPONDENCES == m) {
        if (!Align.paramOptimize.setup("Montage Selection"))
            return;
        final GenericDialog gd = new GenericDialog("Montage Selection: Miscellaneous");
        gd.addCheckbox("tiles are roughly in place", tilesAreInPlace);
        gd.addCheckbox("sloppy overlap test (fast)", sloppyOverlapTest);
        gd.addCheckbox("consider largest graph only", largestGraphOnly);
        gd.addCheckbox("hide tiles from non-largest graph", hideDisconnectedTiles);
        gd.addCheckbox("delete tiles from non-largest graph", deleteDisconnectedTiles);
        gd.showDialog();
        if (gd.wasCanceled())
            return;
        tilesAreInPlace = gd.getNextBoolean();
        sloppyOverlapTest = gd.getNextBoolean();
        largestGraphOnly = gd.getNextBoolean();
        hideDisconnectedTiles = gd.getNextBoolean();
        deleteDisconnectedTiles = gd.getNextBoolean();
        final Align.ParamOptimize p = Align.paramOptimize.clone();
        alignPatches(p, patches, fixedPatches, tilesAreInPlace, largestGraphOnly, hideDisconnectedTiles, deleteDisconnectedTiles, sloppyOverlapTest);
    } else
        Utils.log("Don't know how to align with mode " + m);
}
Also used : GenericDialog(ij.gui.GenericDialog) Patch(ini.trakem2.display.Patch)

Example 2 with Selection

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

the class AlignTask method alignSelection.

public static final void alignSelection(final Selection selection, final int m) throws Exception {
    final List<Patch> patches = new ArrayList<Patch>();
    for (final Displayable d : selection.getSelected()) if (d instanceof Patch)
        patches.add((Patch) d);
    final HashSet<Patch> fixedPatches = new HashSet<Patch>();
    // Add active Patch, if any, as the nail
    final Displayable active = selection.getActive();
    if (null != active && active instanceof Patch)
        fixedPatches.add((Patch) active);
    // Add all locked Patch instances to fixedPatches
    for (final Patch patch : patches) if (patch.isLocked())
        fixedPatches.add(patch);
    alignPatches(patches, fixedPatches, m);
}
Also used : Displayable(ini.trakem2.display.Displayable) ArrayList(java.util.ArrayList) Patch(ini.trakem2.display.Patch) HashSet(java.util.HashSet)

Example 3 with Selection

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

the class AlignTask method alignGraphs.

private static final boolean alignGraphs(final Align.Param p, final Layer layer1, final Layer layer2, final Iterable<Tile<?>> graph1, final Iterable<Tile<?>> graph2) {
    final Align.Param cp = p.clone();
    final Selection selection1 = new Selection(null);
    for (final Tile<?> tile : graph1) selection1.add(((AbstractAffineTile2D<?>) tile).getPatch());
    final Rectangle graph1Box = selection1.getBox();
    final Selection selection2 = new Selection(null);
    for (final Tile<?> tile : graph2) selection2.add(((AbstractAffineTile2D<?>) tile).getPatch());
    final Rectangle graph2Box = selection2.getBox();
    final int maxLength = Math.max(Math.max(Math.max(graph1Box.width, graph1Box.height), graph2Box.width), graph2Box.height);
    // final double scale = ( double )cp.sift.maxOctaveSize / maxLength;
    /* rather ad hoc but we cannot just scale this to maxOctaveSize */
    cp.sift.maxOctaveSize = Math.min(maxLength, 2 * p.sift.maxOctaveSize);
    /* make sure that, despite rounding issues from scale, it is >= image size */
    final double scale = (double) (cp.sift.maxOctaveSize - 1) / maxLength;
    // cp.maxEpsilon *= scale;
    final FloatArray2DSIFT sift = new FloatArray2DSIFT(cp.sift);
    final SIFT ijSIFT = new SIFT(sift);
    final ArrayList<Feature> features1 = new ArrayList<Feature>();
    final ArrayList<Feature> features2 = new ArrayList<Feature>();
    final ArrayList<PointMatch> candidates = new ArrayList<PointMatch>();
    final ArrayList<PointMatch> inliers = new ArrayList<PointMatch>();
    long s = System.currentTimeMillis();
    ijSIFT.extractFeatures(layer1.getProject().getLoader().getFlatImage(layer1, graph1Box, scale, 0xffffffff, ImagePlus.GRAY8, Patch.class, selection1.getSelected(Patch.class), false, Color.GRAY).getProcessor(), features1);
    Utils.log(features1.size() + " features extracted for graphs in layer \"" + layer1.getTitle() + "\" (took " + (System.currentTimeMillis() - s) + " ms).");
    ijSIFT.extractFeatures(layer2.getProject().getLoader().getFlatImage(layer2, graph2Box, scale, 0xffffffff, ImagePlus.GRAY8, Patch.class, selection2.getSelected(Patch.class), false, Color.GRAY).getProcessor(), features2);
    Utils.log(features2.size() + " features extracted for graphs in layer \"" + layer1.getTitle() + "\" (took " + (System.currentTimeMillis() - s) + " ms).");
    boolean modelFound = false;
    if (features1.size() > 0 && features2.size() > 0) {
        s = System.currentTimeMillis();
        FeatureTransform.matchFeatures(features1, features2, candidates, cp.rod);
        final AbstractAffineModel2D<?> model;
        switch(cp.expectedModelIndex) {
            case 0:
                model = new TranslationModel2D();
                break;
            case 1:
                model = new RigidModel2D();
                break;
            case 2:
                model = new SimilarityModel2D();
                break;
            case 3:
                model = new AffineModel2D();
                break;
            default:
                return false;
        }
        boolean again = false;
        try {
            do {
                again = false;
                modelFound = model.filterRansac(candidates, inliers, 1000, cp.maxEpsilon, cp.minInlierRatio, cp.minNumInliers, 3);
                if (modelFound && cp.rejectIdentity) {
                    final ArrayList<Point> points = new ArrayList<Point>();
                    PointMatch.sourcePoints(inliers, points);
                    if (Transforms.isIdentity(model, points, cp.identityTolerance)) {
                        IJ.log("Identity transform for " + inliers.size() + " matches rejected.");
                        candidates.removeAll(inliers);
                        inliers.clear();
                        again = true;
                    }
                }
            } while (again);
        } catch (final NotEnoughDataPointsException e) {
            modelFound = false;
        }
        if (modelFound) {
            Utils.log("Model found for graphs in layer \"" + layer1.getTitle() + "\" and \"" + layer2.getTitle() + "\":\n  correspondences  " + inliers.size() + " of " + candidates.size() + "\n  average residual error  " + (model.getCost() / scale) + " px\n  took " + (System.currentTimeMillis() - s) + " ms");
            final AffineTransform b = new AffineTransform();
            b.translate(graph2Box.x, graph2Box.y);
            b.scale(1.0f / scale, 1.0f / scale);
            b.concatenate(model.createAffine());
            b.scale(scale, scale);
            b.translate(-graph1Box.x, -graph1Box.y);
            for (final Displayable d : selection1.getSelected(Patch.class)) d.getAffineTransform().preConcatenate(b);
            /* assign patch affine transformation to the tile model */
            for (final Tile<?> t : graph1) ((AbstractAffineTile2D<?>) t).initModel();
            Display.repaint(layer1);
        } else
            IJ.log("No model found for graphs in layer \"" + layer1.getTitle() + "\" and \"" + layer2.getTitle() + "\":\n  correspondence candidates  " + candidates.size() + "\n  took " + (System.currentTimeMillis() - s) + " ms");
    }
    return modelFound;
}
Also used : NotEnoughDataPointsException(mpicbg.models.NotEnoughDataPointsException) SIFT(mpicbg.ij.SIFT) FloatArray2DSIFT(mpicbg.imagefeatures.FloatArray2DSIFT) Selection(ini.trakem2.display.Selection) Rectangle(java.awt.Rectangle) ArrayList(java.util.ArrayList) Feature(mpicbg.imagefeatures.Feature) RigidModel2D(mpicbg.trakem2.transform.RigidModel2D) AbstractAffineModel2D(mpicbg.models.AbstractAffineModel2D) AffineModel2D(mpicbg.models.AffineModel2D) SimilarityModel2D(mpicbg.models.SimilarityModel2D) Displayable(ini.trakem2.display.Displayable) Point(mpicbg.models.Point) Point(mpicbg.models.Point) FloatArray2DSIFT(mpicbg.imagefeatures.FloatArray2DSIFT) PointMatch(mpicbg.models.PointMatch) AffineTransform(java.awt.geom.AffineTransform) TranslationModel2D(mpicbg.trakem2.transform.TranslationModel2D) Patch(ini.trakem2.display.Patch)

Example 4 with Selection

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

the class AlignTask method alignSelectionTask.

public static final Bureaucrat alignSelectionTask(final Selection selection) {
    final Worker worker = new Worker("Aligning selected images", false, true) {

        @Override
        public void run() {
            startedWorking();
            try {
                final int m = chooseAlignmentMode();
                if (-1 == m)
                    return;
                alignSelection(selection, m);
                Display.repaint(selection.getLayer());
            } catch (final Throwable e) {
                IJError.print(e);
            } finally {
                finishedWorking();
            }
        }

        @Override
        public void cleanup() {
            if (!selection.isEmpty())
                selection.getLayer().getParent().undoOneStep();
        }
    };
    return Bureaucrat.createAndStart(worker, selection.getProject());
}
Also used : Worker(ini.trakem2.utils.Worker) Point(mpicbg.models.Point)

Example 5 with Selection

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

the class Align method alignSelectedPatches.

/**
 * Align a selection of {@link Patch patches} in a Layer.
 *
 * @param selection
 * @param numThreads
 */
public static final void alignSelectedPatches(final Selection selection, final int numThreads) {
    final List<Patch> patches = new ArrayList<Patch>();
    for (final Displayable d : selection.getSelected()) if (d instanceof Patch)
        patches.add((Patch) d);
    if (patches.size() < 2)
        return;
    if (!paramOptimize.setup("Align selected patches"))
        return;
    final List<AbstractAffineTile2D<?>> tiles = new ArrayList<AbstractAffineTile2D<?>>();
    final List<AbstractAffineTile2D<?>> fixedTiles = new ArrayList<AbstractAffineTile2D<?>>();
    final List<Patch> fixedPatches = new ArrayList<Patch>();
    final Displayable active = selection.getActive();
    if (active != null && active instanceof Patch)
        fixedPatches.add((Patch) active);
    tilesFromPatches(paramOptimize, patches, fixedPatches, tiles, fixedTiles);
    alignTiles(paramOptimize, tiles, fixedTiles, numThreads);
    for (final AbstractAffineTile2D<?> t : tiles) t.getPatch().setAffineTransform(t.getModel().createAffine());
}
Also used : Displayable(ini.trakem2.display.Displayable) ArrayList(java.util.ArrayList) Patch(ini.trakem2.display.Patch)

Aggregations

ArrayList (java.util.ArrayList)8 Patch (ini.trakem2.display.Patch)5 Worker (ini.trakem2.utils.Worker)5 GenericDialog (ij.gui.GenericDialog)4 Displayable (ini.trakem2.display.Displayable)4 DBObject (ini.trakem2.persistence.DBObject)4 Rectangle (java.awt.Rectangle)4 HashSet (java.util.HashSet)4 Roi (ij.gui.Roi)3 Project (ini.trakem2.Project)3 LayerSet (ini.trakem2.display.LayerSet)3 InspectPatchTrianglesMode (ini.trakem2.display.inspect.InspectPatchTrianglesMode)3 Point (java.awt.Point)3 List (java.util.List)3 JMenuItem (javax.swing.JMenuItem)3 JPopupMenu (javax.swing.JPopupMenu)3 ImagePlus (ij.ImagePlus)2 PolygonRoi (ij.gui.PolygonRoi)2 ShapeRoi (ij.gui.ShapeRoi)2 Display (ini.trakem2.display.Display)2