Search in sources :

Example 6 with AffineModel2D

use of mpicbg.trakem2.transform.AffineModel2D in project TrakEM2 by trakem2.

the class Util method applyLayerTransformToPatch.

public static final void applyLayerTransformToPatch(final Patch patch, final CoordinateTransform ct) throws Exception {
    final Rectangle pbox = patch.getCoordinateTransformBoundingBox();
    final AffineTransform pat = new AffineTransform();
    pat.translate(-pbox.x, -pbox.y);
    pat.preConcatenate(patch.getAffineTransform());
    final AffineModel2D toWorld = new AffineModel2D();
    toWorld.set(pat);
    final CoordinateTransformList<CoordinateTransform> ctl = new CoordinateTransformList<CoordinateTransform>();
    ctl.add(toWorld);
    ctl.add(ct);
    ctl.add(toWorld.createInverse());
    patch.appendCoordinateTransform(ctl);
}
Also used : CoordinateTransformList(mpicbg.trakem2.transform.CoordinateTransformList) Rectangle(java.awt.Rectangle) AffineModel2D(mpicbg.trakem2.transform.AffineModel2D) AffineTransform(java.awt.geom.AffineTransform) CoordinateTransform(mpicbg.trakem2.transform.CoordinateTransform)

Example 7 with AffineModel2D

use of mpicbg.trakem2.transform.AffineModel2D in project TrakEM2 by trakem2.

the class ExportARGB method makeFlatImageARGBFromOriginals.

/**
 * Limited to 2GB arrays for the requested image.
 *
 * @param patches
 * @param roi
 * @param backgroundValue
 * @param scale
 * @return
 */
public static final Pair<ColorProcessor, ByteProcessor> makeFlatImageARGBFromOriginals(final List<Patch> patches, final Rectangle roi, final double backgroundValue, final double scale) {
    final ColorProcessor target = new ColorProcessor((int) (roi.width * scale), (int) (roi.height * scale));
    target.setInterpolationMethod(ImageProcessor.BILINEAR);
    final ByteProcessor targetMask = new ByteProcessor(target.getWidth(), target.getHeight());
    targetMask.setInterpolationMethod(ImageProcessor.NEAREST_NEIGHBOR);
    for (final Patch patch : patches) {
        final Patch.PatchImage pai = patch.createTransformedImage();
        final ColorProcessor fp = (ColorProcessor) pai.target.convertToRGB();
        final ByteProcessor alpha;
        System.out.println("IMAGE:" + patch.getTitle());
        System.out.println("mask: " + pai.mask);
        System.out.println("outside: " + pai.outside);
        if (null == pai.mask) {
            if (null == pai.outside) {
                alpha = new ByteProcessor(fp.getWidth(), fp.getHeight());
                // fully opaque
                Arrays.fill((byte[]) alpha.getPixels(), (byte) 255);
            } else {
                alpha = pai.outside;
            }
        } else {
            alpha = pai.mask;
        }
        // The affine to apply
        final AffineTransform atc = new AffineTransform();
        atc.scale(scale, scale);
        atc.translate(-roi.x, -roi.y);
        final AffineTransform at = new AffineTransform();
        at.preConcatenate(atc);
        at.concatenate(patch.getAffineTransform());
        final AffineModel2D aff = new AffineModel2D();
        aff.set(at);
        final CoordinateTransformMesh mesh = new CoordinateTransformMesh(aff, patch.getMeshResolution(), fp.getWidth(), fp.getHeight());
        final TransformMeshMappingWithMasks<CoordinateTransformMesh> mapping = new TransformMeshMappingWithMasks<CoordinateTransformMesh>(mesh);
        fp.setInterpolationMethod(ImageProcessor.BILINEAR);
        // no interpolation
        alpha.setInterpolationMethod(ImageProcessor.NEAREST_NEIGHBOR);
        mapping.map(fp, alpha, target, targetMask);
    }
    return new Pair<ColorProcessor, ByteProcessor>(target, targetMask);
}
Also used : ByteProcessor(ij.process.ByteProcessor) ColorProcessor(ij.process.ColorProcessor) CoordinateTransformMesh(mpicbg.models.CoordinateTransformMesh) AffineTransform(java.awt.geom.AffineTransform) Patch(ini.trakem2.display.Patch) Pair(mpicbg.trakem2.util.Pair)

Example 8 with AffineModel2D

use of mpicbg.trakem2.transform.AffineModel2D in project TrakEM2 by trakem2.

