From d1d762a8ba40ac4416cbe74351bd2f70de920405 Mon Sep 17 00:00:00 2001
From: Tobias Pietzsch <tobias.pietzsch@gmail.com>
Date: Wed, 5 Mar 2014 15:07:40 -0500
Subject: [PATCH] Utility method for computing mipmapTransform (for standard
 averaging down-scaling)

---
 .../bdv/img/catmaid/CatmaidImageLoader.java   | 12 +++++++
 .../java/bdv/img/hdf5/Hdf5ImageLoader.java    | 12 ++-----
 .../bdv/img/remote/RemoteImageLoader.java     | 12 ++-----
 src/main/java/bdv/util/MipmapTransforms.java  | 32 +++++++++++++++++++
 4 files changed, 48 insertions(+), 20 deletions(-)
 create mode 100644 src/main/java/bdv/util/MipmapTransforms.java

diff --git a/src/main/java/bdv/img/catmaid/CatmaidImageLoader.java b/src/main/java/bdv/img/catmaid/CatmaidImageLoader.java
index f7b839f0..7eedf8a2 100644
--- a/src/main/java/bdv/img/catmaid/CatmaidImageLoader.java
+++ b/src/main/java/bdv/img/catmaid/CatmaidImageLoader.java
@@ -7,6 +7,7 @@ import net.imglib2.RandomAccessibleInterval;
 import net.imglib2.img.NativeImg;
 import net.imglib2.img.basictypeaccess.volatiles.array.VolatileIntArray;
 import net.imglib2.img.cell.CellImg;
+import net.imglib2.realtransform.AffineTransform3D;
 import net.imglib2.type.NativeType;
 import net.imglib2.type.numeric.ARGBType;
 import net.imglib2.type.volatiles.VolatileARGBType;
@@ -19,6 +20,7 @@ import bdv.img.cache.VolatileGlobalCellCache;
 import bdv.img.cache.VolatileGlobalCellCache.LoadingStrategy;
 import bdv.img.cache.VolatileImgCells;
 import bdv.img.cache.VolatileImgCells.CellCache;
+import bdv.util.MipmapTransforms;
 
 public class CatmaidImageLoader extends AbstractViewerImgLoader< ARGBType, VolatileARGBType >
 {
@@ -42,6 +44,8 @@ public class CatmaidImageLoader extends AbstractViewerImgLoader< ARGBType, Volat
 
 	private double[][] mipmapResolutions;
 
+	private AffineTransform3D[] mipmapTransforms;
+
 	private long[][] imageDimensions;
 
 	private int[][] blockDimensions;
@@ -75,11 +79,13 @@ public class CatmaidImageLoader extends AbstractViewerImgLoader< ARGBType, Volat
 			numScales = Integer.parseInt( numScalesString );
 
 		mipmapResolutions = new double[ numScales ][];
+		mipmapTransforms = new AffineTransform3D[ numScales ];
 		imageDimensions = new long[ numScales ][];
 		blockDimensions = new int[ numScales ][];
 		for ( int l = 0; l < numScales; ++l )
 		{
 			mipmapResolutions[ l ] = new double[] { 1 << l, 1 << l, 1 };
+			mipmapTransforms[ l ] = MipmapTransforms.getMipmapTransformDefault( mipmapResolutions[ l ] );
 			imageDimensions[ l ] = new long[] { width >> l, height >> l, depth };
 			blockDimensions[ l ] = new int[] { tileWidth, tileHeight, 1 };
 		}
@@ -150,4 +156,10 @@ public class CatmaidImageLoader extends AbstractViewerImgLoader< ARGBType, Volat
 	{
 		return cache;
 	}
+
+	@Override
+	public AffineTransform3D[] getMipmapTransforms( final int setup )
+	{
+		return mipmapTransforms;
+	}
 }
diff --git a/src/main/java/bdv/img/hdf5/Hdf5ImageLoader.java b/src/main/java/bdv/img/hdf5/Hdf5ImageLoader.java
index 526891d2..f3992444 100644
--- a/src/main/java/bdv/img/hdf5/Hdf5ImageLoader.java
+++ b/src/main/java/bdv/img/hdf5/Hdf5ImageLoader.java
@@ -30,6 +30,7 @@ import bdv.img.cache.VolatileGlobalCellCache;
 import bdv.img.cache.VolatileGlobalCellCache.LoadingStrategy;
 import bdv.img.cache.VolatileImgCells;
 import bdv.img.cache.VolatileImgCells.CellCache;
+import bdv.util.MipmapTransforms;
 import ch.systemsx.cisd.hdf5.HDF5DataSetInformation;
 import ch.systemsx.cisd.hdf5.HDF5Factory;
 import ch.systemsx.cisd.hdf5.IHDF5Reader;
