Search in sources :

Example 1 with ComplexFloatType

use of net.imglib2.type.numeric.complex.ComplexFloatType in project imagej-ops by imagej.

the class ConvolveTest method testConvolve.

/**
 * tests fft based convolve
 */
@Test
public void testConvolve() {
    float delta = 0.0001f;
    int[] size = new int[] { 225, 167 };
    int[] kernelSize = new int[] { 27, 39 };
    long[] borderSize = new long[] { 10, 10 };
    // create an input with a small sphere at the center
    Img<FloatType> in = new ArrayImgFactory<FloatType>().create(size, new FloatType());
    placeSphereInCenter(in);
    // create a kernel with a small sphere in the center
    Img<FloatType> kernel = new ArrayImgFactory<FloatType>().create(kernelSize, new FloatType());
    placeSphereInCenter(kernel);
    // create variables to hold the image sums
    FloatType inSum = new FloatType();
    FloatType kernelSum = new FloatType();
    FloatType outSum = new FloatType();
    FloatType outSum2 = new FloatType();
    FloatType outSum3 = new FloatType();
    // calculate sum of input and kernel
    ops.stats().sum(inSum, in);
    ops.stats().sum(kernelSum, kernel);
    // convolve and calculate the sum of output
    @SuppressWarnings("unchecked") final Img<FloatType> out = (Img<FloatType>) ops.run(ConvolveFFTF.class, in, kernel, borderSize);
    // create an output for the next test
    Img<FloatType> out2 = new ArrayImgFactory<FloatType>().create(size, new FloatType());
    // create an output for the next test
    Img<FloatType> out3 = new ArrayImgFactory<FloatType>().create(size, new FloatType());
    // Op used to pad the input
    final BinaryFunctionOp<RandomAccessibleInterval<FloatType>, Dimensions, RandomAccessibleInterval<FloatType>> padOp = (BinaryFunctionOp) Functions.binary(ops, PadInputFFTMethods.class, RandomAccessibleInterval.class, RandomAccessibleInterval.class, Dimensions.class, true);
    // Op used to pad the kernel
    final BinaryFunctionOp<RandomAccessibleInterval<FloatType>, Dimensions, RandomAccessibleInterval<FloatType>> padKernelOp = (BinaryFunctionOp) Functions.binary(ops, PadShiftKernelFFTMethods.class, RandomAccessibleInterval.class, RandomAccessibleInterval.class, Dimensions.class, true);
    // Op used to create the complex FFTs
    UnaryFunctionOp<Dimensions, RandomAccessibleInterval<ComplexFloatType>> createOp = (UnaryFunctionOp) Functions.unary(ops, CreateOutputFFTMethods.class, RandomAccessibleInterval.class, Dimensions.class, new ComplexFloatType(), true);
    final int numDimensions = in.numDimensions();
    // 1. Calculate desired extended size of the image
    final long[] paddedSize = new long[numDimensions];
    // if no getBorderSize() was passed in, then extend based on kernel size
    for (int d = 0; d < numDimensions; ++d) {
        paddedSize[d] = (int) in.dimension(d) + (int) kernel.dimension(d) - 1;
    }
    RandomAccessibleInterval<FloatType> paddedInput = padOp.calculate(in, new FinalDimensions(paddedSize));
    RandomAccessibleInterval<FloatType> paddedKernel = padKernelOp.calculate(kernel, new FinalDimensions(paddedSize));
    RandomAccessibleInterval<ComplexFloatType> fftImage = createOp.calculate(new FinalDimensions(paddedSize));
    RandomAccessibleInterval<ComplexFloatType> fftKernel = createOp.calculate(new FinalDimensions(paddedSize));
    // run convolve using the rai version with the memory created above
    ops.run(ConvolveFFTC.class, out2, paddedInput, paddedKernel, fftImage, fftKernel);
    ops.run(ConvolveFFTC.class, out3, paddedInput, paddedKernel, fftImage, fftKernel, true, false);
    ops.stats().sum(outSum, Views.iterable(out));
    ops.stats().sum(outSum2, out2);
    ops.stats().sum(outSum3, out3);
    // multiply input sum by kernelSum and assert it is the same as outSum
    inSum.mul(kernelSum);
    assertEquals(inSum.get(), outSum.get(), delta);
    assertEquals(inSum.get(), outSum2.get(), delta);
    assertEquals(inSum.get(), outSum3.get(), delta);
    assertEquals(size[0], out.dimension(0));
    assertEquals(size[0], out2.dimension(0));
}
Also used : Img(net.imglib2.img.Img) ComplexFloatType(net.imglib2.type.numeric.complex.ComplexFloatType) FinalDimensions(net.imglib2.FinalDimensions) Dimensions(net.imglib2.Dimensions) BinaryFunctionOp(net.imagej.ops.special.function.BinaryFunctionOp) PadShiftKernelFFTMethods(net.imagej.ops.filter.pad.PadShiftKernelFFTMethods) Point(net.imglib2.Point) FloatType(net.imglib2.type.numeric.real.FloatType) ComplexFloatType(net.imglib2.type.numeric.complex.ComplexFloatType) FinalDimensions(net.imglib2.FinalDimensions) RandomAccessibleInterval(net.imglib2.RandomAccessibleInterval) CreateOutputFFTMethods(net.imagej.ops.filter.fft.CreateOutputFFTMethods) UnaryFunctionOp(net.imagej.ops.special.function.UnaryFunctionOp) PadInputFFTMethods(net.imagej.ops.filter.pad.PadInputFFTMethods) AbstractOpTest(net.imagej.ops.AbstractOpTest) Test(org.junit.Test)

Example 2 with ComplexFloatType

use of net.imglib2.type.numeric.complex.ComplexFloatType in project imagej-ops by imagej.

the class FFTTest method testFFT3DOp.

/**
 * test that a forward transform followed by an inverse transform gives us
 * back the original image
 */
@Test
public void testFFT3DOp() {
    final int min = expensiveTestsEnabled ? 115 : 9;
    final int max = expensiveTestsEnabled ? 120 : 11;
    for (int i = min; i < max; i++) {
        final long[] dimensions = new long[] { i, i, i };
        // create an input with a small sphere at the center
        final Img<FloatType> in = generateFloatArrayTestImg(false, dimensions);
        placeSphereInCenter(in);
        final Img<FloatType> inverse = generateFloatArrayTestImg(false, dimensions);
        @SuppressWarnings("unchecked") final Img<ComplexFloatType> out = (Img<ComplexFloatType>) ops.run(FFTMethodsOpF.class, in);
        ops.run(IFFTMethodsOpC.class, inverse, out);
        assertImagesEqual(in, inverse, .00005f);
    }
}
Also used : ComplexFloatType(net.imglib2.type.numeric.complex.ComplexFloatType) Img(net.imglib2.img.Img) Point(net.imglib2.Point) FFTMethodsOpF(net.imagej.ops.filter.fft.FFTMethodsOpF) FloatType(net.imglib2.type.numeric.real.FloatType) ComplexFloatType(net.imglib2.type.numeric.complex.ComplexFloatType) AbstractOpTest(net.imagej.ops.AbstractOpTest) Test(org.junit.Test)

Example 3 with ComplexFloatType

use of net.imglib2.type.numeric.complex.ComplexFloatType in project imagej-ops by imagej.

the class FFTTest method testFastFFT3DOp.

/**
 * test the fast FFT
 */
