use of ini.trakem2.display.Layer in project TrakEM2 by trakem2.
the class Utils method addLayerChoice.
public static final void addLayerChoice(final String label, final Layer selected, final GenericDialog gd) {
final String[] layers = new String[selected.getParent().size()];
final ArrayList<String> al_layer_titles = new ArrayList<String>();
int i = 0;
for (final Layer layer : selected.getParent().getLayers()) {
layers[i] = selected.getProject().findLayerThing(layer).toString();
al_layer_titles.add(layers[i]);
i++;
}
final int i_layer = selected.getParent().indexOf(selected);
gd.addChoice(label, layers, layers[i_layer]);
}
use of ini.trakem2.display.Layer in project TrakEM2 by trakem2.
the class DistortionCorrectionTask method run.
public static final void run(final CorrectDistortionFromSelectionParam p, final List<Patch> patches, final Displayable active, final Layer layer, final Worker worker) {
/* no multiple inheritance, so p cannot be an Align.ParamOptimize, working around legacy by copying data into one ... */
final Align.ParamOptimize ap = new Align.ParamOptimize();
ap.sift.set(p.sift);
ap.desiredModelIndex = p.desiredModelIndex;
ap.expectedModelIndex = p.expectedModelIndex;
ap.maxEpsilon = p.maxEpsilon;
ap.minInlierRatio = p.minInlierRatio;
ap.rod = p.rod;
ap.identityTolerance = p.identityTolerance;
ap.lambda = p.lambdaRegularize;
ap.maxIterations = p.maxIterationsOptimize;
ap.maxPlateauwidth = p.maxPlateauwidthOptimize;
ap.minNumInliers = p.minNumInliers;
ap.regularize = p.regularize;
ap.regularizerModelIndex = p.regularizerIndex;
ap.rejectIdentity = p.rejectIdentity;
/**
* Get all patches that will be affected.
*/
final List<Patch> allPatches = new ArrayList<Patch>();
for (final Layer l : layer.getParent().getLayers().subList(p.firstLayerIndex, p.lastLayerIndex + 1)) for (final Displayable d : l.getDisplayables(Patch.class)) allPatches.add((Patch) d);
/**
* Unset the coordinate transforms of all patches if desired.
*/
if (p.clearTransform) {
if (worker != null)
worker.setTaskName("Clearing present transforms");
setCoordinateTransform(allPatches, null, Runtime.getRuntime().availableProcessors());
Display.repaint();
}
if (worker != null)
worker.setTaskName("Establishing SIFT correspondences");
final List<AbstractAffineTile2D<?>> tiles = new ArrayList<AbstractAffineTile2D<?>>();
final List<AbstractAffineTile2D<?>> fixedTiles = new ArrayList<AbstractAffineTile2D<?>>();
final List<Patch> fixedPatches = new ArrayList<Patch>();
if (active != null && active instanceof Patch)
fixedPatches.add((Patch) active);
Align.tilesFromPatches(ap, patches, fixedPatches, tiles, fixedTiles);
final List<AbstractAffineTile2D<?>[]> tilePairs = new ArrayList<AbstractAffineTile2D<?>[]>();
if (p.tilesAreInPlace)
AbstractAffineTile2D.pairOverlappingTiles(tiles, tilePairs);
else
AbstractAffineTile2D.pairTiles(tiles, tilePairs);
AbstractAffineTile2D<?> fixedTile = null;
if (fixedTiles.size() > 0)
fixedTile = fixedTiles.get(0);
else
fixedTile = tiles.get(0);
Align.connectTilePairs(ap, tiles, tilePairs, p.maxNumThreadsSift, p.multipleHypotheses);
/**
* Shift all local coordinates into the original image frame
*/
for (final AbstractAffineTile2D<?> tile : tiles) {
final Rectangle box = tile.getPatch().getCoordinateTransformBoundingBox();
for (final PointMatch m : tile.getMatches()) {
final double[] l = m.getP1().getL();
final double[] w = m.getP1().getW();
l[0] += box.x;
l[1] += box.y;
w[0] = l[0];
w[1] = l[1];
}
}
if (Thread.currentThread().isInterrupted())
return;
final List<Set<Tile<?>>> graphs = AbstractAffineTile2D.identifyConnectedGraphs(tiles);
if (graphs.size() > 1)
Utils.log("Could not interconnect all images with correspondences. ");
final List<AbstractAffineTile2D<?>> interestingTiles;
/**
* Find largest graph.
*/
Set<Tile<?>> largestGraph = null;
for (final Set<Tile<?>> graph : graphs) if (largestGraph == null || largestGraph.size() < graph.size())
largestGraph = graph;
interestingTiles = new ArrayList<AbstractAffineTile2D<?>>();
for (final Tile<?> t : largestGraph) interestingTiles.add((AbstractAffineTile2D<?>) t);
if (Thread.currentThread().isInterrupted())
return;
Utils.log("Estimating lens model:");
/* initialize with pure affine */
Align.optimizeTileConfiguration(ap, interestingTiles, fixedTiles);
/* measure the current error */
double e = 0;
int n = 0;
for (final AbstractAffineTile2D<?> t : interestingTiles) for (final PointMatch pm : t.getMatches()) {
e += pm.getDistance();
++n;
}
e /= n;
double dEpsilon_i = 0;
double epsilon_i = e;
double dEpsilon_0 = 0;
NonLinearTransform lensModel = null;
Utils.log("0: epsilon = " + e);
/* Store original point locations */
final HashMap<Point, Point> originalPoints = new HashMap<Point, Point>();
for (final AbstractAffineTile2D<?> t : interestingTiles) for (final PointMatch pm : t.getMatches()) originalPoints.put(pm.getP1(), pm.getP1().clone());
/* ad hoc conditions to terminate iteration:
* small improvement ( 1/1000) relative to first iteration
* less than 20 iterations
* at least 2 iterations */
for (int i = 1; i < 20 && (i < 2 || dEpsilon_i <= dEpsilon_0 / 1000); ++i) {
if (Thread.currentThread().isInterrupted())
return;
/* Some data shuffling for the lens correction interface */
final List<PointMatchCollectionAndAffine> matches = new ArrayList<PointMatchCollectionAndAffine>();
for (final AbstractAffineTile2D<?>[] tilePair : tilePairs) {
final AffineTransform a = tilePair[0].createAffine();
a.preConcatenate(tilePair[1].getModel().createInverseAffine());
final Collection<PointMatch> commonMatches = new ArrayList<PointMatch>();
tilePair[0].commonPointMatches(tilePair[1], commonMatches);
final Collection<PointMatch> originalCommonMatches = new ArrayList<PointMatch>();
for (final PointMatch pm : commonMatches) originalCommonMatches.add(new PointMatch(originalPoints.get(pm.getP1()), originalPoints.get(pm.getP2())));
matches.add(new PointMatchCollectionAndAffine(a, originalCommonMatches));
}
if (worker != null)
worker.setTaskName("Estimating lens distortion correction");
lensModel = Distortion_Correction.createInverseDistortionModel(matches, p.dimension, p.lambda, (int) fixedTile.getWidth(), (int) fixedTile.getHeight());
/* update local points */
for (final AbstractAffineTile2D<?> t : interestingTiles) for (final PointMatch pm : t.getMatches()) {
final Point currentPoint = pm.getP1();
final Point originalPoint = originalPoints.get(currentPoint);
final double[] l = currentPoint.getL();
final double[] lo = originalPoint.getL();
l[0] = lo[0];
l[1] = lo[1];
lensModel.applyInPlace(l);
}
/* re-optimize */
Align.optimizeTileConfiguration(ap, interestingTiles, fixedTiles);
/* measure the current error */
e = 0;
n = 0;
for (final AbstractAffineTile2D<?> t : interestingTiles) for (final PointMatch pm : t.getMatches()) {
e += pm.getDistance();
++n;
}
e /= n;
dEpsilon_i = e - epsilon_i;
epsilon_i = e;
if (i == 1)
dEpsilon_0 = dEpsilon_i;
Utils.log(i + ": epsilon = " + e);
Utils.log(i + ": delta epsilon = " + dEpsilon_i);
}
if (lensModel != null) {
if (p.visualize) {
if (Thread.currentThread().isInterrupted())
return;
if (worker != null)
worker.setTaskName("Visualizing lens distortion correction");
lensModel.visualizeSmall(p.lambda);
}
if (worker != null)
worker.setTaskName("Applying lens distortion correction");
appendCoordinateTransform(allPatches, lensModel, Runtime.getRuntime().availableProcessors());
Utils.log("Done.");
} else
Utils.log("No lens model found.");
}
use of ini.trakem2.display.Layer in project TrakEM2 by trakem2.
the class Search method createCoordinate.
private Coordinate<Displayable> createCoordinate(final Displayable d) {
Rectangle r = d.getBoundingBox();
Layer la = d instanceof ZDisplayable ? ((ZDisplayable) d).getFirstLayer() : d.getLayer();
if (null == la) {
Display display = Display.getFront(d.getProject());
if (null == display)
la = d.getProject().getRootLayerSet().getLayer(0);
else
la = display.getLayer();
}
return new Coordinate<Displayable>(r.x + r.width / 2, r.y + r.height / 2, la, d);
}
use of ini.trakem2.display.Layer in project TrakEM2 by trakem2.
the class DNDInsertImage method importImageFile.
private boolean importImageFile(File f, String path, Point point) throws Exception {
if (f.exists()) {
final Layer layer = display.getLayer();
Bureaucrat burro = null;
if (f.isDirectory()) {
// ask:
GenericDialog gd = new GenericDialog("Import directory");
String[] choice = new String[] { "Stack", "Grid", "Sequence as grid" };
gd.addChoice("Directory as: ", choice, choice[0]);
gd.showDialog();
if (gd.wasCanceled()) {
// the user cancel it, so all is ok.
return true;
}
display.getLayerSet().addLayerContentStep(layer);
switch(gd.getNextChoiceIndex()) {
case // as stack
0:
// if importing image sequence as a stack:
// don't filter by name "^[^\\.].*[\\.][a-zA-Z1-9_]{3,4}$"
String[] names = f.list(new ImageFileFilter());
Utils.log2("stack size: " + names.length);
for (int i = 0; i < names.length; i++) {
Utils.log2(names[i]);
}
Arrays.sort(names);
// I don't care about the dimensions
VirtualStack stack = new VirtualStack(10, 10, null, f.getAbsolutePath().replace('\\', '/'));
for (int k = 0; k < names.length; k++) {
IJ.redirectErrorMessages();
// ignore trakem2 files
if (names[k].toLowerCase().endsWith(".xml"))
continue;
stack.addSlice(names[k]);
}
if (stack.getSize() > 0) {
burro = display.getProject().getLoader().importStack(layer, point.x, point.y, new ImagePlus("stack", stack), true, path, false);
}
break;
case // as grid
1:
burro = display.getProject().getLoader().importGrid(layer, path);
break;
case // sequence as grid
2:
burro = display.getProject().getLoader().importSequenceAsGrid(layer, path);
break;
}
} else {
layer.getParent().addLayerContentStep(layer);
// single image file (single image or a stack)
burro = display.getProject().getLoader().importImage(layer, point.x, point.y, path, false);
}
if (null != burro) {
burro.addPostTask(new Runnable() {
public void run() {
// The current state
layer.getParent().addLayerContentStep(layer);
}
});
}
return true;
} else {
Utils.log("File not found: " + path);
return false;
}
}
use of ini.trakem2.display.Layer in project TrakEM2 by trakem2.
the class AreaList method interpolate.
/**
* Interpolate areas between the given first and last layers,
* both of which must contain an area.
*
* @return false if the interpolation could not be done.
* @throws Exception
*/
public boolean interpolate(final Layer first, final Layer last, final boolean always_use_distance_map) throws Exception {
int i1 = layer_set.indexOf(first);
int i2 = layer_set.indexOf(last);
if (i1 > i2) {
final int tmp = i1;
i1 = i2;
i2 = tmp;
}
final List<Layer> range = layer_set.getLayers().subList(i1, i2 + 1);
Area start = null;
int istart = 0;
int inext = -1;
final HashSet<Layer> touched = new HashSet<Layer>();
for (final Layer la : range) {
inext++;
final Area next = getArea(la);
if (null == next || next.isEmpty())
continue;
if (null == start || 0 == inext - istart - 1) {
// skip for first area or for no space in between
start = next;
istart = inext;
continue;
}
// Interpolate from start to next
Area[] as = always_use_distance_map ? null : AreaUtils.singularInterpolation(start, next, inext - istart - 1);
if (null == as) {
// NOT SINGULAR: must use BinaryInterpolation2D
as = AreaUtils.manyToManyInterpolation(start, next, inext - istart - 1);
}
if (null != as) {
for (int k = 0; k < as.length; k++) {
final Layer la2 = range.get(k + istart + 1);
addArea(la2.getId(), as[k]);
touched.add(la2);
}
}
// Prepare next interval
start = next;
istart = inext;
}
for (final Layer la : touched) calculateBoundingBox(la);
return true;
}
Aggregations