@@ -140,16 +141,7 @@ public class Hdf5ImageLoader extends AbstractViewerImgLoader< UnsignedShortType,
 
 			final AffineTransform3D[] mipmapTransforms = new AffineTransform3D[ mipmapResolutions.length ];
 			for ( int level = 0; level < mipmapResolutions.length; level++ )
-			{
-				final AffineTransform3D mipmapTransform = new AffineTransform3D();
-				final double[] resolution = mipmapResolutions[ level ];
-				for ( int d = 0; d < 3; ++d )
-				{
-					mipmapTransform.set( resolution[ d ], d, d );
-					mipmapTransform.set( 0.5 * ( resolution[ d ] - 1 ), d, 3 );
-				}
-				mipmapTransforms[ level ] = mipmapTransform;
-			}
+				mipmapTransforms[ level ] = MipmapTransforms.getMipmapTransformDefault( mipmapResolutions[ level ] );
 			perSetupMipmapTransforms.add( mipmapTransforms );
 
 			final int[][] subdivisions = hdf5Reader.readIntMatrix( getSubdivisionsPath( setup ) );
diff --git a/src/main/java/bdv/img/remote/RemoteImageLoader.java b/src/main/java/bdv/img/remote/RemoteImageLoader.java
index c6d93738..9046b782 100644
--- a/src/main/java/bdv/img/remote/RemoteImageLoader.java
+++ b/src/main/java/bdv/img/remote/RemoteImageLoader.java
@@ -28,6 +28,7 @@ import bdv.img.cache.VolatileGlobalCellCache;
 import bdv.img.cache.VolatileGlobalCellCache.LoadingStrategy;
 import bdv.img.cache.VolatileImgCells;
 import bdv.img.cache.VolatileImgCells.CellCache;
+import bdv.util.MipmapTransforms;
 
 import com.google.gson.Gson;
 
@@ -67,16 +68,7 @@ public class RemoteImageLoader extends AbstractViewerImgLoader< UnsignedShortTyp
 			final double[][] mipmapResolutions = metadata.perSetupMipmapResolutions.get( setup );
 			final AffineTransform3D[] mipmapTransforms = new AffineTransform3D[ mipmapResolutions.length ];
 			for ( int level = 0; level < mipmapResolutions.length; level++ )
-			{
-				final AffineTransform3D mipmapTransform = new AffineTransform3D();
-				final double[] resolution = mipmapResolutions[ level ];
-				for ( int d = 0; d < 3; ++d )
-				{
-					mipmapTransform.set( resolution[ d ], d, d );
-					mipmapTransform.set( 0.5 * ( resolution[ d ] - 1 ), d, 3 );
-				}
-				mipmapTransforms[ level ] = mipmapTransform;
-			}
+				mipmapTransforms[ level ] = MipmapTransforms.getMipmapTransformDefault( mipmapResolutions[ level ] );
 			perSetupMipmapTransforms.add( mipmapTransforms );
 		}
 		cellsDimensions = metadata.createCellsDimensions();
diff --git a/src/main/java/bdv/util/MipmapTransforms.java b/src/main/java/bdv/util/MipmapTransforms.java
new file mode 100644
index 00000000..cb4dd53b
--- /dev/null
+++ b/src/main/java/bdv/util/MipmapTransforms.java
@@ -0,0 +1,32 @@
+package bdv.util;
+
+import net.imglib2.realtransform.AffineTransform3D;
+
+public class MipmapTransforms
+{
+	/**
+	 * Compute the transformation (scale and shift) that maps from coordinates
+	 * in a down-scaled image to coordinates in the original image. This assumes
+	 * that each down-scaled pixel is the average of a block of blocks of pixels
+	 * in the original image. For down-scaling by a factor of 2, pixel (0,0,0)
+	 * in the down-scaled image is the average of the 8 pixel block from (0,0,0)
+	 * to (1,1,1) in the original image.
+	 *
+	 * @param resolution
+	 *            the down-scaling factors in each dimension. {4,4,2} means
+	 *            every pixel in the down-scaled image corresponds to a 4x4x2
+	 *            pixel block in the original image.
+	 * @return transformation from down-scaled image to original image.
+	 */
+	public static AffineTransform3D getMipmapTransformDefault( final double[] resolution )
+	{
+		assert resolution.length == 3;
+		final AffineTransform3D mipmapTransform = new AffineTransform3D();
+		for ( int d = 0; d < 3; ++d )
+		{
+			mipmapTransform.set( resolution[ d ], d, d );
+			mipmapTransform.set( 0.5 * ( resolution[ d ] - 1 ), d, 3 );
+		}
+		return mipmapTransform;
+	}
+}
-- 
GitLab