Search in sources :

Example 11 with CoordinateTransform

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);
    }
}
Also used : TransformMeshMapping(mpicbg.trakem2.transform.TransformMeshMapping) CoordinateTransformList(mpicbg.trakem2.transform.CoordinateTransformList) Path2D(java.awt.geom.Path2D) Rectangle(java.awt.Rectangle) ImagePlus(ij.ImagePlus) ShapeRoi(ij.gui.ShapeRoi) Roi(ij.gui.Roi) ImageProcessor(ij.process.ImageProcessor) Area(java.awt.geom.Area) AffineModel2D(mpicbg.trakem2.transform.AffineModel2D) AffineTransform(java.awt.geom.AffineTransform) ThresholdToSelection(ij.plugin.filter.ThresholdToSelection) Polygon(java.awt.Polygon) CoordinateTransform(mpicbg.trakem2.transform.CoordinateTransform) TransformMesh(mpicbg.trakem2.transform.TransformMesh) CoordinateTransformMesh(mpicbg.models.CoordinateTransformMesh)

Example 12 with CoordinateTransform

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;
}
Also used : NoninvertibleModelException(mpicbg.models.NoninvertibleModelException) TransformMesh(mpicbg.trakem2.transform.TransformMesh)

Example 13 with CoordinateTransform

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;
    }
}
Also used : CoordinateTransformList(mpicbg.trakem2.transform.CoordinateTransformList) AffineModel2D(mpicbg.trakem2.transform.AffineModel2D) Rectangle(java.awt.Rectangle) AffineTransform(java.awt.geom.AffineTransform) CoordinateTransform(mpicbg.trakem2.transform.CoordinateTransform)

Example 14 with CoordinateTransform

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();
}
Also used : Rectangle(java.awt.Rectangle) CoordinateTransform(mpicbg.trakem2.transform.CoordinateTransform) NoninvertibleModelException(mpicbg.models.NoninvertibleModelException) NoninvertibleTransformException(java.awt.geom.NoninvertibleTransformException) IOException(java.io.IOException) TransformMesh(mpicbg.trakem2.transform.TransformMesh) CoordinateTransformMesh(mpicbg.models.CoordinateTransformMesh)

Example 15 with CoordinateTransform

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);
    }
}
Also used : InvertibleCoordinateTransformList(mpicbg.trakem2.transform.InvertibleCoordinateTransformList) InvertibleCoordinateTransform(mpicbg.trakem2.transform.InvertibleCoordinateTransform) InvertibleCoordinateTransformList(mpicbg.trakem2.transform.InvertibleCoordinateTransformList) CoordinateTransformList(mpicbg.trakem2.transform.CoordinateTransformList) InvertibleCoordinateTransformList(mpicbg.trakem2.transform.InvertibleCoordinateTransformList) TransformList(mpicbg.models.TransformList) CoordinateTransformList(mpicbg.trakem2.transform.CoordinateTransformList) CoordinateTransform(mpicbg.trakem2.transform.CoordinateTransform) InvertibleCoordinateTransform(mpicbg.trakem2.transform.InvertibleCoordinateTransform) SAXException(org.xml.sax.SAXException) SAXParseException(org.xml.sax.SAXParseException)

Aggregations

CoordinateTransform (mpicbg.trakem2.transform.CoordinateTransform)18 CoordinateTransformList (mpicbg.trakem2.transform.CoordinateTransformList)13 Rectangle (java.awt.Rectangle)12 CoordinateTransformMesh (mpicbg.models.CoordinateTransformMesh)10 AffineTransform (java.awt.geom.AffineTransform)9 AffineModel2D (mpicbg.trakem2.transform.AffineModel2D)7 ImageProcessor (ij.process.ImageProcessor)6 NotEnoughDataPointsException (mpicbg.models.NotEnoughDataPointsException)6 Point (mpicbg.models.Point)6 TransformMesh (mpicbg.trakem2.transform.TransformMesh)6 Area (java.awt.geom.Area)5 NoninvertibleTransformException (java.awt.geom.NoninvertibleTransformException)5 ArrayList (java.util.ArrayList)5 AbstractAffineModel2D (mpicbg.models.AbstractAffineModel2D)5 AffineModel2D (mpicbg.models.AffineModel2D)5 NoninvertibleModelException (mpicbg.models.NoninvertibleModelException)5 TransformMeshMapping (mpicbg.trakem2.transform.TransformMeshMapping)5 Layer (ini.trakem2.display.Layer)4 Patch (ini.trakem2.display.Patch)4 ImagePlus (ij.ImagePlus)3