Skip to content

Commit

Permalink
add bbox methods specifying number of samples per dimension
Browse files Browse the repository at this point in the history
* fills spacing argument if few than numDims provided
  • Loading branch information
bogovicj committed Apr 12, 2022
1 parent 7997e19 commit d920a15
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 12 deletions.
96 changes: 86 additions & 10 deletions src/main/java/net/imglib2/util/RealIntervals.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package net.imglib2.util;

import java.util.Arrays;
import java.util.stream.IntStream;

import net.imglib2.FinalRealInterval;
import net.imglib2.RealInterval;
Expand Down Expand Up @@ -82,13 +81,15 @@ public static RealInterval boundingIntervalCorners( final RealInterval interval,
* the real interval
* @param transform
* the transformation
* @param steps
* step between samples
* @param spacing
* spacing between samples along each dimension
* @return the bounding interval
*/
public static RealInterval boundingIntervalFaces( final RealInterval interval, final RealTransform xfm, double... steps )
public static RealInterval boundingIntervalFaces( final RealInterval interval, final RealTransform transform, double... spacing )
{
final int nd = interval.numDimensions();
final double[] itSpacing = fillSpacing( nd, spacing ) ;

final double[] min = new double[ nd ];
final double[] max = new double[ nd ];
Arrays.fill( min, Double.MAX_VALUE );
Expand All @@ -102,16 +103,36 @@ public static RealInterval boundingIntervalFaces( final RealInterval interval, f
interval.realMax( itvlMax );
itvlMin[ i ] = interval.realMin( i );
itvlMax[ i ] = interval.realMin( i );
transformedCoordinateBounds( xfm, new LocalizingRealIntervalIterator( itvlMin, itvlMax, steps ), min, max );
transformedCoordinateBounds( transform, new LocalizingRealIntervalIterator( itvlMin, itvlMax, itSpacing ), min, max );

itvlMin[ i ] = interval.realMax( i );
itvlMax[ i ] = interval.realMax( i );
transformedCoordinateBounds( xfm, new LocalizingRealIntervalIterator( itvlMin, itvlMax, steps ), min, max );
transformedCoordinateBounds( transform, new LocalizingRealIntervalIterator( itvlMin, itvlMax, itSpacing ), min, max );
}

return new FinalRealInterval( min, max );
}

/**
* Estimate the {@link RealInterval} that bounds the given RealInterval
* after being transformed by a {@link RealTransform}.
* <p>
* This implementation estimates the bounding interval by transforming points
* on the faces of the given real interval.
*
* @param interval
* the real interval
* @param transform
* the transformation
* @param numSamples
* number of samples per dimension
* @return the bounding interval
*/
public static RealInterval boundingIntervalFacesSamples( final RealInterval interval, final RealTransform transform, int... numSamples )
{
return boundingIntervalFaces( interval, transform, stepsFromSamples( interval, numSamples ));
}

/**
* Estimate the {@link RealInterval} that bounds the given RealInterval
* after being transformed by a {@link RealTransform}.
Expand All @@ -123,23 +144,47 @@ public static RealInterval boundingIntervalFaces( final RealInterval interval, f
* the real interval
* @param transform
* the transformation
* @param steps
* step between samples
* @param spacing
* spacing between samples along each dimension
* @return the bounding interval
*/
public static RealInterval boundingIntervalVolume(
final RealInterval interval, final RealTransform transform, double... steps )
final RealInterval interval, final RealTransform transform, double... spacing )
{
int nd = interval.numDimensions();
final double[] itSpacing = fillSpacing( nd, spacing ) ;

double[] min = new double[ nd ];
double[] max = new double[ nd ];
Arrays.fill( min, Long.MAX_VALUE );
Arrays.fill( max, Long.MIN_VALUE );
final LocalizingRealIntervalIterator it = new LocalizingRealIntervalIterator( interval, steps );
final LocalizingRealIntervalIterator it = new LocalizingRealIntervalIterator( interval, itSpacing );
transformedCoordinateBounds( transform, it, min, max );
return new FinalRealInterval( min, max );
}

/**
* Estimate the {@link RealInterval} that bounds the given RealInterval
* after being transformed by a {@link RealTransform}.
* <p>
* This implementation estimates the bounding interval by transforming
* points in the volume of the given real interval.
*
* @param interval
* the real interval
* @param transform
* the transformation
* @param numSamples
* the number of samples per dimension
* @return the bounding interval
*/
public static RealInterval boundingIntervalVolumeSamples(
final RealInterval interval, final RealTransform transform, int... numSamples )
{
return boundingIntervalVolume( interval, transform, stepsFromSamples( interval, numSamples ));

}

