Skip to content
Snippets Groups Projects
Commit c6aa04f1 authored by Igor Pisarev's avatar Igor Pisarev Committed by tpietzsch
Browse files

Fix determining best mipmap level for non-isotropic data (#54)

Fix determining mipmap level for non-isotropic data, by mapping screen pixel into source space
parent b60e6079
No related branches found
No related tags found
No related merge requests found
......@@ -162,7 +162,7 @@ public class ProposeMipmaps
}
/**
* Adjust voxelSize such that the largest dimension is 1.0
* Adjust voxelSize such that the smallest dimension is 1.0
*
* @param size
*/
......
......@@ -107,6 +107,47 @@ public class MipmapTransforms
return pixelSize;
}
/**
* Compute the size of the backprojected screen pixel in the {@link Source} space.
* Take a screen pixel (0,0)-(1,1) and transform it into the
* source coordinate system at the given mipmap level and screen scale,
* then compute the length of the resulting vectors.
*
* @param screenTransform
* transforms screen coordinates to global coordinates.
* @param source
* the source
* @param timepoint
* for which timepoint to query the source
* @param mipmapIndex
* mipmap level
* @return pixel size
*/
public static double[] getPixelSourceSize( final AffineTransform3D screenTransform, final Source< ? > source, final int timepoint, final int mipmapIndex )
{
final double[] sourcePixelSize = new double[ 2 ];
final AffineTransform3D sourceToScreen = new AffineTransform3D();
sourceToScreen.set( screenTransform );
final AffineTransform3D sourceTransform = new AffineTransform3D();
source.getSourceTransform( timepoint, mipmapIndex, sourceTransform );
sourceToScreen.concatenate( sourceTransform );
final double[] zero = new double[] { 0, 0, 0 };
final double[] tzero = new double[ 3 ];
final double[] one = new double[ 3 ];
final double[] tone = new double[ 3 ];
final double[] diff = new double[ 3 ];
sourceToScreen.applyInverse( tzero, zero );
for ( int i = 0; i < 2; ++i )
{
for ( int d = 0; d < 3; ++d )
one[ d ] = d == i ? 1 : 0;
sourceToScreen.applyInverse( tone, one );
LinAlgHelpers.subtract( tone, tzero, diff );
sourcePixelSize[ i ] = LinAlgHelpers.length( diff );
}
return sourcePixelSize;
}
/**
* Get the mipmap level that best matches the given screen scale for the
* given source. Assumes that mipmap indices in the source are ordered by
......@@ -122,20 +163,19 @@ public class MipmapTransforms
*/
public static int getBestMipMapLevel( final AffineTransform3D screenTransform, final Source< ? > source, final int timepoint )
{
int targetLevel = source.getNumMipmapLevels() - 1;
for ( int level = targetLevel - 1; level >= 0; level-- )
final int numLevels = source.getNumMipmapLevels();
final double[] bestPixelSourceSize = new double[] { 1, 1 };
int targetLevel = numLevels;
double minDist = Double.POSITIVE_INFINITY;
for ( int level = 0; level < numLevels; ++level )
{
if ( getVoxelScreenSize( screenTransform, source, timepoint, level ) >= 0.99 /* 1.0 */)
final double[] pixelSourceSize = getPixelSourceSize( screenTransform, source, timepoint, level );
final double dist = LinAlgHelpers.squareDistance( pixelSourceSize, bestPixelSourceSize );
if ( minDist > dist )
{
minDist = dist;
targetLevel = level;
else
break;
}
if ( targetLevel > 0 )
{
final double size1 = getVoxelScreenSize( screenTransform, source, timepoint, targetLevel );
final double size0 = getVoxelScreenSize( screenTransform, source, timepoint, targetLevel - 1 );
if ( Math.abs( size1 - 1.0 ) / 2 > Math.abs( size0 - 1.0 ) )
targetLevel--;
}
}
return targetLevel;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment