Search in sources :

Example 21 with Layer

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

the class Align method alignLayer.

/**
 * Align all {@link Patch patches} in a Layer.
 *
 * @param layer
 */
public static final void alignLayer(final Layer layer, final int numThreads) {
    if (!paramOptimize.setup("Align patches in layer"))
        return;
    final List<Displayable> displayables = layer.getDisplayables(Patch.class);
    final List<Patch> patches = new ArrayList<Patch>();
    for (final Displayable d : displayables) patches.add((Patch) d);
    final List<AbstractAffineTile2D<?>> tiles = new ArrayList<AbstractAffineTile2D<?>>();
    final List<AbstractAffineTile2D<?>> fixedTiles = new ArrayList<AbstractAffineTile2D<?>>();
    tilesFromPatches(paramOptimize, patches, null, tiles, fixedTiles);
    alignTiles(paramOptimize, tiles, fixedTiles, numThreads);
    for (final AbstractAffineTile2D<?> t : tiles) t.getPatch().setAffineTransform(t.getModel().createAffine());
}
Also used : Displayable(ini.trakem2.display.Displayable) ArrayList(java.util.ArrayList) Patch(ini.trakem2.display.Patch)

Example 22 with Layer

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

the class AlignLayersTask method alignLayersNonLinearlyJob.

