diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/Threshold.java b/src/main/java/fr/pasteur/ida/zellige/utils/Threshold.java index b937c06e5cb86a80401c8b3fd96e295747067dab..0a93f3086d70448c697471594eb18bd512f4fd49 100644 --- a/src/main/java/fr/pasteur/ida/zellige/utils/Threshold.java +++ b/src/main/java/fr/pasteur/ida/zellige/utils/Threshold.java @@ -1,11 +1,9 @@ package fr.pasteur.ida.zellige.utils; -import ij.IJ; import net.imglib2.Cursor; import net.imglib2.IterableInterval; import net.imglib2.RandomAccess; -import net.imglib2.algorithm.binary.Thresholder; import net.imglib2.algorithm.stats.Histogram; import net.imglib2.algorithm.stats.Max; import net.imglib2.algorithm.stats.RealBinMapper; @@ -16,7 +14,6 @@ import net.imglib2.script.slice.Slice2D; import net.imglib2.type.NativeType; import net.imglib2.type.logic.BitType; import net.imglib2.type.numeric.RealType; -import net.imglib2.type.numeric.real.FloatType; /** @@ -49,18 +46,6 @@ public class Threshold return max; } - public static < R extends RealType< R > & NativeType< R > > double[] sliceThreshold( final Img< R > input, double percent ) throws Exception - { - double[] thresholds = new double[ ( int ) input.dimension( 2 ) ]; - for ( int z = 0; z < input.dimension( 2 ); z++ ) - { - final Slice2D< R > slice = new Slice2D<>( input, 0, 1, 2, z ); - R t = getThreshold( slice, percent ); - thresholds[ z ] = t.getRealDouble(); - } - return thresholds; - } - public static < T extends RealType< T > & NativeType< T > > T findMin( final IterableInterval< T > input, boolean zero ) { @@ -126,9 +111,6 @@ public class Threshold } - - - public static int OtsuCelebiIndex( int[] histogram ) { // Otsu's threshold algorithm @@ -194,24 +176,6 @@ public class Threshold } - public static < T extends RealType< T > & NativeType< T > > Img< T > backgroundRemoval( - Img< T > input, double percent ) - { - T threshold = getThreshold( input, percent ); - IJ.log( "Otsu threshold for background removal = " + threshold ); - - Cursor< T > cursor = input.cursor(); - while ( cursor.hasNext() ) - { - final T value = cursor.next(); - if ( value.compareTo( threshold ) < 0 ) - { - value.setReal( 0 ); - } - } - return input; - } - public static < T extends RealType< T > & NativeType< T > > T getThreshold( Img< T > input, double percent ) { @@ -219,8 +183,9 @@ public class Threshold T max = Threshold.findMax( input ); T min = Threshold.findMin( input ); int[] histogram = getHistogram( input, min, max, 256 ); -// histogram[0] = 0; + histogram[ 0 ] = 0; int thresholdIndex = OtsuCelebiIndex( histogram ); + double binWidth = ( max.getRealDouble() - min.getRealDouble() ) / ( double ) histogram.length; double result = ( ( double ) ( thresholdIndex + 1 ) * binWidth + min.getRealDouble() ); T threshold = Utils.getTypeValue( result, input.firstElement() ); @@ -229,45 +194,63 @@ public class Threshold } - public static < T extends RealType< T > & NativeType< T > > Img< BitType > classification( Img< T > input, double percent ) - { - T threshold = getThreshold( input, percent ); - System.out.println( "Classification threshold : " + threshold ); - Img< BitType > output = Thresholder.threshold( input, threshold, true, 2 ); - ImageJFunctions.show( output, "classification" ); - return output; - } public static < T extends RealType< T > & NativeType< T > > Img< T > classification( - IterableInterval< T > input, ImgFactory<T> factory, Img<BitType> thresholds) + IterableInterval< T > amplitude, ImgFactory< T > factory, Img< BitType > thresholds ) { - - Img< T > output = factory.create( input ); - Cursor<T> inputCursor = input.localizingCursor(); - RandomAccess<T> outputAccess = output.randomAccess(); - RandomAccess< BitType > randomAccess = thresholds.randomAccess(); - while(inputCursor.hasNext()) + Img< T > output = factory.create( thresholds ); + Cursor< T > amplitudeCursor = amplitude.localizingCursor(); + RandomAccess< BitType > thresholdAccess = thresholds.randomAccess(); + RandomAccess< T > outputAccess = output.randomAccess(); + while( amplitudeCursor.hasNext()) { - inputCursor.fwd(); - final float s = inputCursor.get().getRealFloat(); - - if (s != 0f) + amplitudeCursor.fwd(); + if(amplitudeCursor.get().getRealDouble()!= 0) { - randomAccess.setPosition( inputCursor ); - final boolean b = randomAccess.get().get(); - if (b) + thresholdAccess.setPosition( amplitudeCursor ); + if(thresholdAccess.get().get()) { - outputAccess.setPosition( inputCursor ); + outputAccess.setPosition( amplitudeCursor ); outputAccess.get().setOne(); } - } } - ImageJFunctions.show( output.copy(), "classification" ); - return output; + ImageJFunctions.show( output.copy(), "amp+thresh" ); + return output; } + + + + public static < T extends RealType< T > & NativeType< T > > T getFirstMaxValue( Img< T > input, boolean zero ) + { + T max = Threshold.findMax( input ); + T min = Threshold.findMin( input ); + Histogram< T > H = new Histogram<>( new RealBinMapper<>( min, max, 256 ), input ); + H.process(); + int[] histogram = H.getHistogram(); + + if ( zero ) + { + histogram[ 0 ] = 0; + } + int index = getFirstMaxIndex( histogram ); + + return H.getBinCenter( index ); + } + + public static int getFirstMaxIndex( int[] histogram ) + { + for ( int i = 2; i <= histogram.length - 2; i++ ) + { + if ( histogram[ i - 1 ] < histogram[ i ] && histogram[ i ] > histogram[ i + 1 ] ) + { + return i; + } + } + return - 1; // no max ? + } }