Search in sources :

Example 1 with InterpolatedAffineModel2D

use of mpicbg.models.InterpolatedAffineModel2D in project TrakEM2 by trakem2.

the class Align method tilesFromPatches.

/**
 * If a Patch is locked or in fixedPatches, its corresponding Tile is added to fixedTiles.
 *
 * @param p
 * @param patches
 * @param fixedPatches
 * @param tiles will contain the generated
 *   {@link AbstractAffineTile2D Tiles}
 * @param fixedTiles will contain the {@link AbstractAffineTile2D Tiles}
 *   corresponding to the {@link Patch Patches} in fixedPatches
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public static final void tilesFromPatches(final Param p, final List<? extends Patch> patches, final Collection<? extends Patch> fixedPatches, final List<AbstractAffineTile2D<?>> tiles, final Collection<AbstractAffineTile2D<?>> fixedTiles) {
    for (final Patch patch : patches) {
        final AbstractAffineTile2D<?> t;
        if (p.regularize) {
            /* can only be affine per convention */
            final AbstractAffineModel2D<?> m = (AbstractAffineModel2D<?>) Util.createModel(p.desiredModelIndex);
            final AbstractAffineModel2D<?> r = (AbstractAffineModel2D<?>) Util.createModel(p.regularizerModelIndex);
            /* for type safety one would test both models as for the simple
				 * case below but here I will go for the easy route and let
				 * Java cast it to what is required and ignore the warning.
				 */
            @SuppressWarnings({}) final InterpolatedAffineModel2D<?, ?> interpolatedModel = new InterpolatedAffineModel2D(m, r, p.lambda);
            t = new GenericAffineTile2D(interpolatedModel, patch);
        } else {
            switch(p.desiredModelIndex) {
                case 0:
                    t = new TranslationTile2D(patch);
                    break;
                case 1:
                    t = new RigidTile2D(patch);
                    break;
                case 2:
                    t = new SimilarityTile2D(patch);
                    break;
                case 3:
                    t = new AffineTile2D(patch);
                    break;
                default:
                    return;
            }
        }
        tiles.add(t);
        if ((fixedPatches != null && fixedPatches.contains(patch)) || patch.isLocked())
            fixedTiles.add(t);
    }
}
Also used : InterpolatedAffineModel2D(mpicbg.models.InterpolatedAffineModel2D) AbstractAffineModel2D(mpicbg.models.AbstractAffineModel2D) Patch(ini.trakem2.display.Patch)

Example 2 with InterpolatedAffineModel2D

use of mpicbg.models.InterpolatedAffineModel2D in project TrakEM2 by trakem2.

the class RegularizedAffineLayerAlignment method exec.

