use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.
the class FRCTest method canComputeMirrored.
@Test
public void canComputeMirrored() {
// Sample lines through an image to create a structure.
int size = 1024;
double[][] data = new double[size * 2][];
RandomGenerator r = new Well19937c(30051977);
for (int x = 0, y = 0, y2 = size, i = 0; x < size; x++, y++, y2--) {
data[i++] = new double[] { x + r.nextGaussian() * 5, y + r.nextGaussian() * 5 };
data[i++] = new double[] { x + r.nextGaussian() * 5, y2 + r.nextGaussian() * 5 };
}
// Create 2 images
Rectangle bounds = new Rectangle(0, 0, size, size);
IJImagePeakResults i1 = createImage(bounds);
IJImagePeakResults i2 = createImage(bounds);
int[] indices = Utils.newArray(data.length, 0, 1);
MathArrays.shuffle(indices, r);
for (int i : indices) {
IJImagePeakResults image = i1;
i1 = i2;
i2 = image;
image.add((float) data[i][0], (float) data[i][1], 1);
}
i1.end();
i2.end();
ImageProcessor ip1 = i1.getImagePlus().getProcessor();
ImageProcessor ip2 = i2.getImagePlus().getProcessor();
// Test
FRC frc = new FRC();
FloatProcessor[] fft1, fft2;
fft1 = frc.getComplexFFT(ip1);
fft2 = frc.getComplexFFT(ip2);
float[] dataA1 = (float[]) fft1[0].getPixels();
float[] dataB1 = (float[]) fft1[1].getPixels();
float[] dataA2 = (float[]) fft2[0].getPixels();
float[] dataB2 = (float[]) fft2[1].getPixels();
float[] numeratorE = new float[dataA1.length];
float[] absFFT1E = new float[dataA1.length];
float[] absFFT2E = new float[dataA1.length];
FRC.compute(numeratorE, absFFT1E, absFFT2E, dataA1, dataB1, dataA2, dataB2);
Assert.assertTrue("numeratorE", FRC.checkSymmetry(numeratorE, size));
Assert.assertTrue("absFFT1E", FRC.checkSymmetry(absFFT1E, size));
Assert.assertTrue("absFFT2E", FRC.checkSymmetry(absFFT2E, size));
float[] numeratorA = new float[dataA1.length];
float[] absFFT1A = new float[dataA1.length];
float[] absFFT2A = new float[dataA1.length];
FRC.computeMirrored(size, numeratorA, absFFT1A, absFFT2A, dataA1, dataB1, dataA2, dataB2);
//for (int y=0, i=0; y<size; y++)
// for (int x=0; x<size; x++, i++)
// {
// System.out.printf("[%d,%d = %d] %f ?= %f\n", x, y, i, numeratorE[i], numeratorA[i]);
// }
Assert.assertArrayEquals("numerator", numeratorE, numeratorA, 0);
Assert.assertArrayEquals("absFFT1", absFFT1E, absFFT1A, 0);
Assert.assertArrayEquals("absFFT2", absFFT2E, absFFT2A, 0);
FRC.computeMirroredFast(size, numeratorA, absFFT1A, absFFT2A, dataA1, dataB1, dataA2, dataB2);
// Check this.
for (int y = 1; y < size; y++) for (int x = 1, i = y * size + 1; x < size; x++, i++) {
Assert.assertEquals("numerator", numeratorE[i], numeratorA[i], 0);
Assert.assertEquals("absFFT1", absFFT1E[i], absFFT1A[i], 0);
Assert.assertEquals("absFFT2", absFFT2E[i], absFFT2A[i], 0);
}
}
use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.
the class FRCTest method computeMirroredIsFaster.
@Test
public void computeMirroredIsFaster() {
// Sample lines through an image to create a structure.
final int size = 2048;
double[][] data = new double[size * 2][];
RandomGenerator r = new Well19937c(30051977);
for (int x = 0, y = 0, y2 = size, i = 0; x < size; x++, y++, y2--) {
data[i++] = new double[] { x + r.nextGaussian() * 5, y + r.nextGaussian() * 5 };
data[i++] = new double[] { x + r.nextGaussian() * 5, y2 + r.nextGaussian() * 5 };
}
// Create 2 images
Rectangle bounds = new Rectangle(0, 0, size, size);
IJImagePeakResults i1 = createImage(bounds);
IJImagePeakResults i2 = createImage(bounds);
int[] indices = Utils.newArray(data.length, 0, 1);
MathArrays.shuffle(indices, r);
for (int i : indices) {
IJImagePeakResults image = i1;
i1 = i2;
i2 = image;
image.add((float) data[i][0], (float) data[i][1], 1);
}
i1.end();
i2.end();
ImageProcessor ip1 = i1.getImagePlus().getProcessor();
ImageProcessor ip2 = i2.getImagePlus().getProcessor();
// Test
FRC frc = new FRC();
FloatProcessor[] fft1, fft2;
fft1 = frc.getComplexFFT(ip1);
fft2 = frc.getComplexFFT(ip2);
final float[] dataA1 = (float[]) fft1[0].getPixels();
final float[] dataB1 = (float[]) fft1[1].getPixels();
final float[] dataA2 = (float[]) fft2[0].getPixels();
final float[] dataB2 = (float[]) fft2[1].getPixels();
final float[] numerator = new float[dataA1.length];
final float[] absFFT1 = new float[dataA1.length];
final float[] absFFT2 = new float[dataA1.length];
TimingService ts = new TimingService(10);
ts.execute(new MyTimingTask("compute") {
public Object run(Object data) {
FRC.compute(numerator, absFFT1, absFFT2, dataA1, dataB1, dataA2, dataB2);
return null;
}
});
ts.execute(new MyTimingTask("computeMirrored") {
public Object run(Object data) {
FRC.computeMirrored(size, numerator, absFFT1, absFFT2, dataA1, dataB1, dataA2, dataB2);
return null;
}
});
ts.execute(new MyTimingTask("computeMirroredFast") {
public Object run(Object data) {
FRC.computeMirroredFast(size, numerator, absFFT1, absFFT2, dataA1, dataB1, dataA2, dataB2);
return null;
}
});
ts.repeat(ts.getSize());
ts.report();
}
use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.
the class FRC method pad.
private ImageProcessor pad(ImageProcessor ip, int width, int height) {
if (ip.getWidth() != width || ip.getHeight() != height) {
ImageProcessor ip2 = ip.createProcessor(width, height);
ip2.insert(ip, 0, 0);
return ip2;
}
return ip;
}
use of ij.process.ImageProcessor 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 };
}
use of ij.process.ImageProcessor 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);
}
Aggregations