Search in sources :

Example 16 with ImageProcessor

use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.

the class PSFCombiner method combineImages.

private void combineImages() {
    double nmPerPixel = getNmPerPixel();
    if (nmPerPixel <= 0)
        return;
    double nmPerSlice = getNmPerSlice();
    if (nmPerPixel <= 0)
        return;
    // Find the lowest start point
    int min = 0;
    for (PSF psf : input) {
        if (min > psf.start)
            min = psf.start;
    }
    // Shift all stacks and find the dimensions
    final int shift = -min;
    int max = 0, size = 0;
    int totalImages = 0;
    for (PSF psf : input) {
        psf.start += shift;
        totalImages += psf.psfSettings.nImages;
        if (max < psf.getEnd())
            max = psf.getEnd();
        if (size < psf.getSize())
            size = psf.getSize();
    }
    // Create a stack to hold all the images
    ImageStack stack = new ImageStack(size, size, max);
    for (int n = 1; n <= max; n++) stack.setPixels(new float[size * size], n);
    // Insert all the PSFs
    IJ.showStatus("Creating combined image ...");
    int imageNo = 0;
    double fraction = 1.0 / input.size();
    for (PSF psf : input) {
        double progress = imageNo * fraction;
        ImageStack psfStack = psf.psfStack;
        final int offsetXY = (psf.getSize() - size) / 2;
        final int offsetZ = psf.start;
        final int w = psf.getSize();
        final double weight = (1.0 * psf.psfSettings.nImages) / totalImages;
        final double increment = fraction / psfStack.getSize();
        for (int n = 1; n <= psfStack.getSize(); n++) {
            IJ.showProgress(progress += increment);
            // Get the data and adjust using the weight
            float[] psfData = ImageConverter.getData(psfStack.getProcessor(n));
            for (int i = 0; i < psfData.length; i++) psfData[i] *= weight;
            // Insert into the combined PSF
            ImageProcessor ip = stack.getProcessor(n + offsetZ);
            ip.copyBits(new FloatProcessor(w, w, psfData, null), offsetXY, offsetXY, Blitter.ADD);
        }
        imageNo++;
    }
    // IJ.showStatus("Normalising ...");
    // PSFCreator.normalise(stack, 1 + shift);
    IJ.showProgress(1);
    IJ.showStatus("");
    ImagePlus imp = Utils.display("Combined PSF", stack);
    imp.setSlice(1 + shift);
    imp.resetDisplayRange();
    imp.updateAndDraw();
    final double fwhm = getFWHM();
    imp.setProperty("Info", XmlUtils.toXML(new PSFSettings(imp.getSlice(), nmPerPixel, nmPerSlice, totalImages, fwhm)));
    Utils.log("%s : z-centre = %d, nm/Pixel = %s, nm/Slice = %s, %d images, FWHM = %s\n", imp.getTitle(), imp.getSlice(), Utils.rounded(nmPerPixel), Utils.rounded(nmPerSlice), totalImages, Utils.rounded(fwhm));
}
Also used : ImageProcessor(ij.process.ImageProcessor) ImageStack(ij.ImageStack) FloatProcessor(ij.process.FloatProcessor) ImagePlus(ij.ImagePlus) PSFSettings(gdsc.smlm.ij.settings.PSFSettings)

Example 17 with ImageProcessor

use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.

the class PSFCreator method addToPSF.