the class NonLinearTransformMode method applyToPatch.

private final Future<Boolean> applyToPatch(final Patch patch) throws Exception {
    final Rectangle pbox = patch.getCoordinateTransformBoundingBox();
    final AffineTransform pat = new AffineTransform();
    pat.translate(-pbox.x, -pbox.y);
    pat.preConcatenate(patch.getAffineTransform());
    final AffineModel2D toWorld = new AffineModel2D();
    toWorld.set(pat);
    final CoordinateTransform mlst = createCT();
    final CoordinateTransformList<CoordinateTransform> ctl = new CoordinateTransformList<CoordinateTransform>();
    ctl.add(toWorld);
    ctl.add(mlst);
    ctl.add(toWorld.createInverse());
    patch.appendCoordinateTransform(ctl);
    return patch.updateMipMaps();
}
Also used : CoordinateTransformList(mpicbg.trakem2.transform.CoordinateTransformList) Rectangle(java.awt.Rectangle) AbstractAffineModel2D(mpicbg.models.AbstractAffineModel2D) AffineModel2D(mpicbg.trakem2.transform.AffineModel2D) AffineTransform(java.awt.geom.AffineTransform) CoordinateTransform(mpicbg.trakem2.transform.CoordinateTransform)

Example 9 with AffineModel2D

use of mpicbg.trakem2.transform.AffineModel2D 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;
}
Also used : ByteProcessor(ij.process.ByteProcessor) TransformMeshMapping(mpicbg.trakem2.transform.TransformMeshMapping) FloatProcessor(ij.process.FloatProcessor) CoordinateTransformList(mpicbg.trakem2.transform.CoordinateTransformList) Rectangle(java.awt.Rectangle) ShortProcessor(ij.process.ShortProcessor) ImageProcessor(ij.process.ImageProcessor) ColorProcessor(ij.process.ColorProcessor) CoordinateTransformMesh(mpicbg.models.CoordinateTransformMesh) AffineModel2D(mpicbg.trakem2.transform.AffineModel2D) AffineTransform(java.awt.geom.AffineTransform) CoordinateTransform(mpicbg.trakem2.transform.CoordinateTransform)

Example 10 with AffineModel2D

use of mpicbg.trakem2.transform.AffineModel2D 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;
    }
}
Also used : TransformMeshMapping(mpicbg.trakem2.transform.TransformMeshMapping) CoordinateTransformList(mpicbg.trakem2.transform.CoordinateTransformList) Rectangle(java.awt.Rectangle) ShapeRoi(ij.gui.ShapeRoi) Roi(ij.gui.Roi) ImagePlus(ij.ImagePlus) NoninvertibleTransformException(java.awt.geom.NoninvertibleTransformException) ImageProcessor(ij.process.ImageProcessor) Area(java.awt.geom.Area) AffineModel2D(mpicbg.trakem2.transform.AffineModel2D) Worker(ini.trakem2.utils.Worker) CoordinateTransform(mpicbg.trakem2.transform.CoordinateTransform) TransformMesh(mpicbg.trakem2.transform.TransformMesh) CoordinateTransformMesh(mpicbg.models.CoordinateTransformMesh)

Aggregations

AffineTransform (java.awt.geom.AffineTransform)14 Rectangle (java.awt.Rectangle)13 Patch (ini.trakem2.display.Patch)11 AffineModel2D (mpicbg.models.AffineModel2D)11 ArrayList (java.util.ArrayList)10 AbstractAffineModel2D (mpicbg.models.AbstractAffineModel2D)9 NotEnoughDataPointsException (mpicbg.models.NotEnoughDataPointsException)9 Point (mpicbg.models.Point)9 PointMatch (mpicbg.models.PointMatch)9 SimilarityModel2D (mpicbg.models.SimilarityModel2D)9 CoordinateTransform (mpicbg.trakem2.transform.CoordinateTransform)9 CoordinateTransformList (mpicbg.trakem2.transform.CoordinateTransformList)8 Layer (ini.trakem2.display.Layer)7 CoordinateTransformMesh (mpicbg.models.CoordinateTransformMesh)7 ByteProcessor (ij.process.ByteProcessor)6 ImageProcessor (ij.process.ImageProcessor)6 AffineModel2D (mpicbg.trakem2.transform.AffineModel2D)6 RigidModel2D (mpicbg.trakem2.transform.RigidModel2D)6 TranslationModel2D (mpicbg.trakem2.transform.TranslationModel2D)6 SIFT (mpicbg.ij.SIFT)5