public static final void alignLayersNonLinearlyJob(final LayerSet layerSet, final int first, final int last, final boolean propagateTransform, final Rectangle fov, final Filter<Patch> filter) {
    // will reverse order if necessary
    final List<Layer> layerRange = layerSet.getLayers(first, last);
    final Align.Param p = Align.param.clone();
    // Remove all empty layers
    for (final Iterator<Layer> it = layerRange.iterator(); it.hasNext(); ) {
        if (!it.next().contains(Patch.class, true)) {
            it.remove();
        }
    }
    if (0 == layerRange.size()) {
        Utils.log("No layers in range show any images!");
        return;
    }
    /* do not work if there is only one layer selected */
    if (layerRange.size() < 2)
        return;
    final List<Patch> all = new ArrayList<Patch>();
    for (final Layer la : layerRange) {
        for (final Patch patch : la.getAll(Patch.class)) {
            if (null != filter && !filter.accept(patch))
                continue;
            all.add(patch);
        }
    }
    AlignTask.transformPatchesAndVectorData(all, new Runnable() {

        @Override
        public void run() {
            // ///
            final Loader loader = layerSet.getProject().getLoader();
            // Not concurrent safe! So two copies, one per layer and Thread:
            final SIFT ijSIFT1 = new SIFT(new FloatArray2DSIFT(p.sift));
            final SIFT ijSIFT2 = new SIFT(new FloatArray2DSIFT(p.sift));
            final Collection<Feature> features1 = new ArrayList<Feature>();
            final Collection<Feature> features2 = new ArrayList<Feature>();
            final List<PointMatch> candidates = new ArrayList<PointMatch>();
            final List<PointMatch> inliers = new ArrayList<PointMatch>();
            final int n_proc = Runtime.getRuntime().availableProcessors() > 1 ? 2 : 1;
            final ExecutorService exec = Utils.newFixedThreadPool(n_proc, "alignLayersNonLinearly");
            List<Patch> previousPatches = null;
            int s = 0;
            for (int i = 1; i < layerRange.size(); ++i) {
                if (Thread.currentThread().isInterrupted())
                    break;
                final Layer layer1 = layerRange.get(i - 1);
                final Layer layer2 = layerRange.get(i);
                final long t0 = System.currentTimeMillis();
                features1.clear();
                features2.clear();
                final Rectangle box1 = null == fov ? layer1.getMinimalBoundingBox(Patch.class, true) : fov;
                final Rectangle box2 = null == fov ? layer2.getMinimalBoundingBox(Patch.class, true) : fov;
                /* calculate the common scale factor for both flat images */
                final double scale = Math.min(1.0f, (double) p.sift.maxOctaveSize / (double) Math.max(box1.width, Math.max(box1.height, Math.max(box2.width, box2.height))));
                final List<Patch> patches1;
                if (null == previousPatches) {
                    patches1 = layer1.getAll(Patch.class);
                    if (null != filter) {
                        for (final Iterator<Patch> it = patches1.iterator(); it.hasNext(); ) {
                            if (!filter.accept(it.next()))
                                it.remove();
                        }
                    }
                } else {
                    patches1 = previousPatches;
                }
                final List<Patch> patches2 = layer2.getAll(Patch.class);
                if (null != filter) {
                    for (final Iterator<Patch> it = patches2.iterator(); it.hasNext(); ) {
                        if (!filter.accept(it.next()))
                            it.remove();
                    }
                }
                final Future<ImageProcessor> fu1 = exec.submit(new Callable<ImageProcessor>() {

                    @Override
                    public ImageProcessor call() {
                        final ImageProcessor ip1 = loader.getFlatImage(layer1, box1, scale, 0xffffffff, ImagePlus.GRAY8, Patch.class, patches1, true).getProcessor();
                        ijSIFT1.extractFeatures(ip1, features1);
                        Utils.log(features1.size() + " features extracted in layer \"" + layer1.getTitle() + "\" (took " + (System.currentTimeMillis() - t0) + " ms).");
                        return ip1;
                    }
                });
                final Future<ImageProcessor> fu2 = exec.submit(new Callable<ImageProcessor>() {

                    @Override
                    public ImageProcessor call() {
                        final ImageProcessor ip2 = loader.getFlatImage(layer2, box2, scale, 0xffffffff, ImagePlus.GRAY8, Patch.class, patches2, true).getProcessor();
                        ijSIFT2.extractFeatures(ip2, features2);
                        Utils.log(features2.size() + " features extracted in layer \"" + layer2.getTitle() + "\" (took " + (System.currentTimeMillis() - t0) + " ms).");
                        return ip2;
                    }
                });
                final ImageProcessor ip1, ip2;
                try {
                    ip1 = fu1.get();
                    ip2 = fu2.get();
                } catch (final Exception e) {
                    IJError.print(e);
                    return;
                }
                if (features1.size() > 0 && features2.size() > 0) {
                    final long t1 = System.currentTimeMillis();
                    candidates.clear();
                    FeatureTransform.matchFeatures(features2, features1, candidates, p.rod);
                    final AbstractAffineModel2D<?> model;
                    switch(p.expectedModelIndex) {
                        case 0:
                            model = new TranslationModel2D();
                            break;
                        case 1:
                            model = new RigidModel2D();
                            break;
                        case 2:
                            model = new SimilarityModel2D();
                            break;
                        case 3:
                            model = new AffineModel2D();
                            break;
                        default:
                            return;
                    }
                    boolean modelFound;
                    boolean again = false;
                    try {
                        do {
                            again = false;
                            modelFound = model.filterRansac(candidates, inliers, 1000, p.maxEpsilon, p.minInlierRatio, p.minNumInliers, 3);
                            if (modelFound && p.rejectIdentity) {
                                final ArrayList<Point> points = new ArrayList<Point>();
                                PointMatch.sourcePoints(inliers, points);
                                if (Transforms.isIdentity(model, points, p.identityTolerance)) {
                                    IJ.log("Identity transform for " + inliers.size() + " matches rejected.");
                                    candidates.removeAll(inliers);
                                    inliers.clear();
                                    again = true;
                                }
                            }
                        } while (again);
                    } catch (final NotEnoughDataPointsException e) {
                        modelFound = false;
                    }
                    if (modelFound) {
                        IJ.log("Model found for layer \"" + layer2.getTitle() + "\" and its predecessor:\n  correspondences  " + inliers.size() + " of " + candidates.size() + "\n  average residual error  " + (model.getCost() / scale) + " px\n  took " + (System.currentTimeMillis() - t1) + " ms");
                        final ImagePlus imp1 = new ImagePlus("target", ip1);
                        final ImagePlus imp2 = new ImagePlus("source", ip2);
                        final List<Point> sourcePoints = new ArrayList<Point>();
                        final List<Point> targetPoints = new ArrayList<Point>();
                        PointMatch.sourcePoints(inliers, sourcePoints);
                        PointMatch.targetPoints(inliers, targetPoints);
                        imp2.setRoi(Util.pointsToPointRoi(sourcePoints));
                        imp1.setRoi(Util.pointsToPointRoi(targetPoints));
                        final ImageProcessor mask1 = ip1.duplicate();
                        mask1.threshold(1);
                        final ImageProcessor mask2 = ip2.duplicate();
                        mask2.threshold(1);
                        final Transformation warp = bUnwarpJ_.computeTransformationBatch(imp2, imp1, mask2, mask1, elasticParam);
                        final CubicBSplineTransform transf = new CubicBSplineTransform();
                        transf.set(warp.getIntervals(), warp.getDirectDeformationCoefficientsX(), warp.getDirectDeformationCoefficientsY(), imp2.getWidth(), imp2.getHeight());
                        final ArrayList<Future<?>> fus = new ArrayList<Future<?>>();
                        // Transform desired patches only
                        for (final Patch patch : patches2) {
                            try {
                                final Rectangle pbox = patch.getCoordinateTransformBoundingBox();
                                final AffineTransform at = patch.getAffineTransform();
                                final AffineTransform pat = new AffineTransform();
                                pat.scale(scale, scale);
                                pat.translate(-box2.x, -box2.y);
                                pat.concatenate(at);
                                pat.translate(-pbox.x, -pbox.y);
                                final mpicbg.trakem2.transform.AffineModel2D toWorld = new mpicbg.trakem2.transform.AffineModel2D();
                                toWorld.set(pat);
                                final CoordinateTransformList<CoordinateTransform> ctl = new CoordinateTransformList<CoordinateTransform>();
                                // move the patch into the global space where bUnwarpJ calculated the transformation
                                ctl.add(toWorld);
                                // Apply non-linear transformation
                                ctl.add(transf);
                                // move it back
                                ctl.add(toWorld.createInverse());
                                patch.appendCoordinateTransform(ctl);
                                fus.add(patch.updateMipMaps());
                                // Compensate for offset between boxes
                                final AffineTransform offset = new AffineTransform();
                                offset.translate(box1.x - box2.x, box1.y - box2.y);
                                offset.concatenate(at);
                                patch.setAffineTransform(offset);
                            } catch (final Exception e) {
                                e.printStackTrace();
                            }
                        }
                        // await regeneration of all mipmaps
                        Utils.wait(fus);
                        Display.repaint(layer2);
                    } else
                        IJ.log("No model found for layer \"" + layer2.getTitle() + "\" and its predecessor:\n  correspondence candidates  " + candidates.size() + "\n  took " + (System.currentTimeMillis() - s) + " ms");
                }
                IJ.showProgress(++s, layerRange.size());
                // for next iteration
                previousPatches = patches2;
            }
            exec.shutdown();
            if (propagateTransform)
                Utils.log("Propagation not implemented yet for non-linear layer alignment.");
        /* // CANNOT be done (at least not trivially:
		 * //an appropriate "scale" cannot be computed, and the box2 is part of the spline computation.
		if ( propagateTransform && null != lastTransform )
		{
			for (final Layer la : l.getParent().getLayers(last > first ? last +1 : first -1, last > first ? l.getParent().size() -1 : 0)) {
				// Transform visible patches only
				final Rectangle box2 = la.getMinimalBoundingBox( Patch.class, true );
				for ( final Displayable disp : la.getDisplayables( Patch.class, true ) )
				{
					// ...
				}
			}
		}
		*/
        }
    });
// end of transformPatchesAndVectorData
}
Also used : NotEnoughDataPointsException(mpicbg.models.NotEnoughDataPointsException) SIFT(mpicbg.ij.SIFT) FloatArray2DSIFT(mpicbg.imagefeatures.FloatArray2DSIFT) Transformation(bunwarpj.Transformation) CoordinateTransformList(mpicbg.trakem2.transform.CoordinateTransformList) ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) Loader(ini.trakem2.persistence.Loader) Feature(mpicbg.imagefeatures.Feature) Callable(java.util.concurrent.Callable) ImageProcessor(ij.process.ImageProcessor) RigidModel2D(mpicbg.trakem2.transform.RigidModel2D) Iterator(java.util.Iterator) AbstractAffineModel2D(mpicbg.models.AbstractAffineModel2D) AffineModel2D(mpicbg.models.AffineModel2D) CoordinateTransformList(mpicbg.trakem2.transform.CoordinateTransformList) ArrayList(java.util.ArrayList) List(java.util.List) SimilarityModel2D(mpicbg.models.SimilarityModel2D) Point(mpicbg.models.Point) AbstractAffineModel2D(mpicbg.models.AbstractAffineModel2D) Layer(ini.trakem2.display.Layer) ImagePlus(ij.ImagePlus) NotEnoughDataPointsException(mpicbg.models.NotEnoughDataPointsException) IllDefinedDataPointsException(mpicbg.models.IllDefinedDataPointsException) FloatArray2DSIFT(mpicbg.imagefeatures.FloatArray2DSIFT) PointMatch(mpicbg.models.PointMatch) ExecutorService(java.util.concurrent.ExecutorService) Collection(java.util.Collection) Future(java.util.concurrent.Future) AffineTransform(java.awt.geom.AffineTransform) TranslationModel2D(mpicbg.trakem2.transform.TranslationModel2D) CubicBSplineTransform(bunwarpj.trakem2.transform.CubicBSplineTransform) Patch(ini.trakem2.display.Patch) CoordinateTransform(mpicbg.trakem2.transform.CoordinateTransform)

