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