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));
}
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();
}
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);
}
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());
}
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;
}
Aggregations