private boolean addToPSF(int maxz, final int magnification, ImageStack psf, final double[] centre, final float[][] spot, final Rectangle regionBounds, double progress, final double increment, final boolean centreEachSlice) {
    // Calculate insert point in enlargement
    final int z = (int) centre[2];
    int insertZ = maxz - z + 1;
    // Enlargement size
    final int w = regionBounds.width, h = regionBounds.height;
    final int dstWidth = w * magnification;
    final int dstHeight = h * magnification;
    // Multi-thread for speed
    if (threadPool == null)
        threadPool = Executors.newFixedThreadPool(Prefs.getThreads());
    List<Future<?>> futures = new LinkedList<Future<?>>();
    for (int i = 0; i < spot.length; i++) {
        //final int slice = i + 1;
        final ImageProcessor ip = psf.getProcessor(insertZ++);
        final float[] originalSpotData = spot[i];
        futures.add(threadPool.submit(new Runnable() {

            public void run() {
                if (Utils.isInterrupted())
                    return;
                incrementProgress(increment);
                double insertX, insertY;
                // Enlarge
                FloatProcessor fp = new FloatProcessor(w, h, originalSpotData, null);
                fp.setInterpolationMethod(interpolationMethod);
                fp = (FloatProcessor) fp.resize(dstWidth, dstHeight);
                // In the case of Bicubic interpolation check for negative values
                if (interpolationMethod == ImageProcessor.BICUBIC) {
                    float[] pixels = (float[]) fp.getPixels();
                    for (int i = 0; i < pixels.length; i++) if (pixels[i] < 0)
                        pixels[i] = 0;
                }
                // when resizing and the CoM will move.
                if (centreEachSlice) {
                    final double[] com = calculateCenterOfMass(fp);
                    //System.out.printf("CoM %d : %f %f vs %f %f\n", slice, com[0], com[1],
                    //		centre[0] * magnification, centre[1] * magnification);
                    // Get the insert position by subtracting the centre-of-mass of the enlarged image from the 
                    // image centre + allow for a border of 1 pixel * magnification
                    insertX = magnification + dstWidth * 0.5 - com[0];
                    insertY = magnification + dstHeight * 0.5 - com[1];
                //Utils.log("Insert point = %.2f,%.2f => %.2f,%.2f\n", dstWidth * 0.5 - cx, dstHeight * 0.5 - cy,
                //		insertX, insertY);
                } else {
                    // Get the insert position from the stack centre using enlargement
                    insertX = getInsert(centre[0], (int) centre[0], magnification);
                    insertY = getInsert(centre[1], (int) centre[1], magnification);
                //Utils.log("Insert point = %.2f,%.2f => %.2f,%.2f\n", centre[0] - (int) centre[0], centre[1] - (int) centre[1], insertX, insertY);
                }
                // Copy the processor using a weighted image
                final int lowerX = (int) insertX;
                final int lowerY = (int) insertY;
                final double wx2 = insertX - lowerX;
                final double wx1 = 1 - wx2;
                final double wy2 = insertY - lowerY;
                final double wy1 = 1 - wy2;
                // Add to the combined PSF using the correct offset and the weighting
                copyBits(ip, fp, lowerX, lowerY, wx1 * wy1);
                copyBits(ip, fp, lowerX + 1, lowerY, wx2 * wy1);
                copyBits(ip, fp, lowerX, lowerY + 1, wx1 * wy2);
                copyBits(ip, fp, lowerX + 1, lowerY + 1, wx2 * wy2);
            //// Check CoM is correct. This is never perfect since the bilinear weighting 
            //// interpolates the data and shifts the CoM.
            //ImageProcessor ip2 = ip.createProcessor(ip.getWidth(), ip.getHeight());
            //copyBits(ip2, fp, lowerX, lowerY, wx1 * wy1);
            //copyBits(ip2, fp, lowerX + 1, lowerY, wx2 * wy1);
            //copyBits(ip2, fp, lowerX, lowerY + 1, wx1 * wy2);
            //copyBits(ip2, fp, lowerX + 1, lowerY + 1, wx2 * wy2);
            //
            //double[] com = getCoM((FloatProcessor) ip2);
            //System.out.printf("Inserted CoM %d : %f %f\n", slice, com[0], com[1]);
            }
        }));
        if (Utils.isInterrupted())
            break;
    }
    Utils.waitForCompletion(futures);
    return !Utils.isInterrupted();
}
Also used : ImageProcessor(ij.process.ImageProcessor) FloatProcessor(ij.process.FloatProcessor) Future(java.util.concurrent.Future) Point(java.awt.Point) BasePoint(gdsc.core.match.BasePoint) LinkedList(java.util.LinkedList)

