Search in sources :

Example 26 with FloatProcessor

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

the class ConfigurationTemplateTest method canLoadTemplateImageFromFile.

@Test
public void canLoadTemplateImageFromFile() throws IOException {
    ConfigurationTemplate.clearTemplates();
    Assert.assertEquals(0, ConfigurationTemplate.getTemplateNamesWithImage().length);
    // Create a dummy image
    int size = 20;
    float[] pixels = new float[size * size];
    RandomGenerator r = new Well19937c();
    for (int i = pixels.length; i-- > 0; ) pixels[i] = r.nextFloat();
    ImagePlus imp = new ImagePlus("test", new FloatProcessor(size, size, pixels));
    File tmpFile = File.createTempFile("tmp", ".tif");
    tmpFile.deleteOnExit();
    IJ.save(imp, tmpFile.getPath());
    String name = "canLoadTemplateImageFromFile";
    File file = new File(Utils.replaceExtension(tmpFile.getPath(), ".xml"));
    ConfigurationTemplate.saveTemplate(name, new GlobalSettings(), file);
    Assert.assertEquals(1, ConfigurationTemplate.getTemplateNamesWithImage().length);
    ImagePlus imp2 = ConfigurationTemplate.getTemplateImage(name);
    Assert.assertNotNull(imp2);
    float[] data = (float[]) imp2.getProcessor().toFloat(0, null).getPixels();
    Assert.assertArrayEquals(pixels, data, 0);
}
Also used : FloatProcessor(ij.process.FloatProcessor) GlobalSettings(gdsc.smlm.ij.settings.GlobalSettings) Well19937c(org.apache.commons.math3.random.Well19937c) ImagePlus(ij.ImagePlus) File(java.io.File) RandomGenerator(org.apache.commons.math3.random.RandomGenerator) Test(org.junit.Test)

Example 27 with FloatProcessor

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

the class FRC method getComplexFFT.

/**
	 * Convert an image into a Fourier image with real and imaginary parts
	 * 
	 * @param ip
	 *            The image
	 * @return the real and imaginary parts
	 */
public FloatProcessor[] getComplexFFT(ImageProcessor ip) {
    FloatProcessor taperedDataImage = getSquareTaperedImage(ip);
    FHT2 fht = new FHT2(taperedDataImage);
    fht.setShowProgress(false);
    fht.transform();
    ImageStack stack1 = fht.getComplexTransform();
    return getProcessors(stack1);
}
Also used : FHT2(ij.process.FHT2) FloatProcessor(ij.process.FloatProcessor) ImageStack(ij.ImageStack)

Example 28 with FloatProcessor

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

the class GaussianFit method runFinal.

/**
	 * Perform fitting using the chosen maxima. Update the overlay if successful.
	 * 
	 * @param ip
	 *            The input image
	 */
private void runFinal(ImageProcessor ip) {
    ip.reset();
    Rectangle bounds = ip.getRoi();
    // Crop to the ROI
    float[] data = ImageConverter.getData(ip);
    int width = bounds.width;
    int height = bounds.height;
    // Sort the maxima
    float[] smoothData = data;
    if (getSmooth() > 0) {
        // Smoothing destructively modifies the data so create a copy
        smoothData = Arrays.copyOf(data, width * height);
        AverageFilter filter = new AverageFilter();
        //filter.blockAverage(smoothData, width, height, smooth);
        if (smooth <= border)
            filter.stripedBlockAverageInternal(smoothData, width, height, (float) smooth);
        else
            filter.stripedBlockAverage(smoothData, width, height, (float) smooth);
    }
    Sort.sort(maxIndices, smoothData);
    // Show the candidate peaks
    if (maxIndices.length > 0) {
        String message = String.format("Identified %d peaks", maxIndices.length);
        if (isLogProgress()) {
            IJ.log(message);
            for (int index : maxIndices) {
                IJ.log(String.format("  %.2f @ [%d,%d]", data[index], bounds.x + index % width, bounds.y + index / width));
            }
        }
        // Check whether to run if the number of peaks is large
        if (maxIndices.length > 10) {
            GenericDialog gd = new GenericDialog("Warning");
            gd.addMessage(message + "\nDo you want to fit?");
            gd.showDialog();
            if (gd.wasCanceled())
                return;
        }
    } else {
        IJ.log("No maxima identified");
        return;
    }
    results = new IJTablePeakResults(showDeviations, imp.getTitle() + " [" + imp.getCurrentSlice() + "]");
    results.begin();
    // Perform the Gaussian fit
    long ellapsed = 0;
    if (!singleFit) {
        if (isLogProgress())
            IJ.log("Combined fit");
        // Estimate height from smoothed data
        double[] estimatedHeights = new double[maxIndices.length];
        for (int i = 0; i < estimatedHeights.length; i++) estimatedHeights[i] = smoothData[maxIndices[i]];
        FitConfiguration config = new FitConfiguration();
        setupPeakFiltering(config);
        long time = System.nanoTime();
        double[] params = fitMultiple(data, width, height, maxIndices, estimatedHeights);
        ellapsed = System.nanoTime() - time;
        if (params != null) {
            // Copy all the valid parameters into a new array
            double[] validParams = new double[params.length];
            int c = 0;
            int validPeaks = 0;
            validParams[c++] = params[0];
            double[] initialParams = convertParameters(fitResult.getInitialParameters());
            double[] paramsDev = convertParameters(fitResult.getParameterStdDev());
            Rectangle regionBounds = new Rectangle();
            int[] xpoints = new int[maxIndices.length];
            int[] ypoints = new int[maxIndices.length];
            int nMaxima = 0;
            for (int i = 1, n = 0; i < params.length; i += 6, n++) {
                int y = maxIndices[n] / width;
                int x = maxIndices[n] % width;
                // Check the peak is a good fit
                if (filterResults && config.validatePeak(n, initialParams, params) != FitStatus.OK)
                    continue;
                if (showFit) {
                    // Copy the valid parameters
                    validPeaks++;
                    for (int ii = i, j = 0; j < 6; ii++, j++) validParams[c++] = params[ii];
                }
                double[] peakParams = extractParams(params, i);
                double[] peakParamsDev = extractParams(paramsDev, i);
                addResult(bounds, regionBounds, data, peakParams, peakParamsDev, nMaxima, x, y, data[maxIndices[n]]);
                // Add fit result to the overlay - Coords are updated with the region offsets in addResult
                double xf = peakParams[3];
                double yf = peakParams[4];
                xpoints[nMaxima] = (int) (xf + 0.5);
                ypoints[nMaxima] = (int) (yf + 0.5);
                nMaxima++;
            }
            setOverlay(nMaxima, xpoints, ypoints);
            // Draw the fit
            if (showFit && validPeaks != 0) {
                double[] pixels = new double[data.length];
                EllipticalGaussian2DFunction f = new EllipticalGaussian2DFunction(validPeaks, width, height);
                invertParameters(validParams);
                f.initialise(validParams);
                for (int x = 0; x < pixels.length; x++) pixels[x] = f.eval(x);
                FloatProcessor fp = new FloatProcessor(width, height, pixels);
                // Insert into a full size image
                FloatProcessor fp2 = new FloatProcessor(ip.getWidth(), ip.getHeight());
                fp2.insert(fp, bounds.x, bounds.y);
                Utils.display(TITLE, fp2);
            }
        } else {
            if (isLogProgress()) {
                IJ.log("Failed to fit " + Utils.pleural(maxIndices.length, "peak") + getReason(fitResult));
            }
            imp.setOverlay(null);
        }
    } else {
        if (isLogProgress())
            IJ.log("Individual fit");
        int nMaxima = 0;
        int[] xpoints = new int[maxIndices.length];
        int[] ypoints = new int[maxIndices.length];
        // Extract each peak and fit individually
        ImageExtractor ie = new ImageExtractor(data, width, height);
        float[] region = null;
        Gaussian2DFitter gf = createGaussianFitter(filterResults);
        for (int n = 0; n < maxIndices.length; n++) {
            int y = maxIndices[n] / width;
            int x = maxIndices[n] % width;
            long time = System.nanoTime();
            Rectangle regionBounds = ie.getBoxRegionBounds(x, y, singleRegionSize);
            region = ie.crop(regionBounds, region);
            int newIndex = (y - regionBounds.y) * regionBounds.width + x - regionBounds.x;
            if (isLogProgress()) {
                IJ.log("Fitting peak " + (n + 1));
            }
            double[] peakParams = fitSingle(gf, region, regionBounds.width, regionBounds.height, newIndex, smoothData[maxIndices[n]]);
            ellapsed += System.nanoTime() - time;
            // Output fit result
            if (peakParams != null) {
                double[] peakParamsDev = null;
                if (showDeviations) {
                    peakParamsDev = convertParameters(fitResult.getParameterStdDev());
                }
                addResult(bounds, regionBounds, data, peakParams, peakParamsDev, n, x, y, data[maxIndices[n]]);
                // Add fit result to the overlay - Coords are updated with the region offsets in addResult
                double xf = peakParams[3];
                double yf = peakParams[4];
                xpoints[nMaxima] = (int) (xf + 0.5);
                ypoints[nMaxima] = (int) (yf + 0.5);
                nMaxima++;
            } else {
                if (isLogProgress()) {
                    IJ.log("Failed to fit peak " + (n + 1) + getReason(fitResult));
                }
            }
        }
        // Update the overlay
        if (nMaxima > 0)
            setOverlay(nMaxima, xpoints, ypoints);
        else
            imp.setOverlay(null);
    }
    results.end();
    if (isLogProgress())
        IJ.log("Time = " + (ellapsed / 1000000.0) + "ms");
}
Also used : FloatProcessor(ij.process.FloatProcessor) EllipticalGaussian2DFunction(gdsc.smlm.function.gaussian.EllipticalGaussian2DFunction) Gaussian2DFitter(gdsc.smlm.fitting.Gaussian2DFitter) Rectangle(java.awt.Rectangle) AverageFilter(gdsc.smlm.filters.AverageFilter) IJTablePeakResults(gdsc.smlm.ij.results.IJTablePeakResults) FitConfiguration(gdsc.smlm.fitting.FitConfiguration) GenericDialog(ij.gui.GenericDialog) ImageExtractor(gdsc.core.utils.ImageExtractor)