/**
* Transforms all points produced by the {@link LocalizingRealIntervalIterator}
* with the provided {@link RealTransform} and stores the min and max coordinates
Expand Down Expand Up @@ -176,4 +221,35 @@ protected static void transformedCoordinateBounds(
}
}

private static double[] fillSpacing( int nd, double... spacing )
{
final double[] out;
if( spacing.length >= nd )
out = spacing;
else
{
out = new double[ nd ];
for( int i = 0; i < nd; i++ )
if( i < spacing.length )
out[i] = spacing[ i ];
else
out[i] = spacing[ spacing.length - 1 ];
}
return out;
}

private static double[] stepsFromSamples( final RealInterval interval , int... numSamples )
{
final double[] out = new double[ interval.numDimensions() ];
for( int i = 0; i < out.length; i++ )
{
final double w = interval.realMax( i ) - interval.realMin( i );
if( i < numSamples.length )
out[i] = w / numSamples[ i ];
else
out[i] = w / numSamples[ numSamples.length - 1 ];
}
return out;
}

}
24 changes: 22 additions & 2 deletions src/test/java/net/imglib2/util/RealIntervalsTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void testBboxVolumeAffine()
final AffineTransform3D xfm = new AffineTransform3D();
xfm.scale(2, 3, 4);

final RealInterval bbox = RealIntervals.boundingIntervalVolume( itvl, xfm, 10, 10, 10 );
final RealInterval bbox = RealIntervals.boundingIntervalVolume( itvl, xfm, 10 );
assertEquals( "max x ", itvl.realMax(0) * 2, bbox.realMax(0), EPS );
assertEquals( "max y ", itvl.realMax(1) * 3, bbox.realMax(1), EPS );
assertEquals( "max z ", itvl.realMax(2) * 4, bbox.realMax(2), EPS );
Expand Down Expand Up @@ -85,13 +85,23 @@ public void testBboxFacesPfield()

assertEquals( "min z ", itvl.realMin(2), bbox.realMin(2), EPS );
assertEquals( "max z ", itvl.realMax(2), bbox.realMax(2), EPS );

final RealInterval bboxSamples = RealIntervals.boundingIntervalFacesSamples( itvl, xfm, 8, 6, 4 );
assertEquals( "min x ", itvl.realMin(0), bboxSamples.realMin(0), EPS );
assertEquals( "max x ", itvl.realMax(0) + 5, bboxSamples.realMax(0), EPS );

assertEquals( "min y ", itvl.realMin(1) - 5, bboxSamples.realMin(1), EPS );
assertEquals( "max y ", itvl.realMax(1), bboxSamples.realMax(1), EPS );

assertEquals( "min z ", itvl.realMin(2), bboxSamples.realMin(2), EPS );
assertEquals( "max z ", itvl.realMax(2), bboxSamples.realMax(2), EPS );
}

@Test
public void testBboxVolumePfield()
{
final PositionFieldTransform<DoubleType> xfm = pfield();
final RealInterval bbox = RealIntervals.boundingIntervalVolume( itvl, xfm, 5, 5, 5 );
final RealInterval bbox = RealIntervals.boundingIntervalVolume( itvl, xfm, 5 );
assertEquals( "min x ", itvl.realMin(0), bbox.realMin(0), EPS );
assertEquals( "max x ", itvl.realMax(0) + 5, bbox.realMax(0), EPS );

Expand All @@ -100,6 +110,16 @@ public void testBboxVolumePfield()

assertEquals( "min z ", itvl.realMin(2), bbox.realMin(2), EPS );
assertEquals( "max z ", itvl.realMax(2), bbox.realMax(2), EPS );

final RealInterval bboxSamples = RealIntervals.boundingIntervalVolumeSamples( itvl, xfm, 8, 6, 4 );
assertEquals( "min x samples", itvl.realMin(0), bboxSamples.realMin(0), EPS );
assertEquals( "max x samples", itvl.realMax(0) + 5, bboxSamples.realMax(0), EPS );

assertEquals( "min y samples", itvl.realMin(1) - 5, bboxSamples.realMin(1), EPS );
assertEquals( "max y samples", itvl.realMax(1), bboxSamples.realMax(1), EPS );

assertEquals( "min z samples", itvl.realMin(2), bboxSamples.realMin(2), EPS );
assertEquals( "max z samples", itvl.realMax(2), bboxSamples.realMax(2), EPS );
}

private static PositionFieldTransform< DoubleType > pfield()
Expand Down

0 comments on commit d920a15

Please sign in to comment.