Example 18 with ImageProcessor

use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.

the class FRC method pad.

private ImageProcessor pad(ImageProcessor ip, int width, int height) {
    if (ip.getWidth() != width || ip.getHeight() != height) {
        ImageProcessor ip2 = ip.createProcessor(width, height);
        ip2.insert(ip, 0, 0);
        return ip2;
    }
    return ip;
}
Also used : ImageProcessor(ij.process.ImageProcessor)

Example 19 with ImageProcessor

use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.

the class DriftCalculator method calculateUsingImageStack.

/**
	 * Calculates drift using images from a reference stack aligned to the overall z-projection.
	 * 
	 * @param stack
	 * 
	 * @param limits
	 * @return the drift { dx[], dy[] }
	 */
private double[][] calculateUsingImageStack(ImageStack stack, int[] limits) {
    // Update the limits using the stack size
    int upperT = startFrame + frameSpacing * (stack.getSize() - 1);
    limits[1] = FastMath.max(limits[1], upperT);
    // TODO - Truncate the stack if there are far too many frames for the localisation limits
    tracker.status("Constructing images");
    threadPool = Executors.newFixedThreadPool(Prefs.getThreads());
    // Built an image and FHT image for each slice
    final ImageProcessor[] images = new ImageProcessor[stack.getSize()];
    final FHT[] fhtImages = new FHT[stack.getSize()];
    List<Future<?>> futures = new LinkedList<Future<?>>();
    progressCounter = 0;
    totalCounter = images.length;
    int imagesPerThread = getImagesPerThread(images);
    final AlignImagesFFT aligner = new AlignImagesFFT();
    FloatProcessor referenceIp = stack.getProcessor(1).toFloat(0, null);
    // We do not care about the window method because this processor will not 
    // actually be used for alignment, it is a reference for the FHT size		
    aligner.init(referenceIp, WindowMethod.NONE, false);
    for (int i = 0; i < images.length; i += imagesPerThread) {
        futures.add(threadPool.submit(new ImageFHTInitialiser(stack, images, aligner, fhtImages, i, i + imagesPerThread)));
    }
    Utils.waitForCompletion(futures);
    tracker.progress(1);
    if (tracker.isEnded())
        return null;
    double[] dx = new double[limits[1] + 1];
    double[] dy = new double[dx.length];
    double[] originalDriftTimePoints = new double[dx.length];
    int[] blockT = new int[stack.getSize()];
    for (int i = 0, t = startFrame; i < stack.getSize(); i++, t += frameSpacing) {
        originalDriftTimePoints[t] = 1;
        blockT[i] = t;
    }
    double smoothing = updateSmoothingParameter(originalDriftTimePoints);
    lastdx = null;
    // For the first iteration calculate drift to the first image in the stack
    // (since the average projection may have a large drift blurring the image)
    double change = calculateDriftUsingImageStack(referenceIp, images, fhtImages, blockT, dx, dy, originalDriftTimePoints, smoothing, iterations);
    if (Double.isNaN(change) || tracker.isEnded())
        return null;
    plotDrift(limits, dx, dy);
    Utils.log("Drift Calculator : Initial drift " + Utils.rounded(change));
    for (int i = 1; i <= maxIterations; i++) {
        change = calculateDriftUsingImageStack(null, images, fhtImages, blockT, dx, dy, originalDriftTimePoints, smoothing, iterations);
        if (Double.isNaN(change))
            return null;
        plotDrift(limits, dx, dy);
        if (converged(i, change, getTotalDrift(dx, dy, originalDriftTimePoints)))
            break;
    }
    if (tracker.isEnded())
        return null;
    plotDrift(limits, dx, dy);
    return new double[][] { dx, dy };
}
Also used : FloatProcessor(ij.process.FloatProcessor) Point(java.awt.Point) LinkedList(java.util.LinkedList) ImageProcessor(ij.process.ImageProcessor) FHT(ij.process.FHT) Future(java.util.concurrent.Future) AlignImagesFFT(gdsc.core.ij.AlignImagesFFT)