Example 29 with FloatProcessor

use of ij.process.FloatProcessor 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 30 with FloatProcessor

use of ij.process.FloatProcessor 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

FloatProcessor (ij.process.FloatProcessor)49 Test (org.junit.Test)22 ImageProcessor (ij.process.ImageProcessor)11 Rectangle (java.awt.Rectangle)8 FHT2 (ij.process.FHT2)5 ImageStack (ij.ImageStack)4 Point (java.awt.Point)4 LinkedList (java.util.LinkedList)4 Future (java.util.concurrent.Future)4 ClusterPoint (gdsc.core.clustering.ClusterPoint)3 IJImagePeakResults (gdsc.smlm.ij.results.IJImagePeakResults)3 ImagePlus (ij.ImagePlus)3 RandomGenerator (org.apache.commons.math3.random.RandomGenerator)3 Well19937c (org.apache.commons.math3.random.Well19937c)3 BasePoint (gdsc.core.match.BasePoint)2 MaximaSpotFilter (gdsc.smlm.filters.MaximaSpotFilter)2 IJTablePeakResults (gdsc.smlm.ij.results.IJTablePeakResults)2 PeakResult (gdsc.smlm.results.PeakResult)2 ColorProcessor (ij.process.ColorProcessor)2 ShortProcessor (ij.process.ShortProcessor)2