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);
}
}
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.");
}
Aggregations