Search in sources :

Example 91 with Patch

use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.

the class StitchingTEM method makeStripe.

// static public ImageProcessor makeStripe(final Patch p, final double scale, final boolean ignore_patch_transform) {
// return makeStripe(p, null, scale, ignore_patch_transform);
// }
/**
 * @return FloatProcessor.
 * @param ignore_patch_transform will prevent resizing of the ImageProcessor in the event of the Patch having a transform different than identity.
 */
// TODO 2: there is a combination of options that ends up resulting in the actual ImageProcessor of the Patch being returned as is, which is DANGEROUS because it can potentially result in changes in the data.
public static ImageProcessor makeStripe(final Patch p, final Roi roi, final double scale, final boolean ignore_patch_transform) {
    ImagePlus imp = null;
    ImageProcessor ip = null;
    final Loader loader = p.getProject().getLoader();
    // check if using mipmaps and if there is a file for it. If there isn't, most likely this method is being called in an import sequence as grid procedure.
    if (loader.isMipMapsRegenerationEnabled() && loader.checkMipMapFileExists(p, scale)) {
        // Read the transform image from the patch (this way we avoid the JPEG artifacts)
        final Patch.PatchImage pai = p.createTransformedImage();
        pai.target.setMinAndMax(p.getMin(), p.getMax());
        // p.getProject().getLoader().fetchImage(p, scale);
        Image image = pai.target.createImage();
        // Utils.log2("patch w,h " + p.getWidth() + ", " + p.getHeight() + " fetched image w,h: " + image.getWidth(null) + ", " + image.getHeight(null));
        if (Math.abs(p.getWidth() * scale - image.getWidth(null)) > 0.001 || Math.abs(p.getHeight() * scale - image.getHeight(null)) > 0.001) {
            // slow but good quality. Makes an RGB image, but it doesn't matter.
            image = image.getScaledInstance((int) (p.getWidth() * scale), (int) (p.getHeight() * scale), Image.SCALE_AREA_AVERAGING);
        // Utils.log2("   resizing, now image w,h: " + image.getWidth(null) + ", " + image.getHeight(null));
        }
        try {
            imp = new ImagePlus("s", image);
            ip = imp.getProcessor();
        // imp.show();
        } catch (final Exception e) {
            IJError.print(e);
        }
        // cut
        if (null != roi) {
            // scale ROI!
            Rectangle rb = roi.getBounds();
            final Roi roi2 = new Roi((int) (rb.x * scale), (int) (rb.y * scale), (int) (rb.width * scale), (int) (rb.height * scale));
            rb = roi2.getBounds();
            if (ip.getWidth() != rb.width || ip.getHeight() != rb.height) {
                ip.setRoi(roi2);
                ip = ip.crop();
            }
        }
    // Utils.log2("scale: " + scale + "  ip w,h: " + ip.getWidth() + ", " + ip.getHeight());
    } else {
        final Patch.PatchImage pai = p.createTransformedImage();
        pai.target.setMinAndMax(p.getMin(), p.getMax());
        ip = pai.target;
        imp = new ImagePlus("", ip);
        // compare and adjust
        if (!ignore_patch_transform && p.getAffineTransform().getType() != AffineTransform.TYPE_TRANSLATION) {
            // if it's not only a translation:
            final Rectangle b = p.getBoundingBox();
            ip = ip.resize(b.width, b.height);
        // Utils.log2("resizing stripe for patch: " + p);
        // the above is only meant to correct for improperly acquired images at the microscope, the scale only.
        }
        // cut
        if (null != roi) {
            final Rectangle rb = roi.getBounds();
            if (ip.getWidth() != rb.width || ip.getHeight() != rb.height) {
                ip.setRoi(roi);
                ip = ip.crop();
            }
        }
        // scale
        if (scale < 1) {
            // floats have 4 bytes, plus some java peripherals correction factor
            p.getProject().getLoader().releaseToFit((long) (ip.getWidth() * ip.getHeight() * 4 * 1.2));
            ip = ip.convertToFloat();
            // scaling with area averaging is the same as a gaussian of sigma 0.5/scale and then resize with nearest neightbor So this line does the gaussian, and line below does the neares-neighbor scaling
            ip.setPixels(ImageFilter.computeGaussianFastMirror(new FloatArray2D((float[]) ip.getPixels(), ip.getWidth(), ip.getHeight()), Math.sqrt(0.25 / scale / scale - 0.25)).data);
            // scale maintaining aspect ratio
            ip = ip.resize((int) (ip.getWidth() * scale));
        }
    }
    // return a FloatProcessor
    if (imp.getType() != ImagePlus.GRAY32)
        return ip.convertToFloat();
    return ip;
}
Also used : ImageProcessor(ij.process.ImageProcessor) FloatArray2D(mpi.fruitfly.math.datastructures.FloatArray2D) Rectangle(java.awt.Rectangle) Loader(ini.trakem2.persistence.Loader) Image(java.awt.Image) ImagePlus(ij.ImagePlus) Patch(ini.trakem2.display.Patch) Roi(ij.gui.Roi)

Example 92 with Patch

use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.

the class StitchingTEM method montageWithPhaseCorrelation.

/**
 * @param layers
 * @param worker Optional, the {@link Worker} running this task.
 */
public static void montageWithPhaseCorrelation(final List<Layer> layers, final Worker worker) {
    final PhaseCorrelationParam param = new PhaseCorrelationParam();
    final Collection<Displayable> col = layers.get(0).getDisplayables(Patch.class);
    if (!param.setup(col.size() > 0 ? (Patch) col.iterator().next() : null)) {
        return;
    }
    final int i = 1;
    for (final Layer la : layers) {
        if (Thread.currentThread().isInterrupted() || (null != worker && worker.hasQuitted()))
            return;
        if (null != worker)
            worker.setTaskName("Montage layer " + i + "/" + layers.size());
        final Collection<Patch> patches = (Collection<Patch>) (Collection) la.getDisplayables(Patch.class);
        AlignTask.transformPatchesAndVectorData(patches, new Runnable() {

            @Override
            public void run() {
                montageWithPhaseCorrelation(patches, param);
            }
        });
    }
}
Also used : Displayable(ini.trakem2.display.Displayable) Collection(java.util.Collection) Layer(ini.trakem2.display.Layer) Patch(ini.trakem2.display.Patch) Point(mpicbg.models.Point)

Example 93 with Patch

use of ini.trakem2.display.Patch 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 94 with Patch

use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.

the class TestGraphicsSource method asPaintable.

/**
 * Replaces all Patch instances by a smiley face.
 */
public List<? extends Paintable> asPaintable(final List<? extends Paintable> ds) {
    final ArrayList<Paintable> a = new ArrayList<Paintable>();
    for (final Paintable p : ds) {
        if (p instanceof Patch) {
            final Paintable pa = new Paintable() {

                public void paint(Graphics2D g, Rectangle srcRect, double magnification, boolean active, int channels, Layer active_layer, List<Layer> layers) {
                    Patch patch = (Patch) p;
                    Rectangle r = patch.getBoundingBox();
                    g.setColor(Color.magenta);
                    g.fillRect(r.x, r.y, r.width, r.height);
                    g.setColor(Color.green);
                    g.fillOval(r.x + r.width / 3, r.y + r.height / 3, r.width / 10, r.width / 10);
                    g.fillOval(r.x + 2 * (r.width / 3), r.y + r.height / 3, r.width / 10, r.width / 10);
                    g.fillOval(r.x + r.width / 3, r.y + 2 * (r.height / 3), r.width / 3, r.height / 6);
                }

                public void prePaint(Graphics2D g, Rectangle srcRect, double magnification, boolean active, int channels, Layer active_layer, List<Layer> layers) {
                    this.paint(g, srcRect, magnification, active, channels, active_layer, layers);
                }
            };
            a.add(pa);
        } else {
            a.add(p);
        }
    }
    return a;
}
Also used : Paintable(ini.trakem2.display.Paintable) ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) List(java.util.List) ArrayList(java.util.ArrayList) Patch(ini.trakem2.display.Patch) Layer(ini.trakem2.display.Layer) Graphics2D(java.awt.Graphics2D)

Example 95 with Patch

use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.

the class DistortionCorrectionTask method correctDistortionFromSelection.

public static final Bureaucrat correctDistortionFromSelection(final Selection selection) {
    final List<Patch> patches = new ArrayList<Patch>();
    for (final Displayable d : Display.getFront().getSelection().getSelected()) if (d instanceof Patch)
        patches.add((Patch) d);
    if (patches.size() < 2) {
        Utils.log("No images in the selection.");
        return null;
    }
    final Worker worker = new Worker("Lens correction") {

        @Override
        public final void run() {
            try {
                startedWorking();
                if (!correctDistortionFromSelectionParam.setup(selection))
                    return;
                DistortionCorrectionTask.run(correctDistortionFromSelectionParam.clone(), patches, selection.getActive(), selection.getLayer(), null);
                Display.repaint();
            } catch (final Exception e) {
                IJError.print(e);
            } finally {
                finishedWorking();
            }
        }
    };
    return Bureaucrat.createAndStart(worker, selection.getProject());
}
Also used : Displayable(ini.trakem2.display.Displayable) ArrayList(java.util.ArrayList) Worker(ini.trakem2.utils.Worker) Patch(ini.trakem2.display.Patch)

Aggregations

Patch (ini.trakem2.display.Patch)69 ArrayList (java.util.ArrayList)46 Layer (ini.trakem2.display.Layer)39 ImagePlus (ij.ImagePlus)34 Rectangle (java.awt.Rectangle)28 Point (mpicbg.models.Point)26 HashSet (java.util.HashSet)24 Displayable (ini.trakem2.display.Displayable)23 AffineTransform (java.awt.geom.AffineTransform)20 Loader (ini.trakem2.persistence.Loader)15 File (java.io.File)15 Future (java.util.concurrent.Future)15 NotEnoughDataPointsException (mpicbg.models.NotEnoughDataPointsException)15 PointMatch (mpicbg.models.PointMatch)14 Worker (ini.trakem2.utils.Worker)13 HashMap (java.util.HashMap)13 ExecutorService (java.util.concurrent.ExecutorService)12 ImageProcessor (ij.process.ImageProcessor)11 AffineModel2D (mpicbg.models.AffineModel2D)11 GenericDialog (ij.gui.GenericDialog)10