Skip to content

Instantly share code, notes, and snippets.

@tpietzsch
Created April 19, 2012 19:30
Show Gist options
  • Save tpietzsch/2423490 to your computer and use it in GitHub Desktop.
Save tpietzsch/2423490 to your computer and use it in GitHub Desktop.
variations on Ignacios MinimumFilter example
import ij.ImageJ;
import ij.ImagePlus;
import ij.io.Opener;
import java.io.File;
import java.util.ArrayList;
import net.imglib2.Cursor;
import net.imglib2.ExtendedRandomAccessibleInterval;
import net.imglib2.FinalInterval;
import net.imglib2.Interval;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.algorithm.region.hypersphere.HyperSphere;
import net.imglib2.algorithm.region.hypersphere.HyperSphereCursor;
import net.imglib2.img.ImagePlusAdapter;
import net.imglib2.img.Img;
import net.imglib2.img.display.imagej.ImageJFunctions;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.view.Views;
public class MinimumFilter
{
private final Img< FloatType > image;
private final Img< FloatType > output;
private final long sigma;
public MinimumFilter( final long sigma )
{
// define the file to open
final File file = new File( "/home/tobias/flybrain-32bit.tif" );
// open a file with ImageJ
final ImagePlus imp = new Opener().openImage( file.getAbsolutePath() );
// display it via ImageJ
// imp.show();
// wrap it into an ImgLib image (no copying)
image = ImagePlusAdapter.wrap( imp );
// create a new Image with the same properties
output = image.factory().create( image, image.firstElement() );
this.sigma = sigma;
}
public void run()
{
// get mirror view
final ExtendedRandomAccessibleInterval< FloatType, Img< FloatType >> infinite = Views.extendMirrorSingle( image );
final Cursor< FloatType > cursorInput = image.cursor();
final Cursor< FloatType > cursorOutput = output.cursor();
final FloatType min = image.firstElement().createVariable();
// iterate over the input
while ( cursorInput.hasNext() )
{
cursorInput.fwd();
cursorOutput.fwd();
// define a hypersphere (n-dimensional sphere)
final HyperSphere< FloatType > hyperSphere = new HyperSphere< FloatType >( infinite, cursorInput, sigma );
// create a cursor on the hypersphere
final HyperSphereCursor< FloatType > cursor2 = hyperSphere.cursor();
cursor2.fwd();
min.set( cursor2.get() );
while ( cursor2.hasNext() )
{
cursor2.fwd();
if ( cursor2.get().compareTo( min ) <= 0 )
min.set( cursor2.get() );
}
// set the value of this pixel of the output image to the minimum
// value of the sphere
cursorOutput.get().set( min );
}
}
public void run2()
{
// get mirror view
final ExtendedRandomAccessibleInterval< FloatType, Img< FloatType >> infinite = Views.extendMirrorSingle( image );
final Cursor< FloatType > cursorInput = image.localizingCursor();
final Cursor< FloatType > cursorOutput = output.cursor();
final FloatType min = new FloatType();
// define a hypersphere (n-dimensional sphere)
final HyperSphere< FloatType > hyperSphere = new HyperSphere< FloatType >( infinite, cursorInput, sigma );
// create a cursor on the hypersphere
final HyperSphereCursor< FloatType > cursor2 = hyperSphere.cursor();
// iterate over the input
while ( cursorInput.hasNext() )
{
cursorInput.fwd();
cursorOutput.fwd();
hyperSphere.updateCenter( cursorInput );
cursor2.reset();
min.set( cursor2.next() );
while ( cursor2.hasNext() )
{
cursor2.fwd();
if ( cursor2.get().compareTo( min ) <= 0 )
min.set( cursor2.get() );
}
// set the value of this pixel of the output image to the minimum
// value of the sphere
cursorOutput.next().set( min );
}
}
public void run3()
{
// get mirror view
final ExtendedRandomAccessibleInterval< FloatType, Img< FloatType >> infinite = Views.extendMirrorSingle( image );
final Cursor< FloatType > cursorOutput = output.localizingCursor();
final FloatType min = new FloatType();
// define a hypersphere (n-dimensional sphere)
final HyperSphere< FloatType > hyperSphere = new HyperSphere< FloatType >( infinite, cursorOutput, sigma );
// create a cursor on the hypersphere
final HyperSphereCursor< FloatType > cursor2 = hyperSphere.cursor();
// iterate over the input
while ( cursorOutput.hasNext() )
{
cursorOutput.fwd();
hyperSphere.updateCenter( cursorOutput );
cursor2.reset();
min.set( cursor2.next() );
while ( cursor2.hasNext() )
{
cursor2.fwd();
if ( cursor2.get().compareTo( min ) <= 0 )
min.set( cursor2.get() );
}
// set the value of this pixel of the output image to the minimum
// value of the sphere
cursorOutput.get().set( min );
}
}
public Interval shrink( final Interval interval, final long border )
{
final int n = interval.numDimensions();
final long[] min = new long[ n ];
final long[] max = new long[ n ];
interval.min( min );
interval.max( max );
for ( int d = 0; d < n; ++d )
{
min[ d ] += border;
max[ d ] -= border;
}
return new FinalInterval( min, max );
}
public Interval expand( final Interval interval, final long border )
{
final int n = interval.numDimensions();
final long[] min = new long[ n ];
final long[] max = new long[ n ];
interval.min( min );
interval.max( max );
for ( int d = 0; d < n; ++d )
{
min[ d ] -= border;
max[ d ] += border;
}
return new FinalInterval( min, max );
}
private ArrayList< Interval > splitCenterBordersRecursively( final Interval interval, final long border, final int d, final ArrayList< Interval > intervals )
{
if ( d >= 0 )
{
final int n = interval.numDimensions();
final long[] min = new long[ n ];
final long[] max = new long[ n ];
interval.min( min );
interval.max( max );
min[ d ] = interval.min( d );
max[ d ] = interval.min( d ) + border - 1;
intervals.add( new FinalInterval( min, max ) );
min[ d ] = interval.max( d ) - border + 1;
max[ d ] = interval.max( d );
intervals.add( new FinalInterval( min, max ) );
max[ d ] = interval.max( d ) - border;
min[ d ] = interval.min( d ) + border;
return splitCenterBordersRecursively( new FinalInterval( min, max ), border, d - 1, intervals );
}
intervals.add( interval );
return intervals;
}
public ArrayList< Interval > splitCenterBorders( final Interval interval, final long border )
{
return splitCenterBordersRecursively( interval, border, interval.numDimensions() - 1, new ArrayList< Interval >() );
}
public void run4()
{
// get mirror view
final ExtendedRandomAccessibleInterval< FloatType, Img< FloatType >> infinite = Views.extendMirrorSingle( image );
// split output into regions which require out-of-bounds and regions
// which don't
final long border = sigma + 1;
final ArrayList< Interval > outputIntervals = splitCenterBorders( output, border );
for ( final Interval outputInterval : outputIntervals )
{
// take the input interval (only the region which we will access)
// out of infinite
// it needs additional border pixels, therefore expand()...
// HyperSphere will get a randomAccess() from inputView and Views
// will decide whether out-of-bounds is required or not.
final RandomAccessibleInterval< FloatType > inputView = Views.interval( infinite, expand( outputInterval, border ) );
final Cursor< FloatType > cursorOutput = Views.iterable( Views.interval( output, outputInterval ) ).localizingCursor();
final FloatType min = new FloatType();
// define a hypersphere (n-dimensional sphere)
final HyperSphere< FloatType > hyperSphere = new HyperSphere< FloatType >( inputView, cursorOutput, sigma );
// create a cursor on the hypersphere
final HyperSphereCursor< FloatType > cursor2 = hyperSphere.cursor();
// iterate over the input
while ( cursorOutput.hasNext() )
{
cursorOutput.fwd();
hyperSphere.updateCenter( cursorOutput );
cursor2.reset();
min.set( cursor2.next() );
while ( cursor2.hasNext() )
{
cursor2.fwd();
if ( cursor2.get().compareTo( min ) <= 0 )
min.set( cursor2.get() );
}
// set the value of this pixel of the output image to the
// minimum
// value of the sphere
cursorOutput.get().set( min );
}
}
}
public void show()
{
// display it via ImgLib using ImageJ
ImageJFunctions.show( output );
}
public static void main( final String[] args )
{
// open an ImageJ window
new ImageJ();
for ( long l = 1; l <= 16; l *= 2 )
{
final MinimumFilter filter = new MinimumFilter( l );
final long start = System.currentTimeMillis();
// run the example
filter.run4();
final long end = System.currentTimeMillis();
filter.show();
System.out.println( "Minimum filter with sigma = " + l + " took " + ( end - start ) + "ms." );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment