use of ij.process.FloatProcessor 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;
}
use of ij.process.FloatProcessor in project GDSC-SMLM by aherbert.
the class TraceMolecules method createBilinearPlot.
private FloatProcessor createBilinearPlot(List<double[]> results, int w, int h) {
FloatProcessor fp = new FloatProcessor(w, h);
// Create lookup table that map the tested threshold values to a position in the image
int[] xLookup = createLookup(tThresholds, settings.minTimeThreshold, w);
int[] yLookup = createLookup(dThresholds, settings.minDistanceThreshold, h);
origX = (settings.minTimeThreshold != 0) ? xLookup[1] : 0;
origY = (settings.minDistanceThreshold != 0) ? yLookup[1] : 0;
int gridWidth = tThresholds.length;
int gridHeight = dThresholds.length;
for (int y = 0, prevY = 0; y < gridHeight; y++) {
for (int x = 0, prevX = 0; x < gridWidth; x++) {
// Get the 4 flanking values
double x1y1 = results.get(prevY * gridWidth + prevX)[2];
double x1y2 = results.get(y * gridWidth + prevX)[2];
double x2y1 = results.get(prevY * gridWidth + x)[2];
double x2y2 = results.get(y * gridWidth + x)[2];
// Pixel range
int x1 = xLookup[x];
int x2 = xLookup[x + 1];
int y1 = yLookup[y];
int y2 = yLookup[y + 1];
double xRange = x2 - x1;
double yRange = y2 - y1;
for (int yy = y1; yy < y2; yy++) {
double yFraction = (yy - y1) / yRange;
for (int xx = x1; xx < x2; xx++) {
// Interpolate
double xFraction = (xx - x1) / xRange;
double v1 = x1y1 * (1 - xFraction) + x2y1 * xFraction;
double v2 = x1y2 * (1 - xFraction) + x2y2 * xFraction;
double value = v1 * (1 - yFraction) + v2 * yFraction;
fp.setf(xx, yy, (float) value);
}
}
prevX = x;
}
prevY = y;
}
// Convert to absolute for easier visualisation
float[] data = (float[]) fp.getPixels();
for (int i = 0; i < data.length; i++) data[i] = Math.abs(data[i]);
return fp;
}
use of ij.process.FloatProcessor in project GDSC-SMLM by aherbert.
the class PCPALMAnalysis method computeAutoCorrelationCurveFHT.
/**
* Compute the auto-correlation curve using FHT (ImageJ built-in). Computes the correlation
* image and then samples the image at radii up to the specified length to get the average
* correlation at a given radius.
*
* @param im
* @param w
* @param maxRadius
* @param nmPerPixel
* @param density
* @return { distances[], gr[], gr_se[] }
*/
private double[][] computeAutoCorrelationCurveFHT(ImageProcessor im, ImageProcessor w, int maxRadius, double nmPerPixel, double density) {
log("Creating Hartley transforms");
FHT2 fht2Im = padToFHT2(im);
FHT2 fht2W = padToFHT2(w);
if (fht2Im == null || fht2W == null) {
error("Unable to perform Hartley transform");
return null;
}
log("Performing correlation");
FloatProcessor corrIm = computeAutoCorrelationFHT(fht2Im);
FloatProcessor corrW = computeAutoCorrelationFHT(fht2W);
IJ.showProgress(1);
final int centre = corrIm.getHeight() / 2;
Rectangle crop = new Rectangle(centre - maxRadius, centre - maxRadius, maxRadius * 2, maxRadius * 2);
if (showCorrelationImages) {
displayCorrelation(corrIm, "Image correlation", crop);
displayCorrelation(corrW, "Window correlation", crop);
}
log("Normalising correlation");
FloatProcessor correlation = normaliseCorrelation(corrIm, corrW, density);
if (showCorrelationImages)
displayCorrelation(correlation, "Normalised correlation", crop);
return computeRadialAverage(maxRadius, nmPerPixel, correlation);
}
use of ij.process.FloatProcessor in project GDSC-SMLM by aherbert.
the class PCPALMAnalysis method computeAutoCorrelationFFT.
/**
* Compute the auto-correlation using the JTransforms FFT library
*
* @param ip
* @return
*/
private FloatProcessor computeAutoCorrelationFFT(ImageProcessor ip) {
FloatProcessor paddedIp = pad(ip);
if (paddedIp == null)
return null;
final int size = paddedIp.getWidth();
boolean doubleFFT = false;
float[] pixels = (float[]) paddedIp.getPixels();
float[] correlation = new float[size * size];
if (doubleFFT) {
DoubleFFT_2D fft = new DoubleFFT_2D(size, size);
double[] data = new double[size * size * 2];
for (int i = 0; i < pixels.length; i++) data[i] = pixels[i];
fft.realForwardFull(data);
// Re-use data
for (int i = 0, j = 0; i < data.length; i += 2, j++) {
data[j] = data[i] * data[i] + data[i + 1] * data[i + 1];
}
// Zero fill
for (int j = correlation.length; j < data.length; j++) data[j] = 0;
// Re-use the pre-computed object
//fft = new DoubleFFT_2D(size, size);
fft.realInverseFull(data, true);
// Get the real part of the data
for (int i = 0, j = 0; i < data.length; i += 2, j++) {
correlation[j] = (float) data[i];
}
} else {
FloatFFT_2D fft = new FloatFFT_2D(size, size);
float[] data = new float[size * size * 2];
System.arraycopy(pixels, 0, data, 0, pixels.length);
fft.realForwardFull(data);
// Re-use data
for (int i = 0, j = 0; i < data.length; i += 2, j++) {
data[j] = data[i] * data[i] + data[i + 1] * data[i + 1];
}
// Zero fill
for (int j = correlation.length; j < data.length; j++) data[j] = 0;
// Re-use the pre-computed object
//fft = new FloatFFT_2D(size, size);
fft.realInverseFull(data, true);
// Get the real part of the data
for (int i = 0, j = 0; i < data.length; i += 2, j++) {
correlation[j] = data[i];
}
}
// Swap quadrants
FloatProcessor fp = new FloatProcessor(size, size, correlation, null);
new FHT2().swapQuadrants(fp);
return fp;
}
use of ij.process.FloatProcessor in project GDSC-SMLM by aherbert.
the class IJImagePeakResultsTest method canInterpolateUpInYAtPixelEdge.
@Test
public void canInterpolateUpInYAtPixelEdge() {
IJImagePeakResults r = new IJImagePeakResults(title, bounds, 1);
r.setDisplayFlags(IJImagePeakResults.DISPLAY_WEIGHTED);
FloatProcessor fp = new FloatProcessor(bounds.width, bounds.height);
begin(r);
addValue(r, 1.5f, 2f, 2);
fp.putPixelValue(1, 1, 1);
fp.putPixelValue(1, 2, 1);
r.end();
float[] expecteds = getImage(fp);
float[] actuals = getImage(r);
Assert.assertArrayEquals(expecteds, actuals, 0);
}
Aggregations