Example 23 with Layer

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

the class AlignLayersTask method alignLayers.

public static final void alignLayers(final Layer l, final Rectangle fov) throws Exception {
    final List<Layer> layers = l.getParent().getLayers();
    final String[] layerTitles = new String[layers.size()];
    final String[] noneAndLayerTitles = new String[layers.size() + 1];
    noneAndLayerTitles[0] = "*None*";
    for (int i = 0; i < layers.size(); ++i) {
        layerTitles[i] = l.getProject().findLayerThing(layers.get(i)).toString();
        noneAndLayerTitles[i + 1] = layerTitles[i];
    }
    // Param p = Align.param;
    // Align.param.sift.maxOctaveSize = 1024;
    final GenericDialog gd = new GenericDialog("Align Layers");
    gd.addChoice("mode :", modeStrings, modeStrings[LINEAR]);
    gd.addMessage("Layer Range:");
    final int sel = l.getParent().indexOf(l);
    gd.addChoice("first :", layerTitles, layerTitles[sel]);
    gd.addChoice("reference :", noneAndLayerTitles, layerTitles[sel]);
    gd.addChoice("last :", layerTitles, layerTitles[sel]);
    gd.addStringField("Use only images whose title matches:", "", 30);
    gd.addCheckbox("Use visible images only", true);
    gd.addCheckbox("propagate transform to first layer", propagateTransformBefore);
    gd.addCheckbox("propagate transform to last layer", propagateTransformAfter);
    final Vector<?> v = gd.getChoices();
    final Choice cstart = (Choice) v.get(v.size() - 3);
    final Choice cref = (Choice) v.get(v.size() - 2);
    final Choice cend = (Choice) v.get(v.size() - 1);
    final ItemListener startEndListener = new ItemListener() {

        @Override
        public void itemStateChanged(final ItemEvent ie) {
            final int startIndex = cstart.getSelectedIndex();
            final int endIndex = cend.getSelectedIndex();
            final int refIndex = cref.getSelectedIndex();
            final int min = Math.min(startIndex, endIndex);
            final int max = Math.max(startIndex, endIndex);
            if (cref.getSelectedIndex() > 0) {
                cref.select(Math.min(max + 1, Math.max(min + 1, refIndex)));
            }
        }
    };
    cstart.addItemListener(startEndListener);
    cend.addItemListener(startEndListener);
    cref.addItemListener(new ItemListener() {

        @Override
        public void itemStateChanged(final ItemEvent ie) {
            final int startIndex = cstart.getSelectedIndex();
            final int endIndex = cend.getSelectedIndex();
            final int refIndex = cref.getSelectedIndex() - 1;
            final int min = Math.min(startIndex, endIndex);
            final int max = Math.max(startIndex, endIndex);
            if (refIndex >= 0) {
                if (refIndex < min) {
                    if (startIndex <= endIndex)
                        cstart.select(refIndex);
                    else
                        cend.select(refIndex);
                } else if (refIndex > max) {
                    if (startIndex <= endIndex)
                        cend.select(refIndex);
                    else
                        cstart.select(refIndex);
                }
            }
        }
    });
    gd.showDialog();
    if (gd.wasCanceled())
        return;
    mode = gd.getNextChoiceIndex();
    final int first = gd.getNextChoiceIndex();
    final int ref = gd.getNextChoiceIndex() - 1;
    final int last = gd.getNextChoiceIndex();
    final String toMatch1 = gd.getNextString().trim();
    final String toMatch2 = 0 == toMatch1.length() ? null : ".*" + toMatch1 + ".*";
    final boolean visibleOnly = gd.getNextBoolean();
    propagateTransformBefore = gd.getNextBoolean();
    propagateTransformAfter = gd.getNextBoolean();
    final Filter<Patch> filter = new Filter<Patch>() {

        @Override
        public final boolean accept(final Patch patch) {
            if (visibleOnly && !patch.isVisible())
                return false;
            if (null != toMatch2 && !patch.getTitle().matches(toMatch2))
                return false;
            return true;
        }
    };
    if (mode == ELASTIC)
        new ElasticLayerAlignment().exec(l.getParent(), first, last, ref, propagateTransformBefore, propagateTransformAfter, fov, filter);
    else if (mode == LINEAR)
        new RegularizedAffineLayerAlignment().exec(l.getParent(), first, last, ref, propagateTransformBefore, propagateTransformAfter, fov, filter);
    else {
        final GenericDialog gd2 = new GenericDialog("Align Layers");
        Align.param.addFields(gd2);
        gd2.showDialog();
        if (gd2.wasCanceled())
            return;
        Align.param.readFields(gd2);
        if (mode == BUNWARPJ && !elasticParam.showDialog())
            return;
        // From ref to first:
        if (ref - first > 0) {
            if (mode == BUNWARPJ)
                alignLayersNonLinearlyJob(l.getParent(), ref, first, propagateTransformBefore, fov, filter);
            else
                alignLayersLinearlyJob(l.getParent(), ref, first, propagateTransformBefore, fov, filter);
        }
        // From ref to last:
        if (last - ref > 0) {
            if (mode == BUNWARPJ)
                alignLayersNonLinearlyJob(l.getParent(), ref, last, propagateTransformAfter, fov, filter);
            else
                alignLayersLinearlyJob(l.getParent(), ref, last, propagateTransformAfter, fov, filter);
        }
    }
}
Also used : ItemEvent(java.awt.event.ItemEvent) Choice(java.awt.Choice) Layer(ini.trakem2.display.Layer) Point(mpicbg.models.Point) Filter(ini.trakem2.utils.Filter) GenericDialog(ij.gui.GenericDialog) ItemListener(java.awt.event.ItemListener) Patch(ini.trakem2.display.Patch)

Example 24 with Layer

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

the class ExportUnsignedShort method exportTiles.

/**
 * Create constant size tiles that carpet the areas of the {@code layer} where there are images;
 * these tiles are returned in a lazy sequence of {@link Callable} objects that create a tripled
 * consisting of the {@link ShortProcessor} and the X and Y pixel coordinates of that tile.
 *
 * @param layer The layer to export images for
 * @param tileWidth The width of the tiles to export
 * @param tileHeight
 * @return A lazy sequence of {@link Callable} instances, each holding a {@link Triple} that specifies the ShortProcessor,
 * the X and the Y (both in world pixel uncalibrated coordinates).
 */
public static final Iterable<Callable<ExportedTile>> exportTiles(final Layer layer, final int tileWidth, final int tileHeight, final boolean visible_only) {
    final ArrayList<Displayable> patches = layer.getDisplayables(Patch.class, visible_only);
    // If the Layer lacks images, return an empty sequence.
    if (patches.isEmpty()) {
        return Collections.emptyList();
    }
    /* calculate intensity transfer */
    final ArrayList<PatchIntensityRange> patchIntensityRanges = new ArrayList<PatchIntensityRange>();
    double min_ = Double.MAX_VALUE;
    double max_ = -Double.MAX_VALUE;
    for (final Displayable d : patches) {
        final Patch patch = (Patch) d;
        final PatchIntensityRange pir = new PatchIntensityRange(patch);
        if (pir.min < min_)
            min_ = pir.min;
        if (pir.max > max_)
            max_ = pir.max;
        patchIntensityRanges.add(pir);
    }
    final double min = min_;
    final double max = max_;
    /* Create lazy sequence that creates Callable instances. */
    final Rectangle box = layer.getMinimalBoundingBox(Patch.class, visible_only).intersection(layer.getParent().get2DBounds());
    final int nCols = (int) Math.ceil(box.width / (double) tileWidth);
    final int nRows = (int) Math.ceil(box.height / (double) tileHeight);
    final double minI = -min * 65535.0 / (max - min);
    final double maxI = (1.0 - min) * 65535.0 / (max - min);
    return new Iterable<Callable<ExportedTile>>() {

        @Override
        public Iterator<Callable<ExportedTile>> iterator() {
            return new Iterator<Callable<ExportedTile>>() {

                // Internal state
                private int row = 0, col = 0, x0 = box.x, y0 = box.y;

                private final ArrayList<PatchIntensityRange> ps = new ArrayList<PatchIntensityRange>();

                {
                    // Constructor body. Prepare to be able to answer "hasNext()"
                    findNext();
                }

                private final void findNext() {
                    // Iterate until finding a tile that intersects one or more patches
                    ps.clear();
                    while (true) {
                        if (nRows == row) {
                            // End of domain
                            break;
                        }
                        x0 = box.x + col * tileWidth;
                        y0 = box.y + row * tileHeight;
                        final Rectangle tileBounds = new Rectangle(x0, y0, tileWidth, tileHeight);
                        for (final PatchIntensityRange pir : patchIntensityRanges) {
                            if (pir.patch.getBoundingBox().intersects(tileBounds)) {
                                ps.add(pir);
                            }
                        }
                        // Prepare next iteration
                        col += 1;
                        if (nCols == col) {
                            col = 0;
                            row += 1;
                        }
                        if (ps.size() > 0) {
                            // Ready for next iteration
                            break;
                        }
                    }
                }

                @Override
                public boolean hasNext() {
                    return ps.size() > 0;
                }

                @Override
                public Callable<ExportedTile> next() {
                    // Capture state locally
                    final ArrayList<PatchIntensityRange> pirs = new ArrayList<PatchIntensityRange>(ps);
                    final int x = x0;
                    final int y = y0;
                    // Advance
                    findNext();
                    return new Callable<ExportedTile>() {

                        @Override
                        public ExportedTile call() throws Exception {
                            final ShortProcessor sp = new ShortProcessor(tileWidth, tileHeight);
                            sp.setMinAndMax(minI, maxI);
                            for (final PatchIntensityRange pir : pirs) {
                                map(new PatchTransform(pir), x, y, mapIntensities(pir, min, max), sp);
                            }
                            return new ExportedTile(sp, x, y, minI, maxI);
                        }
                    };
                }

                @Override
                public void remove() {
                    throw new UnsupportedOperationException();
                }
            };
        }
    };
}
Also used : Displayable(ini.trakem2.display.Displayable) ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) Callable(java.util.concurrent.Callable) ShortProcessor(ij.process.ShortProcessor) Iterator(java.util.Iterator) Patch(ini.trakem2.display.Patch)

