diff --git a/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/Unbinning.java b/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/Unbinning.java new file mode 100644 index 0000000000000000000000000000000000000000..a459cd24caccc9d677e90345d92c0d80cbda98ba --- /dev/null +++ b/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/Unbinning.java @@ -0,0 +1,139 @@ +package fr.pasteur.ida.zellige.steps.selection.util; + +import io.scif.img.ImgOpener; +import net.imagej.ImageJ; +import net.imglib2.RandomAccess; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.img.Img; +import net.imglib2.img.ImgFactory; +import net.imglib2.img.display.imagej.ImageJFunctions; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.RealType; +import net.imglib2.type.numeric.integer.UnsignedByteType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static fr.pasteur.ida.zellige.steps.Utils.setPosition; +import static fr.pasteur.ida.zellige.steps.Utils.setPositionAndGet; + +/** + * Generates an unbinned image, according to the input image and bin value. Only for 2D images. + * @param <T> the image type + */ +public class Unbinning< T extends RealType< T > & NativeType< T > > +{ + private final static Logger LOGGER = LoggerFactory.getLogger( Unbinning.class ); + private final Img< T > output; + private final RandomAccessibleInterval< T > binned; + private final int bin; + + + /** + * + * @param input a binned image + * @param factory the input image factory + * @param bin the bin size + * @return the input image unbinned + * @param <T> input and output image type + */ + public static < T extends RealType< T > & NativeType< T> > Img<T> run( RandomAccessibleInterval<T> input, ImgFactory<T> factory, int bin) + { + Img <T> output = factory.create( input.dimension( 0 ) * bin, input.dimension( 1 ) * bin); + Unbinning<T> unbinning = new Unbinning<>( input, bin, output ); + unbinning.run(); + return output; + } + + /** + * Constructor + * @param input a binned image + * @param bin the bin size + * @param output he input image unbinned + */ + public Unbinning( RandomAccessibleInterval< T > input, int bin, Img< T > output ) + { + this.binned = input; + this.bin = bin; + this.output = output; + } + + /** + * Parses the binned image and assign the corresponding values to the unbinned image. + */ + public void run() + { + LOGGER.debug( "Starting process..." ); + + double startTime = System.currentTimeMillis(); + + RandomAccess<T> binnedAccess = binned.randomAccess(); + RandomAccess<T> outputAccess = output.randomAccess(); + + for ( int y = 0; y < binned.dimension( 1 ) ; y++ ) + { + for ( int x = 0; x < binned.dimension( 0 ); x ++) + { + T value = setPositionAndGet( binnedAccess, x, y ); + applyValueToGrid( x, y, bin, outputAccess, value); + } + } + double endTime = System.currentTimeMillis(); + + LOGGER.debug( "Process completed in {}s" , (endTime-startTime)/1000); + } + + + /** + * + * @param X the starting x value + * @param Y the starting y value + * @param bin the bin size + * @param access the unbinned image {@link RandomAccess<T>} + * @param value the pixel value to assign + */ + private void applyValueToGrid( int X, int Y, int bin, RandomAccess< T > access, T value ) + { + for ( int y = Y * bin; y < Y * bin + bin; y++ ) + { + for ( int x = X * bin; x < X * bin + bin; x++ ) + { + setPosition( access, x, y ); + access.get().set( value ); + } + } + + } + + public static void main( String[] args ) + { + ImageJ ij = new ImageJ(); + ij.launch( args ); + final ImgOpener io = new ImgOpener(); + @SuppressWarnings( "unchecked" ) final Img< UnsignedByteType > kernel = ( Img< UnsignedByteType > ) io.openImgs( "doc/Scan1_volume_crop.tif" ).get( 0 ); + ImageJFunctions.show( kernel, "original" ); + double time1 = System.currentTimeMillis(); + int bin = 4; + Img< UnsignedByteType > output = Binning.binning( kernel, bin); + double time2 = System.currentTimeMillis(); + LOGGER.debug( "Multithreading time = {}s", ( time2 - time1 ) / 1000 ); + assert output != null; + ImageJFunctions.show( output, "output " ); + + Img<UnsignedByteType> i =kernel.factory().create( output.dimension( 0 ), output.dimension(1) ); + RandomAccess<UnsignedByteType> access = i.randomAccess(); + RandomAccess<UnsignedByteType> cursor = output.randomAccess(); + for ( int y = 0; y < i.dimension( 1 ); y++ ) + { + for ( int x = 0; x < i.dimension( 0 ); x++ ) + { + setPosition( access, x, y ); + access.get().setReal(setPositionAndGet(cursor, x, y).getRealDouble() ); + } + } + + Img<UnsignedByteType> output_unbinned = Unbinning.run(i, i.factory(), bin); + ImageJFunctions.show( output_unbinned, "unbinned 1" ); + } + +} +