Search in sources :

Example 11 with TransformMesh

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

the class Blending method setBlendingMask.

/**
 * Returns true if a new mask has been set to Patch p.
 */
private static boolean setBlendingMask(final Patch p, Set<Patch> overlapping, final Map<Patch, TransformMesh> meshes, final boolean respect_current_mask) {
    Utils.log2("Blending " + p);
    if (overlapping.contains(p)) {
        overlapping = new HashSet<Patch>(overlapping);
        overlapping.remove(p);
    }
    final AffineTransform at = p.getAffineTransform();
    final TransformMesh mesh = meshes.get(p);
    ByteProcessor mask = null;
    if (respect_current_mask) {
        mask = p.getAlphaMask();
    }
    if (null == mask) {
        mask = new ByteProcessor(p.getOWidth(), p.getOHeight());
        mask.setValue(255);
        mask.fill();
    }
    final byte[] pix = (byte[]) mask.getPixels();
    final Point2D.Double po = new Point2D.Double();
    final double[] fo = new double[2];
    final int p_o_width = p.getOWidth();
    final int p_o_height = p.getOHeight();
    int next = 0;
    // the self as well
    final double[] weights = new double[overlapping.size() + 1];
    int masked = 0;
    for (int y = 0; y < p_o_height; y++) {
        if (Thread.currentThread().isInterrupted())
            return false;
        for (int x = 0; x < p_o_width; x++) {
            // transform x,y to world coords
            if (null != mesh) {
                fo[0] = x;
                fo[1] = y;
                mesh.applyInPlace(fo);
                po.x = fo[0];
                po.y = fo[1];
            } else {
                po.x = x;
                po.y = y;
            }
            at.transform(po, po);
            fo[0] = po.x;
            fo[1] = po.y;
            // debug:
            if (0 == x && 0 == y) {
                Utils.log2("point 0,0 goes to " + fo[0] + ", " + fo[1]);
            }
            // check if it intersects any Patch
            next = 0;
            for (final Patch other : overlapping) {
                final double weight = intersects(fo, other, meshes.get(other));
                if (weight > 0)
                    weights[next++] = weight;
            }
            final int i = y * p_o_width + x;
            if (respect_current_mask) {
                // Don't compute if no overlap or if current mask value is zero
                if (next > 0 && pix[i] != 0) {
                    // the weight of Patch p, added last
                    weights[next++] = computeWeight(x, y, p_o_width, p_o_height);
                    double sum = 0;
                    for (int f = 0; f < next; f++) sum += weights[f];
                    pix[i] = (byte) ((int) (255 * (weights[next - 1] / sum) * ((pix[i] & 0xff) / 255.0f)));
                    masked++;
                }
            // else leave current value untouched
            } else if (next > 0) {
                // Overwritting current mask
                // the weight of Patch p, added last
                weights[next++] = computeWeight(x, y, p_o_width, p_o_height);
                double sum = 0;
                for (int f = 0; f < next; f++) sum += weights[f];
                pix[i] = (byte) ((int) (255 * (weights[next - 1] / sum)));
                masked++;
            }
        }
    }
    Utils.log2("Masked = " + masked + " for " + p);
    if (masked > 0) {
        p.setAlphaMask(mask);
        return true;
    }
    Utils.log("Nothing to blend in image " + p);
    return false;
}
Also used : ByteProcessor(ij.process.ByteProcessor) Point2D(java.awt.geom.Point2D) AffineTransform(java.awt.geom.AffineTransform) Patch(ini.trakem2.display.Patch) TransformMesh(mpicbg.trakem2.transform.TransformMesh)

Example 12 with TransformMesh

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

the class Render method render.

/**
 * Renders a patch, mapping its intensities [min, max] &rarr; [0, 1]
 *
 * @param patch the patch to be rendered
 * @param targetImage target pixels, specifies the target box
 * @param targetWeight target weight pixels, depending on alpha
 * @param x target box offset in world coordinates
 * @param y target box offset in world coordinates
 * @param scale target scale
 */