Example 25 with Layer

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

the class ExportUnsignedShort method exportTEST.

public static final void exportTEST(final Layer layer, final int tileWidth, final int tileHeight) {
    /* calculate intensity transfer */
    final ArrayList<Displayable> patches = layer.getDisplayables(Patch.class);
    final ArrayList<PatchIntensityRange> patchIntensityRanges = new ArrayList<PatchIntensityRange>();
    double min = Double.MAX_VALUE;
    double max = -Double.MAX_VALUE;
    for (final Displayable d : patches) {
        final Patch patch = (Patch) d;
        final PatchIntensityRange pir = new PatchIntensityRange(patch);
        if (pir.min < min)
            min = pir.min;
        if (pir.max > max)
            max = pir.max;
        patchIntensityRanges.add(pir);
    }
    /* render tiles */
    /* TODO Do not render them into a stack but save them as files */
    final ImageStack stack = new ImageStack(tileWidth, tileHeight);
    ImagePlus imp = null;
    final double minI = -min * 65535.0 / (max - min);
    final double maxI = (1.0 - min) * 65535.0 / (max - min);
    // ij.IJ.log("min, max: " + min + ", " + max + ",    minI, maxI: " + minI + ", " + maxI);
    final int nc = (int) Math.ceil(layer.getLayerWidth() / tileWidth);
    final int nr = (int) Math.ceil(layer.getLayerHeight() / tileHeight);
    for (int r = 0; r < nr; ++r) {
        final int y0 = r * tileHeight;
        for (int c = 0; c < nc; ++c) {
            final int x0 = c * tileWidth;
            final Rectangle box = new Rectangle(x0, y0, tileWidth, tileHeight);
            final ShortProcessor sp = new ShortProcessor(tileWidth, tileHeight);
            sp.setMinAndMax(minI, maxI);
            for (final PatchIntensityRange pir : patchIntensityRanges) {
                if (pir.patch.getBoundingBox().intersects(box))
                    map(new PatchTransform(pir), x0, y0, mapIntensities(pir, min, max), sp);
            }
            stack.addSlice(r + ", " + c, sp);
            if (null == imp && stack.getSize() > 1) {
                imp = new ImagePlus("tiles", stack);
                imp.show();
            }
            if (null != imp) {
                imp.setSlice(stack.getSize());
                imp.updateAndDraw();
            }
        }
    }
    if (null == imp) {
        // single-slice, non-StackWindow
        new ImagePlus("tiles", stack).show();
    }
}
Also used : Displayable(ini.trakem2.display.Displayable) ImageStack(ij.ImageStack) ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) ImagePlus(ij.ImagePlus) ShortProcessor(ij.process.ShortProcessor) Patch(ini.trakem2.display.Patch)

Aggregations

Layer (ini.trakem2.display.Layer)61 ArrayList (java.util.ArrayList)52 Patch (ini.trakem2.display.Patch)43 Rectangle (java.awt.Rectangle)34 HashSet (java.util.HashSet)27 ImagePlus (ij.ImagePlus)26 Displayable (ini.trakem2.display.Displayable)25 AffineTransform (java.awt.geom.AffineTransform)23 GenericDialog (ij.gui.GenericDialog)22 Worker (ini.trakem2.utils.Worker)22 Point (mpicbg.models.Point)22 HashMap (java.util.HashMap)21 Point (java.awt.Point)19 Area (java.awt.geom.Area)19 NoninvertibleTransformException (java.awt.geom.NoninvertibleTransformException)18 File (java.io.File)16 Future (java.util.concurrent.Future)16 LayerSet (ini.trakem2.display.LayerSet)15 ExecutorService (java.util.concurrent.ExecutorService)14 Collection (java.util.Collection)13