/**
 * @param param
 * @param layerRange
 * @param fixedLayers
 * @param emptyLayers
 * @param box
 * @param propagateTransformAfter
 * @param filter
 * @throws Exception
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public final void exec(final Param param, final List<Layer> layerRange, final Set<Layer> fixedLayers, final Set<Layer> emptyLayers, final Rectangle box, final boolean propagateTransformBefore, final boolean propagateTransformAfter, final Filter<Patch> filter) throws Exception {
    final double scale = Math.min(1.0, Math.min((double) param.ppm.sift.maxOctaveSize / (double) box.width, (double) param.ppm.sift.maxOctaveSize / (double) box.height));
    final ExecutorService exec = ExecutorProvider.getExecutorService(1.0f / (float) param.maxNumThreads);
    /* create tiles and models for all layers */
    final ArrayList<Tile<?>> tiles = new ArrayList<Tile<?>>();
    final AbstractAffineModel2D<?> m = (AbstractAffineModel2D<?>) Util.createModel(param.desiredModelIndex);
    final AbstractAffineModel2D<?> r = (AbstractAffineModel2D<?>) Util.createModel(param.regularizerIndex);
    for (int i = 0; i < layerRange.size(); ++i) {
        if (param.regularize)
            tiles.add(new Tile(new InterpolatedAffineModel2D(m.copy(), r.copy(), param.lambda)));
        else
            tiles.add(new Tile(m.copy()));
    }
    /* collect all pairs of slices for which a model could be found */
    final ArrayList<Triple<Integer, Integer, Collection<PointMatch>>> pairs = new ArrayList<Triple<Integer, Integer, Collection<PointMatch>>>();
    /* extract and save features, overwrite cached files if requested */
    try {
        AlignmentUtils.extractAndSaveLayerFeatures(layerRange, box, scale, filter, param.ppm.sift, param.ppm.clearCache, param.ppm.maxNumThreadsSift);
    } catch (final Exception e) {
        e.printStackTrace();
        IJError.print(e);
        return;
    }
    /* match and filter feature correspondences */
    int numFailures = 0, lastA = 0;
    final double pointMatchScale = 1.0 / scale;
    final ArrayList<Future<Triple<Integer, Integer, Collection<PointMatch>>>> modelFutures = new ArrayList<Future<Triple<Integer, Integer, Collection<PointMatch>>>>();
    for (int i = 0; i < layerRange.size(); ++i) {
        final int range = Math.min(layerRange.size(), i + param.maxNumNeighbors + 1);
        for (int j = i + 1; j < range; ++j) {
            modelFutures.add(exec.submit(new CorrespondenceCallable(param, layerRange.get(i), layerRange.get(j), pointMatchScale, i, j)));
        }
    }
    // Assume that futures are ordered in Triple.a
    try {
        for (final Future<Triple<Integer, Integer, Collection<PointMatch>>> future : modelFutures) {
            final Triple<Integer, Integer, Collection<PointMatch>> pair = future.get();
            if (lastA != pair.a) {
                numFailures = 0;
                lastA = pair.a;
            }
            if (pair.c == null) {
                numFailures++;
            // TODO: Cancel futures associated with pair.a
            } else if (numFailures < param.maxNumFailures) {
                pairs.add(pair);
            }
        }
    } catch (final InterruptedException ie) {
        Utils.log("Establishing feature correspondences interrupted.");
        for (final Future<Triple<Integer, Integer, Collection<PointMatch>>> future : modelFutures) {
            future.cancel(true);
        }
        return;
    }
    /* collect successfully matches pairs and break the search on gaps */
    /*
        for ( int t = 0; t < models.size(); ++t )
        {
            final Triple< Integer, Integer, Collection< PointMatch > > pair = models.get( t );
            if ( pair == null )
            {
                if ( ++numFailures > param.maxNumFailures )
                    break J;
            }
            else
            {
                numFailures = 0;
                pairs.add( pair );
            }
        }
*/
    /* Optimization */
    final TileConfiguration tileConfiguration = new TileConfiguration();
    for (final Triple<Integer, Integer, Collection<PointMatch>> pair : pairs) {
        final Tile<?> t1 = tiles.get(pair.a);
        final Tile<?> t2 = tiles.get(pair.b);
        tileConfiguration.addTile(t1);
        tileConfiguration.addTile(t2);
        t2.connect(t1, pair.c);
    }
    for (int i = 0; i < layerRange.size(); ++i) {
        final Layer layer = layerRange.get(i);
        if (fixedLayers.contains(layer))
            tileConfiguration.fixTile(tiles.get(i));
    }
    final List<Tile<?>> nonPreAlignedTiles = tileConfiguration.preAlign();
    IJ.log("pre-aligned all but " + nonPreAlignedTiles.size() + " tiles");
    tileConfiguration.optimize(param.maxEpsilon, param.maxIterationsOptimize, param.maxPlateauwidthOptimize);
    Utils.log(new StringBuffer("Successfully optimized configuration of ").append(tiles.size()).append(" tiles:").toString());
    Utils.log("  average displacement: " + String.format("%.3f", tileConfiguration.getError()) + "px");
    Utils.log("  minimal displacement: " + String.format("%.3f", tileConfiguration.getMinError()) + "px");
    Utils.log("  maximal displacement: " + String.format("%.3f", tileConfiguration.getMaxError()) + "px");
    if (propagateTransformBefore || propagateTransformAfter) {
        final Layer first = layerRange.get(0);
        final List<Layer> layers = first.getParent().getLayers();
        if (propagateTransformBefore) {
            final AffineTransform b = translateAffine(box, ((Affine2D<?>) tiles.get(0).getModel()).createAffine());
            final int firstLayerIndex = first.getParent().getLayerIndex(first.getId());
            for (int i = 0; i < firstLayerIndex; ++i) applyTransformToLayer(layers.get(i), b, filter);
        }
        if (propagateTransformAfter) {
            final Layer last = layerRange.get(layerRange.size() - 1);
            final AffineTransform b = translateAffine(box, ((Affine2D<?>) tiles.get(tiles.size() - 1).getModel()).createAffine());
            final int lastLayerIndex = last.getParent().getLayerIndex(last.getId());
            for (int i = lastLayerIndex + 1; i < layers.size(); ++i) applyTransformToLayer(layers.get(i), b, filter);
        }
    }
    for (int i = 0; i < layerRange.size(); ++i) {
        final AffineTransform b = translateAffine(box, ((Affine2D<?>) tiles.get(i).getModel()).createAffine());
        applyTransformToLayer(layerRange.get(i), b, filter);
    }
    Utils.log("Done.");
}
Also used : ArrayList(java.util.ArrayList) InterpolatedAffineModel2D(mpicbg.models.InterpolatedAffineModel2D) Tile(mpicbg.models.Tile) AbstractAffineModel2D(mpicbg.models.AbstractAffineModel2D) Layer(ini.trakem2.display.Layer) Point(mpicbg.models.Point) NotEnoughDataPointsException(mpicbg.models.NotEnoughDataPointsException) IllDefinedDataPointsException(mpicbg.models.IllDefinedDataPointsException) Triple(mpicbg.trakem2.util.Triple) PointMatch(mpicbg.models.PointMatch) ExecutorService(java.util.concurrent.ExecutorService) Collection(java.util.Collection) Future(java.util.concurrent.Future) AffineTransform(java.awt.geom.AffineTransform) TileConfiguration(mpicbg.models.TileConfiguration)

Aggregations

AbstractAffineModel2D (mpicbg.models.AbstractAffineModel2D)2 InterpolatedAffineModel2D (mpicbg.models.InterpolatedAffineModel2D)2 Layer (ini.trakem2.display.Layer)1 Patch (ini.trakem2.display.Patch)1 AffineTransform (java.awt.geom.AffineTransform)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 ExecutorService (java.util.concurrent.ExecutorService)1 Future (java.util.concurrent.Future)1 IllDefinedDataPointsException (mpicbg.models.IllDefinedDataPointsException)1 NotEnoughDataPointsException (mpicbg.models.NotEnoughDataPointsException)1 Point (mpicbg.models.Point)1 PointMatch (mpicbg.models.PointMatch)1 Tile (mpicbg.models.Tile)1 TileConfiguration (mpicbg.models.TileConfiguration)1 Triple (mpicbg.trakem2.util.Triple)1