use of mpicbg.trakem2.transform.AffineModel3D in project TrakEM2 by trakem2.
the class Display method insertStack.
/**
* @param stack_patch is just a Patch of a series of Patch that make a stack of Patches.
*/
private boolean insertStack(final ProjectThing target_landmarks, final Project source, final ProjectThing source_landmarks, final Patch stack_patch) {
final List<Ball> l1 = new ArrayList<Ball>();
final List<Ball> l2 = new ArrayList<Ball>();
// source is the one that has the stack_patch
final Collection<ProjectThing> b1s = source_landmarks.findChildrenOfType("ball");
// target is this
final Collection<ProjectThing> b2s = target_landmarks.findChildrenOfType("ball");
final HashSet<String> seen = new HashSet<String>();
for (final ProjectThing b1 : b1s) {
final Ball ball1 = (Ball) b1.getObject();
if (null == ball1) {
Utils.log("ERROR: there's an empty 'ball' node in target project" + project.toString());
return false;
}
final String title1 = ball1.getTitle();
for (final ProjectThing b2 : b2s) {
final Ball ball2 = (Ball) b2.getObject();
if (null == ball2) {
Utils.log("ERROR: there's an empty 'ball' node in source project" + source.toString());
return false;
}
if (title1.equals(ball2.getTitle())) {
if (seen.contains(title1))
continue;
seen.add(title1);
l1.add(ball1);
l2.add(ball2);
}
}
}
if (l1.size() < 4) {
Utils.log("ERROR: found only " + l1.size() + " common landmarks: needs at least 4!");
return false;
}
// Extract coordinates of source project landmarks, in patch stack coordinate space
final List<double[]> c1 = new ArrayList<double[]>();
for (final Ball ball1 : l1) {
final Map<Layer, double[]> m = ball1.getRawBalls();
if (1 != m.size()) {
Utils.log("ERROR: ball object " + ball1 + " from target project " + project + " has " + m.size() + " balls instead of just 1.");
return false;
}
final Map.Entry<Layer, double[]> e = m.entrySet().iterator().next();
final Layer layer = e.getKey();
final double[] xyr = e.getValue();
final double[] fin = new double[] { xyr[0], xyr[1] };
final AffineTransform affine = ball1.getAffineTransformCopy();
try {
affine.preConcatenate(stack_patch.getAffineTransform().createInverse());
} catch (final Exception nite) {
IJError.print(nite);
return false;
}
final double[] fout = new double[2];
affine.transform(fin, 0, fout, 0, 1);
c1.add(new double[] { fout[0], fout[1], layer.getParent().indexOf(layer) });
}
// Extract coordinates of target (this) project landmarks, in calibrated world space
final List<double[]> c2 = new ArrayList<double[]>();
for (final Ball ball2 : l2) {
final double[][] b = ball2.getBalls();
if (1 != b.length) {
Utils.log("ERROR: ball object " + ball2 + " from source project " + source + " has " + b.length + " balls instead of just 1.");
return false;
}
final double[] fin = new double[] { b[0][0], b[0][1] };
final AffineTransform affine = ball2.getAffineTransformCopy();
final double[] fout = new double[2];
affine.transform(fin, 0, fout, 0, 1);
c2.add(new double[] { fout[0], fout[1], b[0][2] });
}
// Print landmarks:
Utils.log("Landmarks:");
for (Iterator<double[]> it1 = c1.iterator(), it2 = c2.iterator(); it1.hasNext(); ) {
Utils.log(Utils.toString(it1.next()) + " <--> " + Utils.toString(it2.next()));
}
// Create point matches
final List<PointMatch> pm = new ArrayList<PointMatch>();
for (Iterator<double[]> it1 = c1.iterator(), it2 = c2.iterator(); it1.hasNext(); ) {
pm.add(new mpicbg.models.PointMatch(new mpicbg.models.Point(it1.next()), new mpicbg.models.Point(it2.next())));
}
// Estimate AffineModel3D
final AffineModel3D aff3d = new AffineModel3D();
try {
aff3d.fit(pm);
} catch (final Exception e) {
IJError.print(e);
return false;
}
// Create and add the Stack
final String path = stack_patch.getImageFilePath();
final Stack st = new Stack(project, new File(path).getName(), 0, 0, getLayerSet().getLayers().get(0), path);
st.setInvertibleCoordinateTransform(aff3d);
getLayerSet().add(st);
return true;
}
use of mpicbg.trakem2.transform.AffineModel3D in project TrakEM2 by trakem2.
the class Stack method fetchFutureImage.
private final Future<Image> fetchFutureImage(final Long imageId, final double magnification, final Layer active_layer, final boolean trigger_repaint_event) {
synchronized (futureImages) {
Future<Image> fu = futureImages.get(imageId);
if (null == fu) {
fu = project.getLoader().doLater(new Callable<Image>() {
@Override
public Image call() {
final InvertibleCoordinateTransformList<mpicbg.models.InvertibleCoordinateTransform> ictl = new InvertibleCoordinateTransformList<mpicbg.models.InvertibleCoordinateTransform>();
if (ict != null) {
// Utils.log2( "ictScale of " + getTitle() + " is " + ictScale );
ictl.add(ict);
/* Remove boundingBox shift ict ... */
final TranslationModel3D unShiftBounds = new TranslationModel3D();
unShiftBounds.set(-boundsMin[0], -boundsMin[1], 0);
ictl.add(unShiftBounds);
if (ictScale != 1.0) {
final AffineModel3D unScaleXY = new AffineModel3D();
unScaleXY.set(1.0 / ictScale, 0, 0, 0, 0, 1.0 / ictScale, 0, 0, 0, 0, 1.0, 0);
ictl.add(unScaleXY);
}
}
/* TODO remove that scale from ict and put it into atp */
final ImagePlus imp = project.getLoader().fetchImagePlus(Stack.this);
final ImageProcessor ip = imp.getStack().getProcessor(1).createProcessor((int) Math.ceil((boundsMax[0] - boundsMin[0]) / ictScale), (int) Math.ceil((boundsMax[1] - boundsMin[1]) / ictScale));
// Utils.log2( "ictScale is " + ictScale );
// Utils.log2( "rendering an image of " + ip.getWidth() + " x " + ip.getHeight() + " px" );
final double currentZ = active_layer.getZ();
final TranslationModel3D sliceShift = new TranslationModel3D();
sliceShift.set(0, 0, -currentZ);
ictl.add(sliceShift);
/* optimization: if ict is affine, reduce ictl into a single affine */
final InverseTransformMapping<mpicbg.models.InvertibleCoordinateTransform> mapping;
if (AffineModel3D.class.isInstance(ict)) {
final AffineModel3D ictAffine = new AffineModel3D();
boolean isAffine = true;
for (final mpicbg.models.InvertibleCoordinateTransform t : ictl.getList(null)) {
if (AffineModel3D.class.isInstance(t))
ictAffine.preConcatenate((AffineModel3D) t);
else if (TranslationModel3D.class.isInstance(t))
ictAffine.preConcatenate((TranslationModel3D) t);
else {
isAffine = false;
break;
}
}
if (isAffine)
mapping = new InverseTransformMapping<mpicbg.models.InvertibleCoordinateTransform>(ictAffine);
else
mapping = new InverseTransformMapping<mpicbg.models.InvertibleCoordinateTransform>(ictl);
} else
mapping = new InverseTransformMapping<mpicbg.models.InvertibleCoordinateTransform>(ictl);
mapping.mapInterpolated(imp.getStack(), ip);
// wast: atp
final double s = estimateAffineScale(new AffineTransform(at));
final double smoothMag = magnification * s * ictScale;
if (smoothMag < 1.0f) {
Filter.smoothForScale(ip, smoothMag, 0.5f, 0.5f);
}
final Image image = ip.createImage();
if (null == image) {
Utils.log2("Stack.paint: null image, returning");
// TEMPORARY from lazy
return null;
// repaints after closing a
// Project
}
project.getLoader().cacheAWT(imageId, image);
synchronized (futureImages) {
futureImages.remove(imageId);
}
if (trigger_repaint_event) {
// Display.repaint( active_layer, Stack.this );
Display.repaint(active_layer);
}
return image;
}
});
}
// else {
// Utils.log2( "fu is not null" );
// // We don't do anything: we wait for itself to launch a
// repaint event
// }
futureImages.put(imageId, fu);
return fu;
}
}
Aggregations