Search in sources :

Example 36 with ImageStack

use of ij.ImageStack 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 37 with ImageStack

use of ij.ImageStack in project GDSC-SMLM by aherbert.

the class YeastMask method createMask.

private void createMask() {
    // Create the dimensions
    final int hw = (int) Math.ceil(radius * 1000 / nmPerPixel);
    final int hd = (int) Math.ceil(radius * 1000 / nmPerSlice);
    final int width = 2 * hw + 1;
    final int depth = 2 * hd + 1;
    ImageStack stack = createHemiSphere(width, depth);
    // Extend the centre circle of the sphere into a tube of the required length
    final int h = (int) Math.ceil(length * 1000 / nmPerPixel);
    if (h > 0) {
        ImageStack newStack = new ImageStack(width, stack.getHeight() + h, stack.getSize());
        for (int slice = 1; slice <= stack.getSize(); slice++) {
            byte[] pixels = (byte[]) stack.getPixels(slice);
            byte[] newPixels = new byte[width * newStack.getHeight()];
            newStack.setPixels(newPixels, slice);
            System.arraycopy(pixels, 0, newPixels, 0, pixels.length);
            // Get the final strip to be extended
            final int offset = pixels.length - width;
            int target = pixels.length;
            for (int i = 0; i < h; i++) {
                System.arraycopy(pixels, offset, newPixels, target, width);
                target += width;
            }
        }
        stack = newStack;
    }
    // Copy the hemi-sphere onto the end
    ImageStack newStack = new ImageStack(width, stack.getHeight() + hw, stack.getSize());
    for (int slice = 1; slice <= stack.getSize(); slice++) {
        byte[] pixels = (byte[]) stack.getPixels(slice);
        byte[] newPixels = new byte[width * newStack.getHeight()];
        newStack.setPixels(newPixels, slice);
        System.arraycopy(pixels, 0, newPixels, 0, pixels.length);
        // Copy the hemi-sphere
        int source = 0;
        int target = newPixels.length - width;
        for (int i = 0; i < hw; i++) {
            System.arraycopy(pixels, source, newPixels, target, width);
            target -= width;
            source += width;
        }
    }
    stack = newStack;
    if (excludeNucleus) {
        ImageStack stack2 = createNucleusSphere(width, depth);
        int xloc = (stack.getWidth() - stack2.getWidth()) / 2;
        int yloc = (stack.getHeight() - stack2.getHeight()) / 2;
        int offset = (stack.getSize() - stack2.getSize()) / 2;
        for (int slice = 1; slice <= stack2.getSize(); slice++) {
            ImageProcessor ip = stack.getProcessor(slice + offset);
            ImageProcessor ip2 = stack2.getProcessor(slice);
            ip.copyBits(ip2, xloc, yloc, Blitter.SUBTRACT);
        }
    }
    if (squareOutput && stack.getWidth() != stack.getHeight()) {
        ImageStack stack2 = new ImageStack(stack.getHeight(), stack.getHeight());
        int end = stack.getHeight() - stack.getWidth();
        for (int slice = 1; slice <= stack.getSize(); slice++) {
            ImageProcessor ip = stack.getProcessor(slice);
            ImageProcessor ip2 = new ByteProcessor(stack2.getWidth(), stack2.getHeight());
            stack2.addSlice(ip2);
            for (int xloc = 0; xloc <= end; xloc += stack.getWidth()) {
                ip2.insert(ip, xloc, 0);
            }
        }
        stack = stack2;
    }
    if (border > 0) {
        ImageStack stack2 = new ImageStack(stack.getWidth() + 2 * border, stack.getHeight() + 2 * border);
        for (int slice = 1; slice <= stack.getSize(); slice++) {
            ImageProcessor ip = stack.getProcessor(slice);
            ImageProcessor ip2 = new ByteProcessor(stack2.getWidth(), stack2.getHeight());
            stack2.addSlice(ip2);
            ip2.insert(ip, border, border);
        }
        stack = stack2;
    }
    ImagePlus imp;
    if (is2D) {
        // TODO - Remove this laziness since we should really just do a 2D image
        int centre = stack.getSize() / 2;
        imp = Utils.display(TITLE, stack.getProcessor(centre));
    } else {
        imp = Utils.display(TITLE, stack);
    }
    // Calibrate
    Calibration cal = new Calibration();
    cal.setUnit("um");
    cal.pixelWidth = cal.pixelHeight = nmPerPixel / 1000;
    cal.pixelDepth = nmPerSlice / 1000;
    imp.setCalibration(cal);
}
Also used : ByteProcessor(ij.process.ByteProcessor) ImageProcessor(ij.process.ImageProcessor) ImageStack(ij.ImageStack) Calibration(ij.measure.Calibration) ImagePlus(ij.ImagePlus)

Example 38 with ImageStack

use of ij.ImageStack in project GDSC-SMLM by aherbert.

the class YeastMask method createHemiSphere.

/**
	 * Create a hemi-sphere using the given pixel width and stack depth using the original cell radius
	 * 
	 * @param width
	 * @param depth
	 * @return A hemi-sphere
	 */
private ImageStack createHemiSphere(int width, int depth) {
    // Create a sphere. This could be done exploiting symmetry to be more efficient
    // but is left as a simple implementation
    final double centreX = width * 0.5;
    final double centreZ = depth * 0.5;
    // Precompute squares for the width
    double[] s = new double[width];
    for (int iy = 0; iy < width; iy++) {
        final double y = (centreX - (iy + 0.5)) * nmPerPixel;
        s[iy] = y * y;
    }
    final int halfHeight = 1 + width / 2;
    ImageStack stack = new ImageStack(width, halfHeight, depth);
    final byte on = (byte) 255;
    final double r = radius * 1000;
    final double r2 = r * r;
    for (int iz = 0; iz < depth; iz++) {
        final double z = (centreZ - (iz + 0.5)) * nmPerSlice;
        final double z2 = z * z;
        byte[] mask = new byte[width * halfHeight];
        for (int iy = 0, i = 0; iy < halfHeight; iy++) {
            final double y2z2 = s[iy] + z2;
            for (int ix = 0; ix < width; ix++, i++) {
                final double d2 = s[ix] + y2z2;
                if (d2 < r2)
                    mask[i] = on;
            }
        }
        stack.setPixels(mask, iz + 1);
    }
    return stack;
}
Also used : ImageStack(ij.ImageStack)

Example 39 with ImageStack

use of ij.ImageStack in project GDSC-SMLM by aherbert.

the class TraceMolecules method buildCombinedImage.

private float[] buildCombinedImage(ImageSource source, Trace trace, float fitWidth, Rectangle bounds, double[] combinedNoise, boolean createStack) {
    final int w = source.getWidth();
    final int h = source.getHeight();
    // Get the coordinates and the spot bounds
    float[] centre = trace.getCentroid(CentroidMethod.SIGNAL_WEIGHTED);
    int minX = (int) Math.floor(centre[0] - fitWidth);
    int maxX = (int) Math.ceil(centre[0] + fitWidth);
    int minY = (int) Math.floor(centre[1] - fitWidth);
    int maxY = (int) Math.ceil(centre[1] + fitWidth);
    // Account for crops at the edge of the image
    minX = FastMath.max(0, minX);
    maxX = FastMath.min(w, maxX);
    minY = FastMath.max(0, minY);
    maxY = FastMath.min(h, maxY);
    int width = maxX - minX;
    int height = maxY - minY;
    if (width <= 0 || height <= 0) {
        // The centre must be outside the image width and height
        return null;
    }
    bounds.x = minX;
    bounds.y = minY;
    bounds.width = width;
    bounds.height = height;
    if (createStack)
        slices = new ImageStack(width, height);
    // Combine the images. Subtract the fitted background to zero the image.
    float[] data = new float[width * height];
    float sumBackground = 0;
    double noise = 0;
    for (PeakResult result : trace.getPoints()) {
        noise += result.noise * result.noise;
        float[] sourceData = source.get(result.getFrame(), bounds);
        final float background = result.getBackground();
        sumBackground += background;
        for (int i = 0; i < data.length; i++) {
            data[i] += sourceData[i] - background;
        }
        if (createStack)
            slices.addSlice(new FloatProcessor(width, height, sourceData, null));
    }
    if (createStack) {
        // Add a final image that is the average of the individual slices. This allows
        // it to be visualised in the same intensity scale.
        float[] data2 = Arrays.copyOf(data, data.length);
        final int size = slices.getSize();
        sumBackground /= size;
        for (int i = 0; i < data2.length; i++) data2[i] = sumBackground + data2[i] / size;
        slices.addSlice(new FloatProcessor(width, height, data2, null));
    }
    // Combined noise is the sqrt of the sum-of-squares
    combinedNoise[0] = Math.sqrt(noise);
    return data;
}
Also used : ImageStack(ij.ImageStack) FloatProcessor(ij.process.FloatProcessor) ClusterPoint(gdsc.core.clustering.ClusterPoint) PeakResult(gdsc.smlm.results.PeakResult)

Aggregations

ImageStack (ij.ImageStack)39 ImagePlus (ij.ImagePlus)13 ImageProcessor (ij.process.ImageProcessor)10 Rectangle (java.awt.Rectangle)9 LinkedList (java.util.LinkedList)8 PeakResult (gdsc.smlm.results.PeakResult)7 BasePoint (gdsc.core.match.BasePoint)6 ArrayBlockingQueue (java.util.concurrent.ArrayBlockingQueue)6 Statistics (gdsc.core.utils.Statistics)5 MemoryPeakResults (gdsc.smlm.results.MemoryPeakResults)5 Point (java.awt.Point)5 ExecutorService (java.util.concurrent.ExecutorService)5 Future (java.util.concurrent.Future)5 StoredDataStatistics (gdsc.core.utils.StoredDataStatistics)4 PeakResultPoint (gdsc.smlm.ij.plugins.ResultsMatchCalculator.PeakResultPoint)4 FloatProcessor (ij.process.FloatProcessor)4 FitWorker (gdsc.smlm.engine.FitWorker)3 IJImageSource (gdsc.smlm.ij.IJImageSource)3 Calibration (gdsc.smlm.results.Calibration)3 WindowOrganiser (ij.plugin.WindowOrganiser)3