forked from bigdataviewer/bigdataviewer-vistools
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request bigdataviewer#33 from haesleinhuepf/samples
add sample sources (mandelbrot / wave / voronoi) + command to display…
- Loading branch information
Showing
7 changed files
with
360 additions
and
3 deletions.
There are no files selected for viewing
56 changes: 56 additions & 0 deletions
56
src/main/java/sc/fiji/bdvpg/command/BdvAppendSampleCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package sc.fiji.bdvpg.command; | ||
|
||
import bdv.util.BdvHandle; | ||
import bdv.viewer.Source; | ||
import org.scijava.ItemIO; | ||
import org.scijava.command.Command; | ||
import org.scijava.plugin.Parameter; | ||
import org.scijava.plugin.Plugin; | ||
import sc.fiji.bdvpg.bdv.source.append.AddSourceToBdv; | ||
import sc.fiji.bdvpg.bdv.source.displayopts.BrightnessAdjuster; | ||
import sc.fiji.bdvpg.log.SystemLogger; | ||
import sc.fiji.bdvpg.scijava.ScijavaBdvDefaults; | ||
import sc.fiji.bdvpg.source.importer.samples.MandelbrotSourceGetter; | ||
import sc.fiji.bdvpg.source.importer.samples.VoronoiSourceGetter; | ||
import sc.fiji.bdvpg.source.importer.samples.Wave3DSourceGetter; | ||
|
||
@Plugin(type = Command.class, menuPath = ScijavaBdvDefaults.RootMenu+"Tools>Append Sample Source to Bdv Window") | ||
public class BdvAppendSampleCommand implements Command { | ||
|
||
@Parameter(type = ItemIO.BOTH) | ||
BdvHandle bdvh; | ||
|
||
@Parameter(choices = {"Mandelbrot", "Wave3D", "Voronoi", "Big Voronoi"}) | ||
String sampleName; | ||
|
||
@Override | ||
public void run() { | ||
Source src; | ||
switch(sampleName) { | ||
|
||
case "Mandelbrot": | ||
src = (new MandelbrotSourceGetter()).get(); | ||
break; | ||
|
||
case "Wave3D": | ||
src = (new Wave3DSourceGetter()).get(); | ||
break; | ||
|
||
case "Voronoi": | ||
src = (new VoronoiSourceGetter(new long[]{512,512,1}, 256, true).get()); | ||
break; | ||
|
||
case "Big Voronoi": | ||
src = (new VoronoiSourceGetter(new long[]{2048,2048,2048}, 65536, false).get()); | ||
break; | ||
|
||
default: | ||
new SystemLogger().err("Invalid sample name"); | ||
return; | ||
} | ||
new AddSourceToBdv(bdvh, src).run(); | ||
|
||
// DO NOT WORK | ||
//new BrightnessAdjuster(bdvh, src, 0.01, 0.99).run(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
src/main/java/sc/fiji/bdvpg/source/importer/samples/MandelbrotSourceGetter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package sc.fiji.bdvpg.source.importer.samples; | ||
|
||
import bdv.viewer.Source; | ||
import net.imglib2.FinalInterval; | ||
|
||
import java.util.function.Supplier; | ||
|
||
public class MandelbrotSourceGetter implements Runnable, Supplier<Source> { | ||
|
||
int maxIterations = 255; | ||
|
||
public void run() { | ||
// Useless | ||
} | ||
|
||
@Override | ||
public Source get() { | ||
return new Procedural3DImageShort( | ||
p -> { | ||
double re = p[0]; | ||
double im = p[1]; | ||
int i = 0; | ||
for ( ; i < maxIterations; ++i ) | ||
{ | ||
final double squre = re * re; | ||
final double squim = im * im; | ||
if ( squre + squim > 4 ) | ||
break; | ||
im = 2 * re * im + p[1]; | ||
re = squre - squim + p[0]; | ||
} | ||
return i; | ||
} | ||
).getSource(new FinalInterval(new long[]{ -2, -1, -0}, new long[]{ 1, 1, 0 }), "Mandelbrot Set"); | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
src/main/java/sc/fiji/bdvpg/source/importer/samples/Procedural3DImageShort.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package sc.fiji.bdvpg.source.importer.samples; | ||
|
||
import bdv.util.RealRandomAccessibleIntervalSource; | ||
import bdv.viewer.Source; | ||
import net.imglib2.*; | ||
import net.imglib2.realtransform.AffineTransform3D; | ||
import net.imglib2.type.numeric.integer.UnsignedShortType; | ||
|
||
import java.util.function.ToIntFunction; | ||
|
||
public class Procedural3DImageShort extends RealPoint implements RealRandomAccess<UnsignedShortType> { | ||
final UnsignedShortType t; | ||
|
||
ToIntFunction<double[]> evalFunction; | ||
|
||
public Procedural3DImageShort(ToIntFunction<double[]> evalFunction) | ||
{ | ||
super( 3 ); // number of dimensions is 3 | ||
t = new UnsignedShortType(); | ||
this.evalFunction=evalFunction; | ||
} | ||
|
||
public Procedural3DImageShort(UnsignedShortType t) { | ||
this.t = t; | ||
} | ||
|
||
@Override | ||
public RealRandomAccess<UnsignedShortType> copyRealRandomAccess() { | ||
return copy(); | ||
} | ||
|
||
@Override | ||
public UnsignedShortType get() { | ||
t.set( | ||
evalFunction.applyAsInt(position) | ||
); | ||
return t; | ||
} | ||
|
||
@Override | ||
public Procedural3DImageShort copy() { | ||
Procedural3DImageShort a = new Procedural3DImageShort(evalFunction); | ||
a.setPosition( this ); | ||
return a; | ||
} | ||
|
||
public RealRandomAccessible<UnsignedShortType> getRRA() { | ||
|
||
RealRandomAccessible<UnsignedShortType> rra = new RealRandomAccessible<UnsignedShortType>() { | ||
@Override | ||
public RealRandomAccess<UnsignedShortType> realRandomAccess() { | ||
return copy(); | ||
} | ||
|
||
@Override | ||
public RealRandomAccess<UnsignedShortType> realRandomAccess(RealInterval realInterval) { | ||
return copy(); | ||
} | ||
|
||
@Override | ||
public int numDimensions() { | ||
return 3; | ||
} | ||
}; | ||
|
||
return rra; | ||
} | ||
|
||
public Source<UnsignedShortType> getSource(final Interval interval, AffineTransform3D at3D, String name) { | ||
return new RealRandomAccessibleIntervalSource<>( getRRA(), interval, new UnsignedShortType(), | ||
new AffineTransform3D(), name ); | ||
} | ||
|
||
public Source<UnsignedShortType> getSource(final Interval interval, String name) { | ||
return new RealRandomAccessibleIntervalSource<>( getRRA(), interval, new UnsignedShortType(), | ||
new AffineTransform3D(), name ); | ||
} | ||
|
||
public Source<UnsignedShortType> getSource(String name) { | ||
return new RealRandomAccessibleIntervalSource<>( getRRA(), new FinalInterval(new long[]{0,0,0}, new long[]{1,1,1}), new UnsignedShortType(), | ||
new AffineTransform3D(), name ); | ||
} | ||
|
||
|
||
} |
160 changes: 160 additions & 0 deletions
160
src/main/java/sc/fiji/bdvpg/source/importer/samples/VoronoiSourceGetter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package sc.fiji.bdvpg.source.importer.samples; | ||
|
||
import bdv.util.RandomAccessibleIntervalSource; | ||
import bdv.viewer.Source; | ||
import net.imglib2.*; | ||
import net.imglib2.algorithm.util.Grids; | ||
import net.imglib2.img.array.ArrayImgFactory; | ||
import net.imglib2.interpolation.neighborsearch.NearestNeighborSearchInterpolatorFactory; | ||
import net.imglib2.neighborsearch.NearestNeighborSearch; | ||
import net.imglib2.neighborsearch.NearestNeighborSearchOnKDTree; | ||
import net.imglib2.realtransform.AffineTransform3D; | ||
import net.imglib2.type.Type; | ||
import net.imglib2.type.numeric.real.FloatType; | ||
import net.imglib2.util.Util; | ||
import net.imglib2.view.Views; | ||
|
||
import java.util.Random; | ||
import java.util.function.Supplier; | ||
|
||
public class VoronoiSourceGetter implements Runnable, Supplier<Source> { | ||
|
||
// Size of the image in pixels | ||
final long[] imgSize; | ||
// Number of random points that will define voronoi cells | ||
final int numPts; | ||
// Flags if the image should be computed completely | ||
final boolean copyImg; | ||
|
||
public VoronoiSourceGetter(final long[] imgSize, int numPts, boolean copyImg) { | ||
this.imgSize = imgSize; | ||
this.numPts = numPts; | ||
this.copyImg = copyImg; | ||
} | ||
|
||
public void run() { | ||
// Useless | ||
} | ||
|
||
@Override | ||
public Source get() { | ||
RandomAccessibleInterval voronoi = getVoronoiTestLabelImage(imgSize, numPts, copyImg); | ||
return new RandomAccessibleIntervalSource<>( voronoi, new FloatType(), new AffineTransform3D(), "Voronoi_"+numPts+" Pts_["+imgSize[0]+","+imgSize[1]+","+imgSize[2]+"]" ); | ||
} | ||
|
||
public static RandomAccessibleInterval<FloatType> getVoronoiTestLabelImage(final long[] imgTestSize, int numPts, boolean copyImg) { | ||
|
||
// the interval in which to create random points | ||
FinalInterval interval = new FinalInterval( imgTestSize ); | ||
|
||
// create an IterableRealInterval | ||
IterableRealInterval< FloatType > realInterval = createRandomPoints( interval, numPts ); | ||
|
||
// using nearest neighbor search we will be able to return a value an any position in space | ||
NearestNeighborSearch< FloatType > search = | ||
new NearestNeighborSearchOnKDTree<>( | ||
new KDTree<>( realInterval ) ); | ||
|
||
// make it into RealRandomAccessible using nearest neighbor search | ||
RealRandomAccessible< FloatType > realRandomAccessible = | ||
Views.interpolate( search, new NearestNeighborSearchInterpolatorFactory< FloatType >() ); | ||
|
||
// convert it into a RandomAccessible which can be displayed | ||
RandomAccessible< FloatType > randomAccessible = Views.raster( realRandomAccessible ); | ||
|
||
// set the initial interval as area to view | ||
RandomAccessibleInterval< FloatType > labelImage = Views.interval( randomAccessible, interval ); | ||
|
||
if (copyImg) { | ||
final RandomAccessibleInterval< FloatType > labelImageCopy = new ArrayImgFactory( Util.getTypeFromInterval( labelImage ) ).create( labelImage ); | ||
|
||
// Image copied to avoid computing it on the fly | ||
// https://github.com/imglib/imglib2-algorithm/blob/47cd6ed5c97cca4b316c92d4d3260086a335544d/src/main/java/net/imglib2/algorithm/util/Grids.java#L221 used for parallel copy | ||
|
||
Grids.collectAllContainedIntervals(imgTestSize, new int[]{64, 64, 64}).stream().forEach(blockinterval -> { | ||
copy(labelImage, Views.interval(labelImageCopy, blockinterval)); | ||
}); | ||
|
||
// Alternative non parallel copy | ||
//LoopBuilder.setImages(labelImage, labelImageCopy).forEachPixel(Type::set); | ||
return labelImageCopy; | ||
|
||
} else { | ||
|
||
return labelImage; | ||
} | ||
} | ||
|
||
/** | ||
* Copy from a source that is just RandomAccessible to an IterableInterval. Latter one defines | ||
* size and location of the copy operation. It will query the same pixel locations of the | ||
* IterableInterval in the RandomAccessible. It is up to the developer to ensure that these | ||
* coordinates match. | ||
* | ||
* Note that both, input and output could be Views, Img or anything that implements | ||
* those interfaces. | ||
* | ||
* @param source - a RandomAccess as source that can be infinite | ||
* @param target - an IterableInterval as target | ||
*/ | ||
public static < T extends Type< T >> void copy(final RandomAccessible< T > source, | ||
final IterableInterval< T > target ) | ||
{ | ||
// create a cursor that automatically localizes itself on every move | ||
Cursor< T > targetCursor = target.localizingCursor(); | ||
RandomAccess< T > sourceRandomAccess = source.randomAccess(); | ||
|
||
// iterate over the input cursor | ||
while ( targetCursor.hasNext()) | ||
{ | ||
// move input cursor forward | ||
targetCursor.fwd(); | ||
|
||
// set the output cursor to the position of the input cursor | ||
sourceRandomAccess.setPosition( targetCursor ); | ||
|
||
// set the value of this pixel of the output image, every Type supports T.set( T type ) | ||
targetCursor.get().set( sourceRandomAccess.get() ); | ||
} | ||
|
||
} | ||
|
||
/** | ||
* Create a number of n-dimensional random points in a certain interval | ||
* having a random intensity 0...1 | ||
* | ||
* @param interval - the interval in which points are created | ||
* @param numPoints - the amount of points | ||
* | ||
* @return a RealPointSampleList (which is an IterableRealInterval) | ||
*/ | ||
public static RealPointSampleList< FloatType > createRandomPoints( | ||
RealInterval interval, int numPoints ) | ||
{ | ||
// the number of dimensions | ||
int numDimensions = interval.numDimensions(); | ||
|
||
// a random number generator | ||
Random rnd = new Random( 2001);//System.currentTimeMillis() ); | ||
|
||
// a list of Samples with coordinates | ||
RealPointSampleList< FloatType > elements = | ||
new RealPointSampleList<>( numDimensions ); | ||
|
||
for ( int i = 0; i < numPoints; ++i ) | ||
{ | ||
RealPoint point = new RealPoint( numDimensions ); | ||
|
||
for ( int d = 0; d < numDimensions; ++d ) | ||
point.setPosition( rnd.nextDouble() * | ||
( interval.realMax( d ) - interval.realMin( d ) ) + interval.realMin( d ), d ); | ||
|
||
// add a new element with a random intensity in the range 0...1 | ||
elements.add( point, new FloatType( rnd.nextFloat()*255 ) ); | ||
} | ||
|
||
return elements; | ||
} | ||
|
||
|
||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/sc/fiji/bdvpg/source/importer/samples/Wave3DSourceGetter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package sc.fiji.bdvpg.source.importer.samples; | ||
|
||
import bdv.viewer.Source; | ||
|
||
import java.util.function.Supplier; | ||
|
||
public class Wave3DSourceGetter implements Runnable, Supplier<Source> { | ||
|
||
@Override | ||
public void run() { | ||
// Useless | ||
} | ||
|
||
@Override | ||
public Source get() { | ||
return new Procedural3DImageShort( | ||
p -> (int) ((Math.sin(p[0]/20)*Math.sin(p[1]/40)*Math.sin(p[2]/5)+1)*100) | ||
).getSource("Wave 3D"); | ||
} | ||
} |