@Test
public void testFastFFT3DOp() {
    final int min = expensiveTestsEnabled ? 120 : 9;
    final int max = expensiveTestsEnabled ? 130 : 11;
    final int size = expensiveTestsEnabled ? 129 : 10;
    for (int i = min; i < max; i++) {
        // define the original dimensions
        final long[] originalDimensions = new long[] { i, size, size };
        // arrays for the fast dimensions
        final long[] fastDimensions = new long[3];
        final long[] fftDimensions = new long[3];
        // compute the dimensions that will result in the fastest FFT time
        ops.run(ComputeFFTSize.class, originalDimensions, fastDimensions, fftDimensions, true, true);
        // create an input with a small sphere at the center
        final Img<FloatType> inOriginal = generateFloatArrayTestImg(false, originalDimensions);
        placeSphereInCenter(inOriginal);
        // create a similar input using the fast size
        final Img<FloatType> inFast = generateFloatArrayTestImg(false, fastDimensions);
        placeSphereInCenter(inFast);
        // call FFT passing false for "fast" (in order to pass the optional
        // parameter we have to pass null for the
        // output parameter).
        @SuppressWarnings("unchecked") final RandomAccessibleInterval<ComplexFloatType> fft1 = (RandomAccessibleInterval<ComplexFloatType>) ops.run(FFTMethodsOpF.class, inOriginal, null, false);
        // call FFT passing true for "fast" The FFT op will pad the input to the
        // fast
        // size.
        @SuppressWarnings("unchecked") final RandomAccessibleInterval<ComplexFloatType> fft2 = (RandomAccessibleInterval<ComplexFloatType>) ops.run(FFTMethodsOpF.class, inOriginal, null, true);
        // call fft using the img that was created with the fast size
        @SuppressWarnings("unchecked") final RandomAccessibleInterval<ComplexFloatType> fft3 = (RandomAccessibleInterval<ComplexFloatType>) ops.run(FFTMethodsOpF.class, inFast);
        // create an image to be used for the inverse, using the original
        // size
        final Img<FloatType> inverseOriginalSmall = generateFloatArrayTestImg(false, originalDimensions);
        // create an inverse image to be used for the inverse, using the
        // original
        // size
        final Img<FloatType> inverseOriginalFast = generateFloatArrayTestImg(false, originalDimensions);
        // create an inverse image to be used for the inverse, using the
        // fast size
        final Img<FloatType> inverseFast = generateFloatArrayTestImg(false, fastDimensions);
        // invert the "small" FFT
        ops.run(IFFTMethodsOpC.class, inverseOriginalSmall, fft1);
        // invert the "fast" FFT. The inverse will should be the original
        // size.
        ops.run(IFFTMethodsOpC.class, inverseOriginalFast, fft2);
        // invert the "fast" FFT that was acheived by explicitly using an
        // image
        // that had "fast" dimensions. The inverse will be the fast size
        // this
        // time.
        ops.run(IFFTMethodsOpC.class, inverseFast, fft3);
        // assert that the inverse images are equal to the original
        assertImagesEqual(inverseOriginalSmall, inOriginal, .0001f);
        assertImagesEqual(inverseOriginalFast, inOriginal, .00001f);
        assertImagesEqual(inverseFast, inFast, 0.00001f);
    }
}
Also used : ComplexFloatType(net.imglib2.type.numeric.complex.ComplexFloatType) RandomAccessibleInterval(net.imglib2.RandomAccessibleInterval) Point(net.imglib2.Point) FFTMethodsOpF(net.imagej.ops.filter.fft.FFTMethodsOpF) FloatType(net.imglib2.type.numeric.real.FloatType) ComplexFloatType(net.imglib2.type.numeric.complex.ComplexFloatType) AbstractOpTest(net.imagej.ops.AbstractOpTest) Test(org.junit.Test)

Aggregations

AbstractOpTest (net.imagej.ops.AbstractOpTest)3 Point (net.imglib2.Point)3 ComplexFloatType (net.imglib2.type.numeric.complex.ComplexFloatType)3 FloatType (net.imglib2.type.numeric.real.FloatType)3 Test (org.junit.Test)3 FFTMethodsOpF (net.imagej.ops.filter.fft.FFTMethodsOpF)2 RandomAccessibleInterval (net.imglib2.RandomAccessibleInterval)2 Img (net.imglib2.img.Img)2 CreateOutputFFTMethods (net.imagej.ops.filter.fft.CreateOutputFFTMethods)1 PadInputFFTMethods (net.imagej.ops.filter.pad.PadInputFFTMethods)1 PadShiftKernelFFTMethods (net.imagej.ops.filter.pad.PadShiftKernelFFTMethods)1 BinaryFunctionOp (net.imagej.ops.special.function.BinaryFunctionOp)1 UnaryFunctionOp (net.imagej.ops.special.function.UnaryFunctionOp)1 Dimensions (net.imglib2.Dimensions)1 FinalDimensions (net.imglib2.FinalDimensions)1