use of mpicbg.trakem2.transform.CoordinateTransform in project TrakEM2 by trakem2.
the class NonLinearTransformMode method mousePressed.
@Override
public void mousePressed(final MouseEvent me, final int x_p, final int y_p, final double magnification) {
/* find if clicked on a point */
p_clicked = null;
double min = Double.MAX_VALUE;
final Point mouse = new Point(new double[] { x_p, y_p });
final double a = 64.0 / magnification / magnification;
for (final Point p : points) {
final double sd = Point.squareDistance(p, mouse);
if (sd < min && sd < a) {
p_clicked = p;
min = sd;
}
}
if (me.isShiftDown()) {
if (null == p_clicked) {
/* add one */
try {
if (points.size() > 0) {
/*
* Create a pseudo-invertible (TransformMesh) for the screen.
*/
final CoordinateTransform mlst = createCT();
final SimilarityModel2D toWorld = new SimilarityModel2D();
toWorld.set(1.0 / magnification, 0, srcRect.x, srcRect.y);
final SimilarityModel2D toScreen = toWorld.createInverse();
final mpicbg.models.CoordinateTransformList<mpicbg.models.CoordinateTransform> ctl = new mpicbg.models.CoordinateTransformList<mpicbg.models.CoordinateTransform>();
ctl.add(toWorld);
ctl.add(mlst);
ctl.add(toScreen);
final CoordinateTransformMesh ctm = new CoordinateTransformMesh(ctl, 32, (int) Math.ceil(srcRect.width * magnification), (int) Math.ceil(srcRect.height * magnification));
final double[] l = mouse.getL();
toScreen.applyInPlace(l);
ctm.applyInverseInPlace(l);
toWorld.applyInPlace(l);
}
points.add(mouse);
p_clicked = mouse;
} catch (final Exception e) {
Utils.log("Could not add point");
e.printStackTrace();
}
} else if (Utils.isControlDown(me)) {
// remove it
points.remove(p_clicked);
p_clicked = null;
}
}
}
use of mpicbg.trakem2.transform.CoordinateTransform in project TrakEM2 by trakem2.
the class Patch method appendCoordinateTransform.
/**
* Append a {@link CoordinateTransform} to the current
* {@link CoordinateTransformList}. If there is no transform yet, it just
* sets it. If there is only one transform, it replaces it by a list
* containing both, the existing first.
*/
@SuppressWarnings("unchecked")
public final void appendCoordinateTransform(final CoordinateTransform ct) {
if (!hasCoordinateTransform())
setCoordinateTransform(ct);
else {
final CoordinateTransformList<CoordinateTransform> ctl;
final CoordinateTransform this_ct = getCoordinateTransform();
if (this_ct instanceof CoordinateTransformList<?>)
ctl = (CoordinateTransformList<CoordinateTransform>) this_ct.copy();
else {
ctl = new CoordinateTransformList<CoordinateTransform>();
ctl.add(this_ct);
}
ctl.add(ct);
setCoordinateTransform(ctl);
}
}
use of mpicbg.trakem2.transform.CoordinateTransform in project TrakEM2 by trakem2.
the class Patch method makeFlatImage.
/**
* Creates an ImageProcessor of the specified type.
* @param type Any of ImagePlus.GRAY_8, GRAY_16, GRAY_32 or COLOR_RGB.
* @param srcRect the box in world coordinates to make an image out of.
* @param scale may be up to 1.0.
* @param patches The list of patches to paint. The first gets painted first (at the bottom).
* @param background The color with which to paint the outsides where no image paints into.
* @param setMinAndMax defines whether the min and max of each Patch is set before pasting the Patch.
*
* For exporting while blending the display ranges (min,max) and respecting alpha masks, see {@link ExportUnsignedShort}.
*/
public static ImageProcessor makeFlatImage(final int type, final Layer layer, final Rectangle srcRect, final double scale, final Collection<Patch> patches, final Color background, final boolean setMinAndMax) {
final ImageProcessor ip;
final int W, H;
if (scale < 1) {
W = (int) (srcRect.width * scale);
H = (int) (srcRect.height * scale);
} else {
W = srcRect.width;
H = srcRect.height;
}
switch(type) {
case ImagePlus.GRAY8:
ip = new ByteProcessor(W, H);
break;
case ImagePlus.GRAY16:
ip = new ShortProcessor(W, H);
break;
case ImagePlus.GRAY32:
ip = new FloatProcessor(W, H);
break;
case ImagePlus.COLOR_RGB:
ip = new ColorProcessor(W, H);
break;
default:
Utils.logAll("Cannot create an image of type " + type + ".\nSupported types: 8-bit, 16-bit, 32-bit and RGB.");
return null;
}
// Fill with background
if (null != background && Color.black != background) {
ip.setColor(background);
ip.fill();
}
AffineModel2D sc = null;
if (scale < 1.0) {
sc = new AffineModel2D();
sc.set(scale, 0, 0, scale, 0, 0);
}
for (final Patch p : patches) {
// TODO patches seem to come in in inverse order---find out why
// A list to represent all the transformations that the Patch image has to go through to reach the scaled srcRect image
final CoordinateTransformList<CoordinateTransform> list = new CoordinateTransformList<CoordinateTransform>();
final AffineTransform at = new AffineTransform();
at.translate(-srcRect.x, -srcRect.y);
at.concatenate(p.getAffineTransform());
// 1. The coordinate tranform of the Patch, if any
if (p.hasCoordinateTransform()) {
final CoordinateTransform ct = p.getCoordinateTransform();
list.add(ct);
// Remove the translation in the patch_affine that the ct added to it
final Rectangle box = Patch.getCoordinateTransformBoundingBox(p, ct);
at.translate(-box.x, -box.y);
}
// 2. The affine transform of the Patch
final AffineModel2D patch_affine = new AffineModel2D();
patch_affine.set(at);
list.add(patch_affine);
// 3. The desired scaling
if (null != sc)
patch_affine.preConcatenate(sc);
final CoordinateTransformMesh mesh = new CoordinateTransformMesh(list, p.meshResolution, p.getOWidth(), p.getOHeight());
final mpicbg.ij.TransformMeshMapping<CoordinateTransformMesh> mapping = new mpicbg.ij.TransformMeshMapping<CoordinateTransformMesh>(mesh);
// 4. Convert the patch to the required type
ImageProcessor pi = p.getImageProcessor();
if (setMinAndMax) {
pi = pi.duplicate();
pi.setMinAndMax(p.min, p.max);
}
switch(type) {
case ImagePlus.GRAY8:
pi = pi.convertToByte(true);
break;
case ImagePlus.GRAY16:
pi = pi.convertToShort(true);
break;
case ImagePlus.GRAY32:
pi = pi.convertToFloat();
break;
default:
// ImagePlus.COLOR_RGB and COLOR_256
pi = pi.convertToRGB();
break;
}
/* TODO for taking into account independent min/max setting for each patch,
* we will need a mapping with an `intensity transfer function' to be implemented.
* --> EXISTS already as mpicbg/trakem2/transform/ExportUnsignedShort.java
*/
mapping.mapInterpolated(pi, ip);
}
return ip;
}
use of mpicbg.trakem2.transform.CoordinateTransform in project TrakEM2 by trakem2.
the class Patch method keyPressed.
@Override
public void keyPressed(final KeyEvent ke) {
final Object source = ke.getSource();
if (!(source instanceof DisplayCanvas))
return;
final DisplayCanvas dc = (DisplayCanvas) source;
final Roi roi = dc.getFakeImagePlus().getRoi();
final int mod = ke.getModifiers();
switch(ke.getKeyCode()) {
case KeyEvent.VK_C:
// Ignoring masks: outside is already black, and ImageJ cannot handle alpha masks.
if (0 == (mod ^ (Event.SHIFT_MASK | Event.ALT_MASK))) {
// Place the source image, untransformed, into clipboard:
final ImagePlus imp = getImagePlus();
if (null != imp)
imp.copy(false);
} else if (0 == mod || (0 == (mod ^ Event.SHIFT_MASK))) {
CoordinateTransformList<CoordinateTransform> list = null;
if (hasCoordinateTransform()) {
list = new CoordinateTransformList<CoordinateTransform>();
list.add(getCoordinateTransform());
}
if (0 == mod) {
// SHIFT is not down
final AffineModel2D am = new AffineModel2D();
am.set(this.at);
if (null == list)
list = new CoordinateTransformList<CoordinateTransform>();
list.add(am);
}
ImageProcessor ip;
if (null != list) {
final TransformMesh mesh = new TransformMesh(list, meshResolution, o_width, o_height);
final TransformMeshMapping mapping = new TransformMeshMapping(mesh);
ip = mapping.createMappedImageInterpolated(getImageProcessor());
} else {
ip = getImageProcessor();
}
new ImagePlus(this.title, ip).copy(false);
}
ke.consume();
break;
case KeyEvent.VK_F:
// fill mask with current ROI using
if (null != roi && M.isAreaROI(roi)) {
Bureaucrat.createAndStart(new Worker.Task("Filling image mask") {
@Override
public void exec() {
getLayerSet().addDataEditStep(Patch.this);
if (0 == mod) {
addAlphaMask(roi, ProjectToolbar.getForegroundColorValue());
} else if (0 == (mod ^ Event.SHIFT_MASK)) {
// shift is down: fill outside
try {
final Area localRoi = M.areaInInts(M.getArea(roi)).createTransformedArea(at.createInverse());
final Area invLocalRoi = new Area(new Rectangle(0, 0, getOWidth(), getOHeight()));
invLocalRoi.subtract(localRoi);
addAlphaMaskLocal(invLocalRoi, ProjectToolbar.getForegroundColorValue());
} catch (final NoninvertibleTransformException e) {
IJError.print(e);
return;
}
}
getLayerSet().addDataEditStep(Patch.this);
// wait
try {
updateMipMaps().get();
} catch (final Throwable t) {
IJError.print(t);
}
Display.repaint();
}
}, project);
}
// capturing:
ke.consume();
break;
default:
super.keyPressed(ke);
break;
}
}
use of mpicbg.trakem2.transform.CoordinateTransform in project TrakEM2 by trakem2.
the class NonLinearTransformMode method doPainterUpdate.
@Override
protected void doPainterUpdate(final Rectangle r, final double m) {
try {
final CoordinateTransform mlst = createCT();
final SimilarityModel2D toWorld = new SimilarityModel2D();
toWorld.set(1.0 / m, 0, r.x - ScreenPatchRange.pad / m, r.y - ScreenPatchRange.pad / m);
final mpicbg.models.CoordinateTransformList<mpicbg.models.CoordinateTransform> ctl = new mpicbg.models.CoordinateTransformList<mpicbg.models.CoordinateTransform>();
ctl.add(toWorld);
ctl.add(mlst);
ctl.add(toWorld.createInverse());
final CoordinateTransformMesh ctm = new CoordinateTransformMesh(ctl, 32, r.width * m + 2 * ScreenPatchRange.pad, r.height * m + 2 * ScreenPatchRange.pad);
final TransformMeshMappingWithMasks<CoordinateTransformMesh> mapping = new TransformMeshMappingWithMasks<CoordinateTransformMesh>(ctm);
// keep a pointer to the current list
final HashMap<Paintable, GroupingMode.ScreenPatchRange<?>> screenPatchRanges = this.screenPatchRanges;
for (final GroupingMode.ScreenPatchRange spr : screenPatchRanges.values()) {
if (screenPatchRanges != this.screenPatchRanges) {
// TODO should it call itself: doPainterUpdate( r, m );
break;
}
spr.update(mapping);
}
} catch (final NotEnoughDataPointsException e) {
} catch (final NoninvertibleModelException e) {
} catch (final IllDefinedDataPointsException e) {
} catch (final Exception e) {
e.printStackTrace();
}
}
Aggregations