From 52a9ea40d405b316dd5b57b83c3d66c1bc7f5d4a Mon Sep 17 00:00:00 2001 From: Michael Innerberger Date: Mon, 16 Oct 2023 09:16:07 -0400 Subject: [PATCH] Add convenience methods for creating images from arrays --- src/main/java/net/imglib2/img/Imgs.java | 94 +++++++++++ .../img/ImgConvenienceFactoryMethodTest.java | 148 ++++++++++++++++++ 2 files changed, 242 insertions(+) create mode 100644 src/main/java/net/imglib2/img/Imgs.java create mode 100644 src/test/java/net/imglib2/img/ImgConvenienceFactoryMethodTest.java diff --git a/src/main/java/net/imglib2/img/Imgs.java b/src/main/java/net/imglib2/img/Imgs.java new file mode 100644 index 000000000..eac498f79 --- /dev/null +++ b/src/main/java/net/imglib2/img/Imgs.java @@ -0,0 +1,94 @@ +package net.imglib2.img; + +import net.imglib2.img.array.ArrayImgs; +import net.imglib2.type.numeric.complex.ComplexDoubleType; +import net.imglib2.type.numeric.complex.ComplexFloatType; +import net.imglib2.type.numeric.integer.ByteType; +import net.imglib2.type.numeric.integer.IntType; +import net.imglib2.type.numeric.integer.LongType; +import net.imglib2.type.numeric.real.DoubleType; +import net.imglib2.type.numeric.real.FloatType; + +import java.util.Arrays; + +/** + * Convenience factory methods for creation of {@link Img} instances from arrays + * for testing and exploration purposes. + * + * @author Michael Innerberger + */ +public class Imgs { + // prevent instantiation + private Imgs() {} + + public static Img fromArray(final byte[] array, final long... dimensions) { + return ArrayImgs.bytes(array, dimensions); + } + + public static Img fromArray(final int[] array, final long... dimensions) { + return ArrayImgs.ints(array, dimensions); + } + + public static Img fromArray(final long[] array, final long... dimensions) { + return ArrayImgs.longs(array, dimensions); + } + + public static Img fromArray(final float[] array, final long... dimensions) { + return ArrayImgs.floats(array, dimensions); + } + + public static Img fromArray(final double[] array, final long... dimensions) { + return ArrayImgs.doubles(array, dimensions); + } + + public static Img fromArray(final double[] real, final double[] imag, final long... dimensions) { + Img img = ArrayImgs.complexDoubles(dimensions); + int i = 0; + for (final ComplexDoubleType pixel : img) { + pixel.setReal(real[i]); + pixel.setImaginary(imag[i++]); + } + return img; + } + + public static Img fromArray(final float[] real, final float[] imag, final long... dimensions) { + Img img = ArrayImgs.complexFloats(dimensions); + int i = 0; + for (final ComplexFloatType pixel : img) { + pixel.setReal(real[i]); + pixel.setImaginary(imag[i++]); + } + return img; + } + + public static Img fromArrays(final byte[][] slices, final long... dimensions) { + final int nPixels = (int) Arrays.stream(dimensions).reduce(1, (a, b) -> a * b); + final byte[] array = new byte[nPixels]; + for (int i = 0; i < slices.length; i++) + System.arraycopy(slices[i], 0, array, i * slices[i].length, slices[i].length); + return fromArray(array, dimensions); + } + + public static Img fromArrays(final int[][] slices, final long... dimensions) { + final int[] array = Arrays.stream(slices).flatMapToInt(Arrays::stream).toArray(); + return fromArray(array, dimensions); + } + + public static Img fromArrays(final long[][] slices, final long... dimensions) { + final long[] array = Arrays.stream(slices).flatMapToLong(Arrays::stream).toArray(); + return fromArray(array, dimensions); + } + + public static Img fromArrays(final float[][] slices, final long... dimensions) { + final int nPixels = (int) Arrays.stream(dimensions).reduce(1, (a, b) -> a * b); + final float[] array = new float[nPixels]; + for (int i = 0; i < slices.length; i++) + System.arraycopy(slices[i], 0, array, i * slices[i].length, slices[i].length); + return fromArray(array, dimensions); + } + + public static Img fromArrays(final double[][] slices, final long... dimensions) { + final double[] array = Arrays.stream(slices).flatMapToDouble(Arrays::stream).toArray(); + return fromArray(array, dimensions); + } +} \ No newline at end of file diff --git a/src/test/java/net/imglib2/img/ImgConvenienceFactoryMethodTest.java b/src/test/java/net/imglib2/img/ImgConvenienceFactoryMethodTest.java new file mode 100644 index 000000000..51aa46572 --- /dev/null +++ b/src/test/java/net/imglib2/img/ImgConvenienceFactoryMethodTest.java @@ -0,0 +1,148 @@ +package net.imglib2.img; + +import net.imglib2.type.numeric.complex.ComplexDoubleType; +import net.imglib2.type.numeric.complex.ComplexFloatType; +import net.imglib2.type.numeric.integer.ByteType; +import net.imglib2.type.numeric.integer.IntType; +import net.imglib2.type.numeric.integer.LongType; +import net.imglib2.type.numeric.real.DoubleType; +import net.imglib2.type.numeric.real.FloatType; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ImgConvenienceFactoryMethodTest { + + private static final double delta = 0.0; + + @Test + public void createBytes() { + Img img = Imgs.fromArray(new byte[] { 1, 2, 3, 4, 5, 6 }, 2, 3); + int i = 0; + for (final ByteType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.get()); + } + } + + @Test + public void createInts() { + Img img = Imgs.fromArray(new int[] { 1, 2, 3, 4, 5, 6 }, 2, 3); + int i = 0; + for (final IntType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.get()); + } + } + + @Test + public void createLongs() { + Img img = Imgs.fromArray(new long[] { 1, 2, 3, 4, 5, 6 }, 2, 3); + int i = 0; + for (final LongType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.get()); + } + } + + @Test + public void createFloats() { + Img img = Imgs.fromArray(new float[] { 1, 2, 3, 4, 5, 6 }, 2, 3); + int i = 0; + for (final FloatType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.get(), delta); + } + } + + @Test + public void createDoubles() { + Img img = Imgs.fromArray(new double[] { 1, 2, 3, 4, 5, 6 }, 2, 3); + int i = 0; + for (final DoubleType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.get(), delta); + } + } + + @Test + public void createComplexFloats() { + Img img = Imgs.fromArray(new float[] { 1, 2, 3, 4, 5, 6 }, new float[] { 2, 3, 4, 5, 6, 7 }, 2, 3); + int i = 0; + for (final ComplexFloatType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.getRealDouble(), delta); + assertEquals(indexMsg(i), i+1, pixel.getImaginaryDouble(), delta); + } + } + + @Test + public void createComplexDoubles() { + Img img = Imgs.fromArray(new double[] { 1, 2, 3, 4, 5, 6 }, new double[] { 2, 3, 4, 5, 6, 7 }, 2, 3); + int i = 0; + for (final ComplexDoubleType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.getRealDouble(), delta); + assertEquals(indexMsg(i), i+1, pixel.getImaginaryDouble(), delta); + } + } + + @Test + public void createByteSlices() { + final byte[][] data = {{ 1, 2, 3, 4, 5, 6 }, { 7, 8, 9, 10, 11, 12 }}; + Img img = Imgs.fromArrays(data, 2, 3, 2); + int i = 0; + for (final ByteType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.get(), delta); + } + } + + @Test + public void createIntSlices() { + final int[][] data = {{ 1, 2, 3, 4, 5, 6 }, { 7, 8, 9, 10, 11, 12 }}; + Img img = Imgs.fromArrays(data, 2, 3, 2); + int i = 0; + for (final IntType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.get(), delta); + } + } + + @Test + public void createLongSlices() { + final long[][] data = {{ 1, 2, 3, 4, 5, 6 }, { 7, 8, 9, 10, 11, 12 }}; + Img img = Imgs.fromArrays(data, 2, 3, 2); + int i = 0; + for (final LongType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.get(), delta); + } + } + + @Test + public void createFloatSlices() { + final float[][] data = {{ 1, 2, 3, 4, 5, 6 }, { 7, 8, 9, 10, 11, 12 }}; + Img img = Imgs.fromArrays(data, 2, 3, 2); + int i = 0; + for (final FloatType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.get(), delta); + } + } + + @Test + public void createDoubleSlices() { + final double[][] data = {{ 1, 2, 3, 4, 5, 6 }, { 7, 8, 9, 10, 11, 12 }}; + Img img = Imgs.fromArrays(data, 2, 3, 2); + int i = 0; + for (final DoubleType pixel : img) { + i++; + assertEquals(indexMsg(i), i, pixel.get(), delta); + } + } + + private static String indexMsg(final int i) { + return "Index: " + i; + } +}