Example 20 with ImageProcessor

use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.

the class DriftCalculator method calculateDriftUsingImageStack.

/**
	 * Calculate the drift of images to the reference image. If no reference is provided then produce a combined
	 * z-projection. Update the current drift parameters.
	 * 
	 * @param reference
	 * @param images
	 *            The images to align
	 * @param fhtImages
	 *            The images to align (pre-transformed to a FHT)
	 * @param blockT
	 *            The frame number for each image
	 * @param dx
	 *            The X drift
	 * @param dy
	 *            The Y drift
	 * @param originalDriftTimePoints
	 *            Non-zero when the frame number refers to an aligned image frame
	 * @param smoothing
	 * @param iterations
	 * @return The change in the drift (NaN is an error occurred)
	 */
private double calculateDriftUsingImageStack(FloatProcessor reference, ImageProcessor[] images, FHT[] fhtImages, int[] blockT, double[] dx, double[] dy, double[] originalDriftTimePoints, double smoothing, int iterations) {
    progressCounter = 0;
    totalCounter = images.length;
    if (reference == null) {
        // Construct images using the current drift
        tracker.status("Constructing reference image");
        // Built an image using the current drift
        List<Future<?>> futures = new LinkedList<Future<?>>();
        totalCounter = images.length * 2;
        final ImageProcessor[] blockIp = new ImageProcessor[images.length];
        double[] threadDx = new double[images.length];
        double[] threadDy = new double[images.length];
        for (int i = 0; i < images.length; i++) {
            threadDx[i] = dx[blockT[i]];
            threadDy[i] = dy[blockT[i]];
        }
        int imagesPerThread = getImagesPerThread(images);
        for (int i = 0; i < images.length; i += imagesPerThread) {
            futures.add(threadPool.submit(new ImageTranslator(images, blockIp, threadDx, threadDy, i, i + imagesPerThread)));
        }
        Utils.waitForCompletion(futures);
        // Build an image with all results.
        reference = new FloatProcessor(blockIp[0].getWidth(), blockIp[0].getHeight());
        for (ImageProcessor ip : blockIp) {
            reference.copyBits(ip, 0, 0, Blitter.ADD);
        }
    }
    // Ensure the reference is windowed
    AlignImagesFFT.applyWindowSeparable(reference, WindowMethod.TUKEY);
    return calculateDrift(blockT, 1f, dx, dy, originalDriftTimePoints, smoothing, iterations, fhtImages, reference, false);
}
Also used : ImageProcessor(ij.process.ImageProcessor) FloatProcessor(ij.process.FloatProcessor) Future(java.util.concurrent.Future) LinkedList(java.util.LinkedList) Point(java.awt.Point)

Aggregations

ImageProcessor (ij.process.ImageProcessor)33 FloatProcessor (ij.process.FloatProcessor)11 ImageStack (ij.ImageStack)10 ImagePlus (ij.ImagePlus)9 Rectangle (java.awt.Rectangle)9 IJImagePeakResults (gdsc.smlm.ij.results.IJImagePeakResults)5 PeakResult (gdsc.smlm.results.PeakResult)5 Point (java.awt.Point)5 LinkedList (java.util.LinkedList)4 Future (java.util.concurrent.Future)4 Calibration (gdsc.smlm.results.Calibration)3 ByteProcessor (ij.process.ByteProcessor)3 BasePoint (gdsc.core.match.BasePoint)2 ImageSource (gdsc.smlm.results.ImageSource)2 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)2 MappedImageStack (ij.MappedImageStack)2 Plot2 (ij.gui.Plot2)2 Calibration (ij.measure.Calibration)2 LutLoader (ij.plugin.LutLoader)2 WindowOrganiser (ij.plugin.WindowOrganiser)2