Search in sources :

Example 16 with Patch

use of ini.trakem2.display.Patch 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 17 with Patch

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

the class AlignTask method alignPatchesTask.

public static final Bureaucrat alignPatchesTask(final List<Patch> patches, final Set<Patch> fixedPatches) {
    if (0 == patches.size()) {
        Utils.log("Can't align zero patches.");
        return null;
    }
    final Worker worker = new Worker("Aligning images", false, true) {

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

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

Example 18 with Patch

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

the class AlignTask method transformPatchesAndVectorData.

/**
 * For registering within the same project instance.
 */
public static final void transformPatchesAndVectorData(final Collection<Patch> patches, final Runnable alignment) {
    if (patches.isEmpty()) {
        Utils.log("No patches to align!");
        return;
    }
    // 1 - Collect all VectorData to transform
    final ArrayList<Displayable> vdata = new ArrayList<Displayable>();
    final LayerSet ls = patches.iterator().next().getLayerSet();
    for (final Layer layer : ls.getLayers()) {
        vdata.addAll(layer.getDisplayables(VectorData.class, false, true));
    }
    vdata.addAll(ls.getZDisplayables(VectorData.class, true));
    // Perhaps none:
    if (vdata.isEmpty()) {
        alignment.run();
        return;
    }
    // 2 - Store current transformation of each Patch under any VectorData
    final HashSet<Long> lids = new HashSet<Long>();
    for (final Patch p : patches) lids.add(p.getLayer().getId());
    final ReferenceData rd = createTransformPropertiesTable(vdata, null, lids);
    // 3 - Align:
    alignment.run();
    // 4 - Transform VectorData instances to match the position of the Patch instances over which they were defined
    if (null != rd && !vdata.isEmpty())
        transformVectorData(rd, vdata, ls);
}
Also used : Displayable(ini.trakem2.display.Displayable) LayerSet(ini.trakem2.display.LayerSet) ArrayList(java.util.ArrayList) Layer(ini.trakem2.display.Layer) Patch(ini.trakem2.display.Patch) VectorData(ini.trakem2.display.VectorData) HashSet(java.util.HashSet)

Example 19 with Patch

use of ini.trakem2.display.Patch 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 20 with Patch

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

the class ElasticLayerAlignment method exec.

/**
 * Stateful.  Changing the parameters of this instance.  Do not use in parallel.
 *
 * @param layerRange
 * @param fixedLayers
 * @param propagateTransformBefore
 * @param propagateTransformAfter
 * @param fov
 * @param filter
 * @throws Exception
 */
public final void exec(final Project project, final List<Layer> layerRange, final Set<Layer> fixedLayers, final boolean propagateTransformBefore, final boolean propagateTransformAfter, final Rectangle fov, final Filter<Patch> filter) throws Exception {
    Rectangle box = null;
    final HashSet<Layer> emptyLayers = new HashSet<Layer>();
    for (final Iterator<Layer> it = layerRange.iterator(); it.hasNext(); ) {
        /* remove empty layers */
        final Layer la = it.next();
        if (!la.contains(Patch.class, true)) {
            emptyLayers.add(la);
        // it.remove();
        } else {
            /* accumulate boxes */
            if (// The first layer:
            null == box)
                box = la.getMinimalBoundingBox(Patch.class, true);
            else
                box = box.union(la.getMinimalBoundingBox(Patch.class, true));
        }
    }
    if (box == null)
        box = new Rectangle();
    if (fov != null)
        box = box.intersection(fov);
    if (box.width <= 0 || box.height <= 0) {
        Utils.log("Bounding box empty.");
        return;
    }
    if (layerRange.size() == emptyLayers.size()) {
        Utils.log("All layers in range are empty!");
        return;
    }
    /* do not work if there is only one layer selected */
    if (layerRange.size() - emptyLayers.size() < 2) {
        Utils.log("All except one layer in range are empty!");
        return;
    }
    if (!p.setup(box))
        return;
    exec(p.clone(), project, layerRange, fixedLayers, emptyLayers, box, propagateTransformBefore, propagateTransformAfter, filter);
}
Also used : Rectangle(java.awt.Rectangle) Layer(ini.trakem2.display.Layer) Patch(ini.trakem2.display.Patch) HashSet(java.util.HashSet)

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