openspim / SPIMAcquisition

The Micro-Manager plugin to acquire images with an OpenSPIM setup
1 stars 8 forks source link

Untangle the drift correction code from the actual acquisition #12

Closed dscho closed 9 years ago

dscho commented 9 years ago

To have a reliable antidrift, it is crucial to add unit tests that verify that the code does what it is supposed to do.

That means that we have to separate out the antidrift code into its own package with a neatly crafted API, with its own unit test (the first in this project, yay!). That will also allow us to extend the code to easily replay antidrift corrections that went awry.

dscho commented 9 years ago

A couple of notes regarding the to-be-written unit test we discussed:

I could not resist and whipped up an example for the Gaussian blobs in my Fiji script editor:

import ij.ImagePlus;
import ij.ImageStack;
import ij.process.FloatProcessor;

public class HongKee_Example2 {
    /**
     * Calculates the Gauss function (AKA kernel) of the given parameters.
     * 
     * @param size the size of the kernel
     * @param center the center of the Gaussian function
     * @param the standard deviation of the Gaussian function
     * @return the kernel
     */
    private static float[] gauss(final int size, final float center, final float sigma) {
        final float[] result = new float[size];
        for (int i = 0; i < size; i++) {
            final float x = (i - center) / sigma;
            result[i] = (float) Math.exp(-x * x / 2);
        }
        return result;
    }

    /**
     * Generates a Gaussian 3D blob.
     * 
     * @param width the width of the output image
     * @param height the height of the output image
     * @param depth the depth of the output image
     * @param centerX the x-coordinate of the center of the blob
     * @param centery the y-coordinate of the center of the blob
     * @param centerZ the z-coordinate of the center of the blob
     * @param sigmaX the fuzzy radius in x direction
     * @param sigmaY the fuzzy radius in y direction
     * @param sigmaZ the fuzzy radius in z direction
     * @return the image with the blob
     */
    private static ImagePlus generateBlob(final int width, final int height, final int depth,
            final float centerX, final float centerY, final float centerZ,
            final float sigmaX, final float sigmaY, final float sigmaZ) {
        final float[] gaussX = gauss(width, centerX, sigmaX);
        final float[] gaussY = gauss(height, centerY, sigmaY);
        final float[] gaussZ = gauss(depth, centerZ, sigmaZ);

        final ImageStack stack = new ImageStack(width, height);
        for (int k = 0; k < depth; k++) {
            final float[] pixels = new float[width * height];
            for (int j = 0; j < height; j++)
                for (int i = 0; i < width; i++)
                    pixels[i + width * j] = gaussX[i] * gaussY[j] * gaussZ[k];
            stack.addSlice(null, new FloatProcessor(width, height, pixels, null));
        }
        return new ImagePlus("Blob", stack);
    }

    public static void main(final String... args) {
        final ImagePlus imp = generateBlob(128, 128, 128, 64, 32, 48, 50, 30, 40);
        imp.show();
    }
}
dscho commented 9 years ago

Oh, BTW I do not recall what the current anti-drift restrictions are on the data type. IIRC it was limited to 16-bit images (in which case you would need to generate a ShortProcessor instead of the FloatProcessor of my example).

dscho commented 9 years ago

Forgotten note: Fiji wiki's page on development: http://fiji.sc/Introduction_into_Developing_Plugins (you can thank @ctrueden and @hinerm who did an excellent job of cleaning up this community resource!)

hkmoon commented 9 years ago

@dscho Thank you! I made a unit-test class for it. Could you have a look on e7ff6e9?

If you want to change the our SCRUM meeting time, just let me know.

dscho commented 9 years ago

Your work already looks very good! Thank you!

hkmoon commented 9 years ago

@dscho I have found the problem of anti-drift.

  1. X-axis offset should be applied with inverse sign especially in our OpenSPIM. Otherwise, it diverges.
  2. Pixel/um should be set before anti-drift. Because core.getPixelSizeUm() is 1 by default.

Finally, the anti-drift works well now. It would be good to have a way of systematically inferring pixelSizeUm value in micromanager without calibrating pixel size by drawing a line in the image.