use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.
the class Utils method addPlugIns.
/**
* Returns null if none to add.
*/
public static final JMenu addPlugIns(final String menu, final Project project, final Callable<Displayable> active) {
final Map<String, TPlugIn> plugins = project.getPlugins(menu);
if (0 == plugins.size())
return null;
Displayable d = null;
try {
d = active.call();
} catch (final Exception e) {
IJError.print(e);
}
final JMenu m = new JMenu("Plugins");
JMenuItem item;
int count = 0;
for (final Map.Entry<String, TPlugIn> e : plugins.entrySet()) {
item = new JMenuItem(e.getKey());
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent ae) {
Bureaucrat.createAndStart(new Worker.Task(e.getKey()) {
@Override
public void exec() {
try {
e.getValue().invoke(active.call());
} catch (final Exception e) {
IJError.print(e);
}
}
}, project);
}
});
item.setEnabled(e.getValue().applies(d));
if (count < 9) {
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1 + count, Utils.getControlModifier(), true));
}
m.add(item);
count++;
}
if (0 == m.getItemCount())
return null;
m.addSeparator();
// Now all the "Setup " + name
for (final Map.Entry<String, TPlugIn> e : plugins.entrySet()) {
item = new JMenuItem("Setup " + e.getKey());
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent ae) {
Bureaucrat.createAndStart(new Worker.Task(e.getKey()) {
@Override
public void exec() {
try {
e.getValue().setup(active.call());
} catch (final Exception e) {
IJError.print(e);
}
}
}, project);
}
});
m.add(item);
}
return m;
}
use of ini.trakem2.display.Displayable 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.Displayable in project TrakEM2 by trakem2.
the class Merger method compare.
/**
* Take two projects and find out what is different among them,
* independent of id.
*/
public static final void compare(final Project p1, final Project p2) {
Utils.log("Be warned: only Treeline, AreaTree and Connector are considered at the moment.");
final LayerSet ls1 = p1.getRootLayerSet(), ls2 = p2.getRootLayerSet();
final Collection<ZDisplayable> zds1 = ls1.getZDisplayables(), zds2 = ls2.getZDisplayables();
final HashSet<Class<?>> accepted = new HashSet<Class<?>>();
accepted.add(Treeline.class);
accepted.add(AreaTree.class);
accepted.add(Connector.class);
final HashMap<Displayable, List<Change>> matched = new HashMap<Displayable, List<Change>>();
final HashSet<ZDisplayable> empty1 = new HashSet<ZDisplayable>(), empty2 = new HashSet<ZDisplayable>();
final HashSet<ZDisplayable> unmatched1 = new HashSet<ZDisplayable>(), unmatched2 = new HashSet<ZDisplayable>(zds2);
// Remove instances of classes not accepted
for (final Iterator<ZDisplayable> it = unmatched2.iterator(); it.hasNext(); ) {
ZDisplayable zd = it.next();
if (!accepted.contains(zd.getClass())) {
it.remove();
continue;
}
if (zd.isDeletable()) {
it.remove();
empty2.add(zd);
}
}
zds2.removeAll(empty2);
final AtomicInteger counter = new AtomicInteger(0);
// or at least one or more that are similar in that they have some nodes in common.
try {
ini.trakem2.parallel.Process.unbound(zds1, new TaskFactory<ZDisplayable, Object>() {
@Override
public Object process(final ZDisplayable zd1) {
Utils.showProgress(counter.getAndIncrement() / (float) zds1.size());
if (!accepted.contains(zd1.getClass())) {
Utils.log("Ignoring: [A] " + zd1);
return null;
}
if (zd1.isDeletable()) {
synchronized (empty1) {
empty1.add(zd1);
}
return null;
}
final List<Change> cs = new ArrayList<Change>();
for (final ZDisplayable zd2 : zds2) {
// Same class?
if (zd1.getClass() != zd2.getClass())
continue;
if (zd1 instanceof Tree<?> && zd2 instanceof Tree<?>) {
Change c = compareTrees(zd1, zd2);
if (c.hasSimilarNodes()) {
cs.add(c);
if (1 == cs.size()) {
synchronized (matched) {
matched.put(zd1, cs);
}
}
synchronized (unmatched2) {
unmatched2.remove(zd2);
}
}
// debug
if (zd1.getId() == zd2.getId()) {
Utils.log("zd1 #" + zd1.getId() + " is similar to #" + zd2.getId() + ": " + c.hasSimilarNodes());
}
}
}
if (cs.isEmpty()) {
synchronized (unmatched1) {
unmatched1.add(zd1);
}
}
return null;
}
});
} catch (Exception e) {
IJError.print(e);
}
// reset
Utils.showProgress(1);
Utils.log("matched.size(): " + matched.size());
makeGUI(p1, p2, empty1, empty2, matched, unmatched1, unmatched2);
}
use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.
the class ProjectTree method remove.
/**
* Remove the Thing and DefaultMutableTreeNode that wrap each of the Displayable;
* calls softRemove on each Displayable, and does NOT call remove on the Displayable.
* If a Displayable is not found, it returns it in a set of not found objects.
* If all are removed, returns an empty set.
*/
public final Set<Displayable> remove(final Set<? extends Displayable> displayables, final DefaultMutableTreeNode top) {
final Enumeration<?> en = (null == top ? (DefaultMutableTreeNode) getModel().getRoot() : top).depthFirstEnumeration();
final HashSet<DefaultMutableTreeNode> to_remove = new HashSet<DefaultMutableTreeNode>();
final HashSet<Displayable> remaining = new HashSet<Displayable>(displayables);
while (en.hasMoreElements()) {
final DefaultMutableTreeNode node = (DefaultMutableTreeNode) en.nextElement();
final ProjectThing pt = (ProjectThing) node.getUserObject();
if (remaining.remove(pt.getObject())) {
// don't call remove on the object!
pt.remove(false, false);
((Displayable) pt.getObject()).softRemove();
to_remove.add(node);
}
}
// Updates the model properly:
for (final DefaultMutableTreeNode node : to_remove) {
((DefaultTreeModel) this.getModel()).removeNodeFromParent(node);
}
if (!remaining.isEmpty()) {
Utils.log("Could not remove:", remaining);
}
return remaining;
}
use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.
the class ProjectTree method selectInDisplay.
public void selectInDisplay(final ProjectThing thing, final boolean shift_down) {
Object obd = thing.getObject();
if (obd instanceof Displayable) {
Displayable d = (Displayable) obd;
if (!d.isVisible())
d.setVisible(true);
Display display = Display.getFront(d.getProject());
if (null == display)
return;
display.select(d, shift_down);
} else {
// select all basic types under this leaf
final List<Displayable> ds = thing.findChildrenOfType(Displayable.class);
Display display = null;
for (final Iterator<Displayable> it = ds.iterator(); it.hasNext(); ) {
final Displayable d = it.next();
if (null == display) {
display = Display.getFront(d.getProject());
if (null == display)
return;
}
if (!d.isVisible()) {
Utils.log("Skipping non-visible object " + d);
it.remove();
}
}
if (null == display)
return;
if (!shift_down)
display.getSelection().clear();
display.getSelection().selectAll(ds);
}
}
Aggregations