Search in sources :

Example 31 with FloatProcessor

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

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

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

the class SpotInspector method run.

/*
	 * (non-Javadoc)
	 * 
	 * @see ij.plugin.PlugIn#run(java.lang.String)
	 */
public void run(String arg) {
    SMLMUsageTracker.recordPlugin(this.getClass(), arg);
    if (MemoryPeakResults.isMemoryEmpty()) {
        IJ.error(TITLE, "No localisations in memory");
        return;
    }
    if (!showDialog())
        return;
    // Load the results
    results = ResultsManager.loadInputResults(inputOption, false);
    if (results == null || results.size() == 0) {
        IJ.error(TITLE, "No results could be loaded");
        IJ.showStatus("");
        return;
    }
    // Check if the original image is open
    ImageSource source = results.getSource();
    if (source == null) {
        IJ.error(TITLE, "Unknown original source image");
        return;
    }
    source = source.getOriginal();
    if (!source.open()) {
        IJ.error(TITLE, "Cannot open original source image: " + source.toString());
        return;
    }
    final float stdDevMax = getStandardDeviation(results);
    if (stdDevMax < 0) {
        // TODO - Add dialog to get the initial peak width
        IJ.error(TITLE, "Fitting configuration (for initial peak width) is not available");
        return;
    }
    // Rank spots
    rankedResults = new ArrayList<PeakResultRank>(results.size());
    final double a = results.getNmPerPixel();
    final double gain = results.getGain();
    final boolean emCCD = results.isEMCCD();
    for (PeakResult r : results.getResults()) {
        float[] score = getScore(r, a, gain, emCCD, stdDevMax);
        rankedResults.add(new PeakResultRank(r, score[0], score[1]));
    }
    Collections.sort(rankedResults);
    // Prepare results table. Get bias if necessary
    if (showCalibratedValues) {
        // Get a bias if required
        Calibration calibration = results.getCalibration();
        if (calibration.getBias() == 0) {
            ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
            gd.addMessage("Calibrated results requires a camera bias");
            gd.addNumericField("Camera_bias (ADUs)", calibration.getBias(), 2);
            gd.showDialog();
            if (!gd.wasCanceled()) {
                calibration.setBias(Math.abs(gd.getNextNumber()));
            }
        }
    }
    IJTablePeakResults table = new IJTablePeakResults(false, results.getName(), true);
    table.copySettings(results);
    table.setTableTitle(TITLE);
    table.setAddCounter(true);
    table.setShowCalibratedValues(showCalibratedValues);
    table.begin();
    // Add a mouse listener to jump to the frame for the clicked line
    textPanel = table.getResultsWindow().getTextPanel();
    // We must ignore old instances of this class from the mouse listeners
    id = ++currentId;
    textPanel.addMouseListener(this);
    // Add results to the table
    int n = 0;
    for (PeakResultRank rank : rankedResults) {
        rank.rank = n++;
        PeakResult r = rank.peakResult;
        table.add(r.getFrame(), r.origX, r.origY, r.origValue, r.error, r.noise, r.params, r.paramsStdDev);
    }
    table.end();
    if (plotScore || plotHistogram) {
        // Get values for the plots
        float[] xValues = null, yValues = null;
        double yMin, yMax;
        int spotNumber = 0;
        xValues = new float[rankedResults.size()];
        yValues = new float[xValues.length];
        for (PeakResultRank rank : rankedResults) {
            xValues[spotNumber] = spotNumber + 1;
            yValues[spotNumber++] = recoverScore(rank.score);
        }
        // Set the min and max y-values using 1.5 x IQR 
        DescriptiveStatistics stats = new DescriptiveStatistics();
        for (float v : yValues) stats.addValue(v);
        if (removeOutliers) {
            double lower = stats.getPercentile(25);
            double upper = stats.getPercentile(75);
            double iqr = upper - lower;
            yMin = FastMath.max(lower - iqr, stats.getMin());
            yMax = FastMath.min(upper + iqr, stats.getMax());
            IJ.log(String.format("Data range: %f - %f. Plotting 1.5x IQR: %f - %f", stats.getMin(), stats.getMax(), yMin, yMax));
        } else {
            yMin = stats.getMin();
            yMax = stats.getMax();
            IJ.log(String.format("Data range: %f - %f", yMin, yMax));
        }
        plotScore(xValues, yValues, yMin, yMax);
        plotHistogram(yValues, yMin, yMax);
    }
    // Extract spots into a stack
    final int w = source.getWidth();
    final int h = source.getHeight();
    final int size = 2 * radius + 1;
    ImageStack spots = new ImageStack(size, size, rankedResults.size());
    // To assist the extraction of data from the image source, process them in time order to allow 
    // frame caching. Then set the appropriate slice in the result stack
    Collections.sort(rankedResults, new Comparator<PeakResultRank>() {

        public int compare(PeakResultRank o1, PeakResultRank o2) {
            if (o1.peakResult.getFrame() < o2.peakResult.getFrame())
                return -1;
            if (o1.peakResult.getFrame() > o2.peakResult.getFrame())
                return 1;
            return 0;
        }
    });
    for (PeakResultRank rank : rankedResults) {
        PeakResult r = rank.peakResult;
        // Extract image
        // Note that the coordinates are relative to the middle of the pixel (0.5 offset)
        // so do not round but simply convert to int
        final int x = (int) (r.params[Gaussian2DFunction.X_POSITION]);
        final int y = (int) (r.params[Gaussian2DFunction.Y_POSITION]);
        // Extract a region but crop to the image bounds
        int minX = x - radius;
        int minY = y - radius;
        int maxX = FastMath.min(x + radius + 1, w);
        int maxY = FastMath.min(y + radius + 1, h);
        int padX = 0, padY = 0;
        if (minX < 0) {
            padX = -minX;
            minX = 0;
        }
        if (minY < 0) {
            padY = -minY;
            minY = 0;
        }
        int sizeX = maxX - minX;
        int sizeY = maxY - minY;
        float[] data = source.get(r.getFrame(), new Rectangle(minX, minY, sizeX, sizeY));
        // Prevent errors with missing data
        if (data == null)
            data = new float[sizeX * sizeY];
        ImageProcessor spotIp = new FloatProcessor(sizeX, sizeY, data, null);
        // Pad if necessary, i.e. the crop is too small for the stack
        if (padX > 0 || padY > 0 || sizeX < size || sizeY < size) {
            ImageProcessor spotIp2 = spotIp.createProcessor(size, size);
            spotIp2.insert(spotIp, padX, padY);
            spotIp = spotIp2;
        }
        int slice = rank.rank + 1;
        spots.setPixels(spotIp.getPixels(), slice);
        spots.setSliceLabel(Utils.rounded(rank.originalScore), slice);
    }
    source.close();
    ImagePlus imp = Utils.display(TITLE, spots);
    imp.setRoi((PointRoi) null);
    // Make bigger		
    for (int i = 10; i-- > 0; ) imp.getWindow().getCanvas().zoomIn(imp.getWidth() / 2, imp.getHeight() / 2);
}
Also used : DescriptiveStatistics(org.apache.commons.math3.stat.descriptive.DescriptiveStatistics) ImageStack(ij.ImageStack) FloatProcessor(ij.process.FloatProcessor) Rectangle(java.awt.Rectangle) Calibration(gdsc.smlm.results.Calibration) ExtendedGenericDialog(ij.gui.ExtendedGenericDialog) ImagePlus(ij.ImagePlus) PeakResult(gdsc.smlm.results.PeakResult) ImageProcessor(ij.process.ImageProcessor) IJTablePeakResults(gdsc.smlm.ij.results.IJTablePeakResults) ImageSource(gdsc.smlm.results.ImageSource)