public static final void render(final Patch patch, final int coefficientsWidth, final int coefficientsHeight, final FloatProcessor targetImage, final FloatProcessor targetWeight, final ColorProcessor targetCoefficients, final double x, final double y, final double scale) {
    /* assemble coordinate transformations and add bounding box offset */
    final CoordinateTransformList<CoordinateTransform> ctl = new CoordinateTransformList<CoordinateTransform>();
    ctl.add(patch.getFullCoordinateTransform());
    final AffineModel2D affineScale = new AffineModel2D();
    affineScale.set(scale, 0, 0, scale, -x * scale, -y * scale);
    ctl.add(affineScale);
    /* estimate average scale and generate downsampled source */
    final int width = patch.getOWidth(), height = patch.getOHeight();
    final double s = sampleAverageScale(ctl, width, height, width / patch.getMeshResolution());
    final int mipmapLevel = bestMipmapLevel(s);
    final ImageProcessor ipMipmap = Downsampler.downsampleImageProcessor(patch.getImageProcessor(), mipmapLevel);
    /* create a target */
    final ImageProcessor tp = ipMipmap.createProcessor(targetImage.getWidth(), targetImage.getHeight());
    /* prepare and downsample alpha mask if there is one */
    final ByteProcessor bpMaskMipmap;
    final ByteProcessor bpMaskTarget;
    final ByteProcessor bpMask = patch.getAlphaMask();
    if (bpMask == null) {
        bpMaskMipmap = null;
        bpMaskTarget = null;
    } else {
        bpMaskMipmap = bpMask == null ? null : Downsampler.downsampleByteProcessor(bpMask, mipmapLevel);
        bpMaskTarget = new ByteProcessor(tp.getWidth(), tp.getHeight());
    }
    /* create coefficients map */
    final ColorProcessor cp = new ColorProcessor(ipMipmap.getWidth(), ipMipmap.getHeight());
    final int w = cp.getWidth();
    final int h = cp.getHeight();
    for (int yi = 0; yi < h; ++yi) {
        final int yc = yi * coefficientsHeight / h;
        final int ic = yc * coefficientsWidth;
        final int iyi = yi * w;
        for (int xi = 0; xi < w; ++xi) cp.set(iyi + xi, ic + (xi * coefficientsWidth / w) + 1);
    }
    /* attach mipmap transformation */
    final CoordinateTransformList<CoordinateTransform> ctlMipmap = new CoordinateTransformList<CoordinateTransform>();
    ctlMipmap.add(createScaleLevelTransform(mipmapLevel));
    ctlMipmap.add(ctl);
    /* create mesh */
    final CoordinateTransformMesh mesh = new CoordinateTransformMesh(ctlMipmap, patch.getMeshResolution(), ipMipmap.getWidth(), ipMipmap.getHeight());
    /* render */
    final ImageProcessorWithMasks source = new ImageProcessorWithMasks(ipMipmap, bpMaskMipmap, null);
    final ImageProcessorWithMasks target = new ImageProcessorWithMasks(tp, bpMaskTarget, null);
    final TransformMeshMappingWithMasks<TransformMesh> mapping = new TransformMeshMappingWithMasks<TransformMesh>(mesh);
    mapping.mapInterpolated(source, target, 1);
    final TransformMeshMapping<TransformMesh> coefficientsMapMapping = new TransformMeshMapping<TransformMesh>(mesh);
    coefficientsMapMapping.map(cp, targetCoefficients, 1);
    /* set alpha channel */
    final byte[] alphaPixels;
    if (bpMaskTarget != null)
        alphaPixels = (byte[]) bpMaskTarget.getPixels();
    else
        alphaPixels = (byte[]) target.outside.getPixels();
    /* convert */
    final double min = patch.getMin();
    final double max = patch.getMax();
    final double a = 1.0 / (max - min);
    final double b = 1.0 / 255.0;
    for (int i = 0; i < alphaPixels.length; ++i) targetImage.setf(i, (float) ((tp.getf(i) - min) * a));
    for (int i = 0; i < alphaPixels.length; ++i) targetWeight.setf(i, (float) ((alphaPixels[i] & 0xff) * b));
}
Also used : ByteProcessor(ij.process.ByteProcessor) TransformMeshMapping(mpicbg.ij.TransformMeshMapping) ImageProcessorWithMasks(mpicbg.trakem2.transform.TransformMeshMappingWithMasks.ImageProcessorWithMasks) CoordinateTransformList(mpicbg.models.CoordinateTransformList) Point(mpicbg.models.Point) ImageProcessor(ij.process.ImageProcessor) ColorProcessor(ij.process.ColorProcessor) CoordinateTransformMesh(mpicbg.models.CoordinateTransformMesh) AffineModel2D(mpicbg.models.AffineModel2D) TransformMeshMappingWithMasks(mpicbg.trakem2.transform.TransformMeshMappingWithMasks) CoordinateTransform(mpicbg.models.CoordinateTransform) TransformMesh(mpicbg.models.TransformMesh) CoordinateTransformMesh(mpicbg.models.CoordinateTransformMesh)

Aggregations

TransformMesh (mpicbg.trakem2.transform.TransformMesh)9 CoordinateTransformMesh (mpicbg.models.CoordinateTransformMesh)8 CoordinateTransform (mpicbg.trakem2.transform.CoordinateTransform)8 Rectangle (java.awt.Rectangle)6 ImageProcessor (ij.process.ImageProcessor)4 AffineTransform (java.awt.geom.AffineTransform)4 NoninvertibleTransformException (java.awt.geom.NoninvertibleTransformException)4 NoninvertibleModelException (mpicbg.models.NoninvertibleModelException)4 CoordinateTransformList (mpicbg.trakem2.transform.CoordinateTransformList)4 TransformMeshMapping (mpicbg.trakem2.transform.TransformMeshMapping)4 ByteProcessor (ij.process.ByteProcessor)3 Area (java.awt.geom.Area)3 AffineModel2D (mpicbg.trakem2.transform.AffineModel2D)3 ImagePlus (ij.ImagePlus)2 Roi (ij.gui.Roi)2 ShapeRoi (ij.gui.ShapeRoi)2 Patch (ini.trakem2.display.Patch)2 Point (mpicbg.models.Point)2 ImageProcessorWithMasks (mpicbg.trakem2.transform.TransformMeshMappingWithMasks.ImageProcessorWithMasks)2 ThresholdToSelection (ij.plugin.filter.ThresholdToSelection)1