use of mpicbg.trakem2.transform.CoordinateTransform in project TrakEM2 by trakem2.
the class Patch method getArea.
/**
* Returns an Area in world coords representing the inside of this Patch. The fully alpha pixels are considered outside.
*/
@Override
public Area getArea() {
CoordinateTransform ct = null;
if (hasAlphaMask()) {
// Read the mask as a ROI for the 0 pixels only and apply the AffineTransform to it:
ImageProcessor alpha_mask = getAlphaMask();
if (null == alpha_mask) {
Utils.log2("Could not retrieve alpha mask for " + this);
} else {
if (hasCoordinateTransform()) {
// must transform it
ct = getCoordinateTransform();
final TransformMesh mesh = new TransformMesh(ct, meshResolution, o_width, o_height);
final TransformMeshMapping mapping = new TransformMeshMapping(mesh);
// Without interpolation
alpha_mask = mapping.createMappedImage(alpha_mask);
// Keep in mind the affine of the Patch already contains the translation specified by the mesh bounds.
}
// Threshold all non-zero areas of the mask:
alpha_mask.setThreshold(1, 255, ImageProcessor.NO_LUT_UPDATE);
final ImagePlus imp = new ImagePlus("", alpha_mask);
// TODO replace by our much faster method that scans by line, in AmiraImporter
final ThresholdToSelection tts = new ThresholdToSelection();
tts.setup("", imp);
tts.run(alpha_mask);
final Roi roi = imp.getRoi();
if (null == roi) {
// All pixels in the alpha mask have a value of zero
return new Area();
}
return M.getArea(roi).createTransformedArea(this.at);
}
}
// No alpha mask, or error in retrieving it:
final int[] x = new int[o_width + o_width + o_height + o_height];
final int[] y = new int[x.length];
int next = 0;
// Top edge:
for (int i = 0; i <= o_width; i++, next++) {
// len: o_width + 1
x[next] = i;
y[next] = 0;
}
// Right edge:
for (int i = 1; i <= o_height; i++, next++) {
// len: o_height
x[next] = o_width;
y[next] = i;
}
// bottom edge:
for (int i = o_width - 1; i > -1; i--, next++) {
// len: o_width
x[next] = i;
y[next] = o_height;
}
// left edge:
for (int i = o_height - 1; i > 0; i--, next++) {
// len: o_height -1
x[next] = 0;
y[next] = i;
}
if (hasCoordinateTransform() && null == ct)
ct = getCoordinateTransform();
if (null != ct) {
final CoordinateTransformList<CoordinateTransform> t = new CoordinateTransformList<CoordinateTransform>();
t.add(ct);
final TransformMesh mesh = new TransformMesh(ct, meshResolution, o_width, o_height);
final Rectangle box = mesh.getBoundingBox();
final AffineTransform aff = new AffineTransform(this.at);
// Must correct for the inverse of the mesh translation, because the affine also includes the translation.
aff.translate(-box.x, -box.y);
final AffineModel2D affm = new AffineModel2D();
affm.set(aff);
t.add(affm);
/*
* WORKS FINE, but for points that fall outside the mesh, they don't get transformed!
// Do it like Patch does it to generate the mipmap, with a mesh (and all the imprecisions of a mesh):
final CoordinateTransformList t = new CoordinateTransformList();
final TransformMesh mesh = new TransformMesh(this.ct, meshResolution, o_width, o_height);
final AffineTransform aff = new AffineTransform(this.at);
t.add(mesh);
final AffineModel2D affm = new AffineModel2D();
affm.set(aff);
t.add(affm);
*/
final double[] f = new double[] { x[0], y[0] };
t.applyInPlace(f);
final Path2D.Float path = new Path2D.Float(Path2D.Float.WIND_EVEN_ODD, x.length + 1);
path.moveTo(f[0], f[1]);
for (int i = 1; i < x.length; i++) {
f[0] = x[i];
f[1] = y[i];
t.applyInPlace(f);
path.lineTo(f[0], f[1]);
}
// line to last call to moveTo
path.closePath();
return new Area(path);
} else {
return new Area(new Polygon(x, y, x.length)).createTransformedArea(this.at);
}
}
use of mpicbg.trakem2.transform.CoordinateTransform in project TrakEM2 by trakem2.
the class Patch method toPixelCoordinate.
/**
* @see Patch#toPixelCoordinate(double, double)
* @param world_x The X of the world coordinate (in pixels, uncalibrated)
* @param world_y The Y of the world coordinate (in pixels, uncalibrated)
* @param aff The {@link AffineTransform} of the {@link Patch}.
* @param ct The {@link CoordinateTransform} of the {@link Patch}, if any (can be null).
* @param meshResolution The precision demanded for approximating a transform with a {@link TransformMesh}.
* @param o_width The width of the image underlying the {@link Patch}.
* @param o_height The height of the image underlying the {@link Patch}.
* @return A {@code double[]} array with the x,y values.
* @throws NoninvertibleTransformException
*/
public static final double[] toPixelCoordinate(final double world_x, final double world_y, final AffineTransform aff, final CoordinateTransform ct, final int meshResolution, final int o_width, final int o_height) throws NoninvertibleTransformException {
// Inverse the affine
final double[] d = new double[] { world_x, world_y };
aff.inverseTransform(d, 0, d, 0, 1);
// Inverse the coordinate transform
if (null != ct) {
final double[] f = new double[] { d[0], d[1] };
final mpicbg.models.InvertibleCoordinateTransform t = mpicbg.models.InvertibleCoordinateTransform.class.isAssignableFrom(ct.getClass()) ? (mpicbg.models.InvertibleCoordinateTransform) ct : new mpicbg.trakem2.transform.TransformMesh(ct, meshResolution, o_width, o_height);
try {
t.applyInverseInPlace(f);
} catch (final NoninvertibleModelException e) {
}
d[0] = f[0];
d[1] = f[1];
}
return d;
}
use of mpicbg.trakem2.transform.CoordinateTransform in project TrakEM2 by trakem2.
the class Patch method getFullCoordinateTransform.
/**
* Create a {@link CoordinateTransform} that incorporates both the
* {@link CoordinateTransform} of this {@link Patch} (if present) and its
* {@link AffineTransform}. The returned {@link CoordinateTransform} directly
* transfers the {@link Patch} into world coordinates. An image can be rendered
* e.g. using {@link mpicbg.ij.TransformMeshMapping} with an
* {@link mpicbg.models.TransformMesh}. Note that you may prefer to use
* {@link mpicbg.models.TransformMesh} which does not perform auto-boxing as
* opposed to {@link TransformMesh} in the mpicbg.trakem2 package.
*
* @return
*/
public final CoordinateTransform getFullCoordinateTransform() {
final CoordinateTransform ctp = getCoordinateTransform();
if (ctp == null) {
final AffineModel2D affine = new AffineModel2D();
affine.set(at);
return affine;
} else {
final Rectangle box = getCoordinateTransformBoundingBox();
final AffineTransform at2 = new AffineTransform(at);
at2.translate(-box.x, -box.y);
final AffineModel2D affine = new AffineModel2D();
affine.set(at2);
final CoordinateTransformList<CoordinateTransform> ctl = new CoordinateTransformList<CoordinateTransform>();
ctl.add(ctp);
ctl.add(affine);
return ctl;
}
}
use of mpicbg.trakem2.transform.CoordinateTransform in project TrakEM2 by trakem2.
the class Patch method setCoordinateTransform.
/**
* Set a CoordinateTransform to this Patch.
* The resulting image of applying the coordinate transform does not need to be rectangular: an alpha mask will take care of the borders. You should call updateMipMaps() afterwards to update the mipmap images used for painting this Patch to the screen.
*/
public final void setCoordinateTransform(final CoordinateTransform ct) {
if (isLinked()) {
Utils.log("Cannot set coordinate transform: patch is linked!");
return;
}
CoordinateTransform this_ct = hasCoordinateTransform() ? getCoordinateTransform() : null;
if (null != this_ct) {
// restore image without the transform
final TransformMesh mesh = new TransformMesh(this_ct, meshResolution, o_width, o_height);
final Rectangle box = mesh.getBoundingBox();
this.at.translate(-box.x, -box.y);
updateInDatabase("transform+dimensions");
}
try {
setNewCoordinateTransform(ct);
} catch (final Exception e) {
throw new RuntimeException(e);
}
this_ct = ct;
updateInDatabase("ict_transform");
if (null == this_ct) {
width = o_width;
height = o_height;
updateBucket();
return;
}
// Adjust the AffineTransform to correct for bounding box displacement
final TransformMesh mesh = new TransformMesh(this_ct, meshResolution, o_width, o_height);
final Rectangle box = mesh.getBoundingBox();
this.at.translate(box.x, box.y);
width = box.width;
height = box.height;
// the AffineTransform
updateInDatabase("transform+dimensions");
updateBucket();
// Updating the mipmaps will call createTransformedImage below if ct is not null
/* DISABLED */
// updateMipMaps();
}
use of mpicbg.trakem2.transform.CoordinateTransform in project TrakEM2 by trakem2.
the class TMLHandler method makeCoordinateTransform.
private final void makeCoordinateTransform(String type, final HashMap<String, String> ht_attributes) {
try {
type = type.toLowerCase();
if (type.equals("ict_transform")) {
final CoordinateTransform ct = (CoordinateTransform) Class.forName(ht_attributes.get("class")).newInstance();
ct.init(ht_attributes.get("data"));
if (ct_list_stack.isEmpty()) {
if (last_patch != null)
last_ct = ct;
} else {
ct_list_stack.get(ct_list_stack.size() - 1).add(ct);
}
} else if (type.equals("iict_transform")) {
final InvertibleCoordinateTransform ict = (InvertibleCoordinateTransform) Class.forName(ht_attributes.get("class")).newInstance();
ict.init(ht_attributes.get("data"));
if (ct_list_stack.isEmpty()) {
if (last_patch != null)
last_ct = ict;
else if (last_stack != null)
last_ict = ict;
} else {
ct_list_stack.get(ct_list_stack.size() - 1).add(ict);
}
} else if (type.equals("ict_transform_list")) {
final CoordinateTransformList<CoordinateTransform> ctl = new CoordinateTransformList<CoordinateTransform>();
if (ct_list_stack.isEmpty()) {
if (last_patch != null)
last_ct = ctl;
} else
ct_list_stack.get(ct_list_stack.size() - 1).add(ctl);
ct_list_stack.add((TransformList) ctl);
} else if (type.equals("iict_transform_list")) {
final InvertibleCoordinateTransformList<InvertibleCoordinateTransform> ictl = new InvertibleCoordinateTransformList<InvertibleCoordinateTransform>();
if (ct_list_stack.isEmpty()) {
if (last_patch != null)
last_ct = ictl;
else if (last_stack != null)
last_ict = ictl;
} else
ct_list_stack.get(ct_list_stack.size() - 1).add(ictl);
ct_list_stack.add((TransformList) ictl);
}
} catch (Exception e) {
IJError.print(e);
}
}
Aggregations