use of mpicbg.trakem2.transform.TransformMesh 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.TransformMesh 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.TransformMesh in project TrakEM2 by trakem2.
the class Patch method addAlphaMaskLocal.
/**
* Add the given area, in local coordinates, to the alpha mask, using the given fill value.
*/
public void addAlphaMaskLocal(final Area aLocal, int value) {
if (value < 0)
value = 0;
if (value > 255)
value = 255;
//
CoordinateTransform ct = null;
if (hasCoordinateTransform() && null == (ct = getCT())) {
return;
}
// When the area is larger than the image, sometimes the area fails to be set at all
// Also, intersection accelerates calls to contains(x,y) for complex polygons
final Area a = new Area(new Rectangle(0, 0, (int) (width + 1), (int) (height + 1)));
a.intersect(aLocal);
if (M.isEmpty(a)) {
Utils.log("ROI does not intersect the active image!");
return;
}
ByteProcessor mask = getAlphaMask();
// Use imglib to bypass all the problems with ShapeROI
// Create a Shape image with background and the Area on it with 'value'
final int background = (null != mask && 255 == value) ? 0 : 255;
final ShapeList<UnsignedByteType> shapeList = new ShapeList<UnsignedByteType>(new int[] { (int) width, (int) height, 1 }, new UnsignedByteType(background));
shapeList.addShape(a, new UnsignedByteType(value), new int[] { 0 });
final mpicbg.imglib.image.Image<UnsignedByteType> shapeListImage = new mpicbg.imglib.image.Image<UnsignedByteType>(shapeList, shapeList.getBackground(), "mask");
ByteProcessor rmask = (ByteProcessor) ImageJFunctions.copyToImagePlus(shapeListImage, ImagePlus.GRAY8).getProcessor();
if (hasCoordinateTransform()) {
// inverse the coordinate transform
final TransformMesh mesh = new TransformMesh(ct, meshResolution, o_width, o_height);
final TransformMeshMapping mapping = new TransformMeshMapping(mesh);
rmask = (ByteProcessor) mapping.createInverseMappedImageInterpolated(rmask);
}
if (null == mask) {
// There wasn't a mask, hence just set it
mask = rmask;
} else {
final byte[] b1 = (byte[]) mask.getPixels();
final byte[] b2 = (byte[]) rmask.getPixels();
// Whatever is not background in the new mask gets set on the old mask
for (int i = 0; i < b1.length; i++) {
// background pixel in new mask
if (background == (b2[i] & 0xff))
continue;
// replace old pixel with new pixel
b1[i] = b2[i];
}
}
setAlphaMask(mask);
}
use of mpicbg.trakem2.transform.TransformMesh in project TrakEM2 by trakem2.
the class Patch method getLocalAffine.
/**
* Return the local affine transformation for a passed location in world
* coordinates. This affine transform is either the global affine
* transform of the patch or the combined affine transform of the local
* affine transform in the transform mesh and its global affine transform.
*
* @param wx
* @param wy
* @return
*/
public AffineTransform getLocalAffine(final double wx, final double wy) {
final AffineTransform affine = new AffineTransform(at);
if (hasCoordinateTransform()) {
final CoordinateTransform ct = getCoordinateTransform();
final double[] w = new double[] { wx, wy };
try {
at.inverseTransform(w, 0, w, 0, 1);
} catch (final NoninvertibleTransformException e) {
}
final TransformMesh mesh = new TransformMesh(ct, meshResolution, o_width, o_height);
final mpicbg.models.AffineModel2D triangle = mesh.closestTargetAffine(new double[] { w[0], w[1] });
affine.concatenate(triangle.createAffine());
}
return affine;
}
use of mpicbg.trakem2.transform.TransformMesh in project TrakEM2 by trakem2.
the class Patch method createCoordinateTransformedImage.
public final Patch.PatchImage createCoordinateTransformedImage() {
if (!hasCoordinateTransform())
return null;
final CoordinateTransform ct = getCoordinateTransform();
final ImageProcessor source = getImageProcessor();
// some error occurred
if (null == source)
return null;
// Utils.log2("source image dimensions: " + source.getWidth() + ", " + source.getHeight());
final TransformMesh mesh = new TransformMesh(ct, meshResolution, o_width, o_height);
final Rectangle box = mesh.getBoundingBox();
/* We can calculate the exact size of the image to be rendered, so let's do it */
// project.getLoader().releaseToFit(o_width, o_height, type, 5);
final long b = // outside and mask source
2 * o_width * o_height + // outside and mask target
2 * box.width * box.height + // image source
5 * o_width * o_height + // image target
5 * box.width * box.height;
project.getLoader().releaseToFit(b);
final TransformMeshMapping mapping = new TransformMeshMapping(mesh);
final ImageProcessorWithMasks target = mapping.createMappedMaskedImageInterpolated(source, getAlphaMask());
// Set the LUT
target.ip.setColorModel(source.getColorModel());
return new PatchImage(target.ip, (ByteProcessor) target.mask, target.outside, box, true);
}
Aggregations