Example 34 with FloatProcessor

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

the class SmoothImage method run.

/*
	 * (non-Javadoc)
	 * 
	 * @see ij.plugin.filter.PlugInFilter#run(ij.process.ImageProcessor)
	 */
public void run(ImageProcessor ip) {
    Rectangle bounds = ip.getRoi();
    // Crop to the ROI
    FloatProcessor fp = ip.crop().toFloat(0, null);
    float[] data = (float[]) fp.getPixels();
    MaximaSpotFilter filter = createSpotFilter();
    int width = fp.getWidth();
    int height = fp.getHeight();
    data = filter.preprocessData(data, width, height);
    //System.out.println(filter.getDescription());
    fp = new FloatProcessor(width, height, data);
    ip.insert(fp, bounds.x, bounds.y);
    //ip.resetMinAndMax();
    ip.setMinAndMax(fp.getMin(), fp.getMax());
}
Also used : FloatProcessor(ij.process.FloatProcessor) MaximaSpotFilter(gdsc.smlm.filters.MaximaSpotFilter) Rectangle(java.awt.Rectangle)

Example 35 with FloatProcessor

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

the class PCPALMAnalysis method normaliseCorrelation.

private FloatProcessor normaliseCorrelation(FloatProcessor corrIm, FloatProcessor corrW, double density) {
    float[] data = new float[corrIm.getWidth() * corrIm.getHeight()];
    float[] dataIm = (float[]) corrIm.getPixels();
    float[] dataW = (float[]) corrW.getPixels();
    // Square the density for normalisation
    density *= density;
    for (int i = 0; i < data.length; i++) {
        data[i] = (float) ((double) dataIm[i] / (density * dataW[i]));
    }
    FloatProcessor correlation = new FloatProcessor(corrIm.getWidth(), corrIm.getHeight(), data, null);
    return correlation;
}
Also used : FloatProcessor(ij.process.FloatProcessor)

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