diff --git a/src/main/java/StartingOSStats.java b/src/main/java/StartingOSStats.java index ccc8c76bb2a7b8998ebd3cb5b8dad2dcacc62024..1217020f467ce7d90a2e76a27056c09b44bac865 100644 --- a/src/main/java/StartingOSStats.java +++ b/src/main/java/StartingOSStats.java @@ -1,4 +1,6 @@ +import fr.pasteur.ida.zellige.surfaceConstruction.parameters.AdvancedUserParameters; import fr.pasteur.ida.zellige.surfaceConstruction.construction.ReferenceSurfaceExtraction; +import fr.pasteur.ida.zellige.surfaceConstruction.parameters.UserParameters; import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSE; import fr.pasteur.ida.zellige.utils.TestMIP; import ij.IJ; @@ -88,9 +90,8 @@ public class StartingOSStats int delta = Integer.parseInt( args[ 7 ] ); /* End of parameters. */ - - - /* End of Print parameters.*/ + UserParameters userParameters = new UserParameters( amplitude, otsu, sigmas, delta, "MIP" ); + AdvancedUserParameters advancedUserParameters = new AdvancedUserParameters( k1, percent1, k2, percent2 ); IJ.log("Type: "+ imgPlus.firstElement().getClass().toGenericString()); @@ -98,10 +99,7 @@ public class StartingOSStats { ImageJFunctions.show( stackImage, "original" ); ImageJFunctions.show( TestMIP.findMIP( stackImage, stackImage.factory() ), "MIP" ); - new ReferenceSurfaceExtraction<>( stackImage, stackImage.factory(),amplitude,otsu, sigmas, delta, k1, percent1, k2, percent2 ); - -// SurfacesExtraction.extract(stackImage, stackImage.factory(),amplitude, otsu, sigmas, false, delta, false, -// false, true, "MIP", k1, percent1, k2, percent2); + new ReferenceSurfaceExtraction<>( stackImage, stackImage.factory(),userParameters, advancedUserParameters ); } else { diff --git a/src/main/java/fr/pasteur/ida/zellige/main/Main.java b/src/main/java/fr/pasteur/ida/zellige/main/Main.java index 5ca1c0041bffb989e8c9d161f18ed8758e6730b3..0be1b5d25c4afe8e372632f074828b6f5cbc9675 100644 --- a/src/main/java/fr/pasteur/ida/zellige/main/Main.java +++ b/src/main/java/fr/pasteur/ida/zellige/main/Main.java @@ -1,6 +1,8 @@ package fr.pasteur.ida.zellige.main; +import fr.pasteur.ida.zellige.surfaceConstruction.parameters.AdvancedUserParameters; import fr.pasteur.ida.zellige.surfaceConstruction.construction.ReferenceSurfaceExtraction; +import fr.pasteur.ida.zellige.surfaceConstruction.parameters.UserParameters; import fr.pasteur.ida.zellige.utils.TestMIP; import ij.IJ; import ij.ImageJ; @@ -87,15 +89,17 @@ public class Main System.out.println( System.lineSeparator() ); /* End of Print parameters.*/ + UserParameters userParameters = new UserParameters( amplitude, otsu, sigmas, delta, "MIP" ); + AdvancedUserParameters advancedUserParameters = new AdvancedUserParameters( k1, percent1, k2, percent2 ); IJ.log("Type: "+ imgPlus.firstElement().getClass().toGenericString()); if ( stackImage.numDimensions() == 3 )// Is it a stack ? { ImageJFunctions.show( stackImage, "original" ); ImageJFunctions.show( TestMIP.findMIP( stackImage, stackImage.factory() ), "MIP" ); - new ReferenceSurfaceExtraction<>( stackImage, stackImage.factory(),amplitude,otsu, sigmas, delta, k1, percent1, k2, percent2 ); -// SurfacesExtraction.extract(stackImage, stackImage.factory(),amplitude,otsu, sigmas, false, delta, false, -// false, true, "MIP", k1, percent1, k2, percent2); + ReferenceSurfaceExtraction rse = new ReferenceSurfaceExtraction<>( stackImage, stackImage.factory(),userParameters, advancedUserParameters ); + rse.extract(); + rse.project(); } else { diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/ReferenceSurfaceExtraction.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/ReferenceSurfaceExtraction.java index 0259bb8c9b09cba3312aa33f520f432f6a12b9cf..3bd58de8119623e4ad034cd4a17295ae0c9cc090 100644 --- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/ReferenceSurfaceExtraction.java +++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/ReferenceSurfaceExtraction.java @@ -1,6 +1,7 @@ package fr.pasteur.ida.zellige.surfaceConstruction.construction; -import fr.pasteur.ida.zellige.DisplayParameter; +import fr.pasteur.ida.zellige.surfaceConstruction.parameters.AdvancedUserParameters; +import fr.pasteur.ida.zellige.surfaceConstruction.parameters.DisplayParameter; import fr.pasteur.ida.zellige.exception.FirstRoundConstructionException; import fr.pasteur.ida.zellige.exception.NoSurfaceFoundException; import fr.pasteur.ida.zellige.jzy3D.LocalMaximumsDisplay; @@ -11,6 +12,7 @@ import fr.pasteur.ida.zellige.surfaceConstruction.element.ReferenceSurface; import fr.pasteur.ida.zellige.surfaceConstruction.element.Surface; import fr.pasteur.ida.zellige.surfaceConstruction.element.ose.OSEList; import fr.pasteur.ida.zellige.surfaceConstruction.element.surfaceLine.SurfaceLine; +import fr.pasteur.ida.zellige.surfaceConstruction.parameters.UserParameters; import fr.pasteur.ida.zellige.utils.*; import net.imglib2.RandomAccessibleInterval; import net.imglib2.img.Img; @@ -28,51 +30,45 @@ import java.util.ArrayList; public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T > > { - private ArrayList< ReferenceSurface <T>> referenceSurfaces = new ArrayList<>(); - - public ReferenceSurfaceExtraction( RandomAccessibleInterval< T > input, ImgFactory<T> factory, double amplitude, double threshold, int sigmas, - int delta, int k1, double percent1, int k2, double percent2) + private final ArrayList< ReferenceSurface <T>> referenceSurfaces = new ArrayList<>(); + private final RandomAccessibleInterval< T > input; + private final ImgFactory<T> factory; + private final UserParameters userParameters; + private final AdvancedUserParameters advancedUserParameters; + public ReferenceSurfaceExtraction( RandomAccessibleInterval< T > input, ImgFactory<T> factory, + UserParameters userParameters, AdvancedUserParameters advancedUserParameters) { - extract(input, factory,amplitude, threshold, sigmas, delta, - k1, percent1, k2, percent2); + this.input = input; + this.factory = factory; + this.userParameters = userParameters; + this.advancedUserParameters = advancedUserParameters; } - public void extract( - RandomAccessibleInterval< T > input, ImgFactory<T> factory,double amplitude, double threshold, int sigmas, int delta, - int k1, double percent1, int k2, double percent2) + + public void extract( ) { /* First step : Pixel selection */ - Pixels[][] maximums = SurfacePixelSelection.run( input, amplitude, threshold, sigmas ); + SurfacePixelSelection selection = new SurfacePixelSelection( userParameters ); + selection.run( input ); + Pixels[][] maximums = selection.getMaximums(); + /* Second step : Surface construction in 2 rounds */ try { /* First round construction*/ + double percent1 = advancedUserParameters.getPercent1(); + int k1 = advancedUserParameters.getK1(); ArrayList< Surface > tempSurfaces = firstRoundConstruction( maximums, percent1, k1); System.out.println( "first round surfaces = " + tempSurfaces.size() ); -//// -// for (Surface surface : surfaces) { -// displaySurface(surface); -// } + /* Second round construction */ + double percent2 = advancedUserParameters.getPercent2(); + int k2 = advancedUserParameters.getK2(); ArrayList< Surface > finalSurfaces = secondRoundConstruction( tempSurfaces, percent2, k2 ); System.out.println( "second round surfaces = " + finalSurfaces.size() ); -// if ( !finalSurfaces.isEmpty() ) -// { - int index = 0; /* Process of zMaps */ + processZMap( finalSurfaces ); - for(Surface surface : finalSurfaces) - { - displaySurface( surface ); - Img<UnsignedShortType> processedZMap = processedZMap( surface ); - ReferenceSurface<T> referenceSurface = new ReferenceSurface<>( input, factory, processedZMap, index++ ); - referenceSurfaces.add(referenceSurface); - referenceSurface.setProjection( "MIP" , delta); - DisplayParameter displayParameter = new DisplayParameter(delta, true, - true, true, true ); - referenceSurface.display( displayParameter ); - } -// // Display the projection System.out.println( "The end" ); } catch ( Exception e ) @@ -167,7 +163,7 @@ public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T Img< UnsignedShortType > interpolated = Interpolation.run( surface.getZMap() ); Img< UnsignedShortType > smoothed = interpolated.copy(); ImageJFunctions.show( smoothed, "smoothed" ); - // Second step smoothed the elevation map with gaussian blur + // Second step: smooth the elevation map with gaussian blur Utils.gaussConvolution( interpolated, smoothed, new double[]{ 1.0, 1.0 } ); return smoothed; } @@ -220,6 +216,29 @@ public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T return surfacesReconstruction.getSurfaces(); } + private void processZMap(ArrayList<Surface> surfaces) + { + int index = 0; + for( Surface surface : surfaces ) + { + displaySurface( surface ); + Img< UnsignedShortType > processedZMap = processedZMap( surface ); + ReferenceSurface< T > referenceSurface = new ReferenceSurface<>( input, factory, processedZMap, index++ ); + referenceSurfaces.add( referenceSurface ); + } + } + + public void project() + { + for(ReferenceSurface<T> referenceSurface : referenceSurfaces) + { + referenceSurface.setProjection( userParameters.getProjectionType(), userParameters.getDelta() ); + DisplayParameter displayParameter = new DisplayParameter( userParameters.getDelta(), true, + true, true, true ); + referenceSurface.display( displayParameter ); + } + } + /* ----- Displaying methods -----*/ /** diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/SurfacePixelSelection.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacePixelSelection.java similarity index 79% rename from src/main/java/fr/pasteur/ida/zellige/utils/SurfacePixelSelection.java rename to src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacePixelSelection.java index 15434644ea5c598c58cc6174b372f212e580db17..aa34c762171b31e780f748682c82a7d96833466b 100644 --- a/src/main/java/fr/pasteur/ida/zellige/utils/SurfacePixelSelection.java +++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/construction/SurfacePixelSelection.java @@ -1,12 +1,13 @@ -package fr.pasteur.ida.zellige.utils; +package fr.pasteur.ida.zellige.surfaceConstruction.construction; import fr.pasteur.ida.zellige.jzy3D.LocalMaximumsDisplay; +import fr.pasteur.ida.zellige.surfaceConstruction.parameters.UserParameters; import fr.pasteur.ida.zellige.surfaceConstruction.element.Coordinate; import fr.pasteur.ida.zellige.surfaceConstruction.element.Pixels; +import fr.pasteur.ida.zellige.utils.*; import net.imglib2.RandomAccess; import net.imglib2.RandomAccessibleInterval; import net.imglib2.converter.Converters; -import net.imglib2.converter.RealFloatConverter; import net.imglib2.converter.readwrite.RealFloatSamplerConverter; import net.imglib2.img.Img; import net.imglib2.img.ImgFactory; @@ -16,34 +17,36 @@ import net.imglib2.type.NativeType; import net.imglib2.type.logic.BitType; import net.imglib2.type.numeric.RealType; import net.imglib2.type.numeric.real.FloatType; -import net.imglib2.util.ImgUtil; import org.jzy3d.analysis.AnalysisLauncher; public class SurfacePixelSelection { + private final UserParameters userParameters; + private Pixels[][] maximums; + + public SurfacePixelSelection( UserParameters userParameters ) + { + this.userParameters = userParameters; + } /** * * @param source - * @param amplitude - * @param threshold - * @param sigmas * @param <T> * @return */ - public static < T extends RealType< T > & NativeType< T > > Pixels[][] run( RandomAccessibleInterval< T > source, double amplitude, double threshold, int sigmas ) + public < T extends RealType< T > & NativeType< T > > void run( RandomAccessibleInterval< T > source ) { /* Pretreatment of the image.*/ Img< FloatType > normalized = pretreatment( source ); ImageJFunctions.show( normalized.copy(), "converted, blurred and normalized " ); ImgFactory<FloatType> factory = normalized.factory(); /* Local maximum search and selection */ - Pixels[][] maximums = maximumSearch( normalized, factory, amplitude,threshold, sigmas ); + maximums = maximumSearch( normalized, factory ); /* Output */ displayMaximums( maximums ); - return maximums; } /** @@ -52,7 +55,7 @@ public class SurfacePixelSelection * @param <T> * @return */ - private static < T extends RealType< T > & NativeType< T > >Img<FloatType> pretreatment( RandomAccessibleInterval< T > source ) + private < T extends RealType< T > & NativeType< T > >Img<FloatType> pretreatment( RandomAccessibleInterval< T > source ) { // Conversion into FloatType for the derivative computation (negative values) RandomAccessibleInterval< FloatType > converted = Converters.convert( source, new RealFloatSamplerConverter< T >() ); @@ -65,29 +68,27 @@ public class SurfacePixelSelection return Utils.normalizeImage( c, c.factory()); } - /** * * @param input - * @param amplitude - * @param threshold - * @param sigma + * @param factory * @param <T> * @return */ - private static < T extends RealType< T > & NativeType< T > > Pixels[][] maximumSearch( RandomAccessibleInterval< T > input,ImgFactory<T> factory, double amplitude, double threshold, int sigma ) + private < T extends RealType< T > & NativeType< T > > Pixels[][] maximumSearch( RandomAccessibleInterval< T > input,ImgFactory<T> factory ) { /* Grid of amplitude thresholds */ - Img< FloatType > amplitudeImg = MaximumAmplitudeClassification.find(input,factory, amplitude, 0.10); + Img< FloatType > amplitudeImg = MaximumAmplitudeClassification.find(input,factory,userParameters.getAmplitude() , 0.10); ImageJFunctions.show( amplitudeImg," amplitude" ); /* Grid of local thresholds*/ - Img< BitType > thresholds = LocalOtsuClassification.find( input, factory, threshold ); + Img< BitType > thresholds = LocalOtsuClassification.find( input, factory, userParameters.getThreshold()); /* Pixel selection */ Img<FloatType> finalList = Threshold.classification( amplitudeImg, amplitudeImg.factory(), thresholds ); /* Dilatation of the resulting image*/ + double sigma = userParameters.getSigmas(); Utils.gaussConvolution( finalList.copy(), finalList, new double[]{ sigma, sigma, 1 } ); ImageJFunctions.show(finalList, "blurred maximums" ); @@ -95,14 +96,13 @@ public class SurfacePixelSelection finalList = LocalExtremaDetection.findMaxima( finalList.copy(), finalList.factory() ); return buildPixelArray( finalList ); } - /** * * @param stack * @param <T> * @return */ - public static < T extends RealType< T > & NativeType< T > > Pixels[][] buildPixelArray( + public < T extends RealType< T > & NativeType< T > > Pixels[][] buildPixelArray( final RandomAccessibleInterval< T > stack ) { RandomAccess< T > access = stack.randomAccess(); @@ -147,4 +147,8 @@ public class SurfacePixelSelection } } + public Pixels[][] getMaximums() + { + return maximums; + } } diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ReferenceSurface.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ReferenceSurface.java index b8adab90dde115a4fe300b1f1fcb130e026b5b57..0ab013ec3ae2e4f4b2526dd83bdb68afc13c165c 100644 --- a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ReferenceSurface.java +++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/element/ReferenceSurface.java @@ -1,9 +1,7 @@ package fr.pasteur.ida.zellige.surfaceConstruction.element; -import fr.pasteur.ida.zellige.DisplayParameter; -import fr.pasteur.ida.zellige.utils.Interpolation; +import fr.pasteur.ida.zellige.surfaceConstruction.parameters.DisplayParameter; import fr.pasteur.ida.zellige.utils.StackProjection; -import fr.pasteur.ida.zellige.utils.Utils; import net.imglib2.RandomAccessibleInterval; import net.imglib2.img.Img; import net.imglib2.img.ImgFactory; @@ -19,9 +17,9 @@ public class ReferenceSurface< T extends RealType< T > & NativeType< T > > private final Img< UnsignedShortType > zMap; private Img<T> extractedStack; private Img< UnsignedShortType > elevationMap; - Img< T > projection; - Img< T > heightMapStack; - int index; + private Img< T > projection; + private Img< T > heightMapStack; + private int index; private int delta; private String projectionType; @@ -56,60 +54,6 @@ public class ReferenceSurface< T extends RealType< T > & NativeType< T > > } -// private static < R extends RealType< R > & NativeType< R > > void projection( -// RandomAccessibleInterval< R > original, ImgFactory<R> factory, int delta, Img< UnsignedShortType > zMap, -// boolean zMapDisplay, -// boolean extractedStackDisplay, -// boolean heightMapDisplay, -// boolean projectionDisplay, -// String projectionType, int index ) -// { -// -// // First step : fill in the holes. */ -// Img< UnsignedShortType > interpolated = Interpolation.execute( zMap ); -// Img< UnsignedShortType > smoothed = interpolated.copy(); -// Utils.gaussConvolution( interpolated, smoothed, new double[]{ 1.0, 1.0 } ); -//// Second step smoothed the elevation map -// if ( zMapDisplay ) -// { -// ImageJFunctions.show( smoothed, "Elevation map" + "RS n°" + index ); -// } -// -// Img< R > extractedStack = StackProjection.getExtractedStack( original, factory, smoothed, delta ); -// if ( extractedStackDisplay ) -// { -// ImageJFunctions.show( extractedStack, -// "Extracted stack (delta = " + delta + ")" + "RS n°" + index ); -// } -// if ( projectionDisplay ) -// { -// // A heightmap can be displayed -// if ( projectionType.equals( "MIP" ) || -// projectionType.equals( "Minimum Intensity" ) ) -// { -// Img< UnsignedShortType > heightMap = StackProjection.getHeightMap -// ( original, smoothed, projectionType, delta ); -// if ( heightMapDisplay ) -// { -// ImageJFunctions.show( heightMap, "Height Map with " + -// projectionType + " RS n°" + index ); -// } -// -// Img< R > projection = StackProjection.projection1( original,factory, heightMap, projectionType ); -// ImageJFunctions.show( projection, "Projection with " + projectionType + " RS n°" + index ); -// } -// else -// { -// -// Img< R > projection = StackProjection.projection2( StackProjection.getHeightMapStack( original, factory,zMap, delta ),factory, projectionType ); -// ImageJFunctions.show( projection, "Projection with " + projectionType + " RS n°" + index ); -// -// } -//// ImageJFunctions.show(StackProjection.getHeightMapStack(original, zMap, delta), "HMS"); -// } -// -// } - public void display( DisplayParameter displayParameter ) { if ( projection != null ) diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/AdvancedUserParameters.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/AdvancedUserParameters.java new file mode 100644 index 0000000000000000000000000000000000000000..1f91632024362c725cdfba3dca8391f57afff9c2 --- /dev/null +++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/AdvancedUserParameters.java @@ -0,0 +1,57 @@ +package fr.pasteur.ida.zellige.surfaceConstruction.parameters; + +public class AdvancedUserParameters +{ + private int k1; + private double percent1; + private int k2; + private double percent2; + + public AdvancedUserParameters( int k1, double percent1, int k2, double percent2 ) + { + this.k1 = k1; + this.percent1 = percent1; + this.k2 = k2; + this.percent2 = percent2; + } + + public int getK1() + { + return k1; + } + + public void setK1( int k1 ) + { + this.k1 = k1; + } + + public double getPercent1() + { + return percent1; + } + + public void setPercent1( double percent1 ) + { + this.percent1 = percent1; + } + + public int getK2() + { + return k2; + } + + public void setK2( int k2 ) + { + this.k2 = k2; + } + + public double getPercent2() + { + return percent2; + } + + public void setPercent2( double percent2 ) + { + this.percent2 = percent2; + } +} diff --git a/src/main/java/fr/pasteur/ida/zellige/DisplayParameter.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/DisplayParameter.java similarity index 94% rename from src/main/java/fr/pasteur/ida/zellige/DisplayParameter.java rename to src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/DisplayParameter.java index 8ab217934418a0f2efdcf23eeff93e8f2355d272..5b0ad5983b06cc04ccc55cfc7424160a777cc3d3 100644 --- a/src/main/java/fr/pasteur/ida/zellige/DisplayParameter.java +++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/DisplayParameter.java @@ -1,4 +1,4 @@ -package fr.pasteur.ida.zellige; +package fr.pasteur.ida.zellige.surfaceConstruction.parameters; public class DisplayParameter { diff --git a/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/UserParameters.java b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/UserParameters.java new file mode 100644 index 0000000000000000000000000000000000000000..f9a48c64817e1cb8a31776a14076d8f5596d1cfc --- /dev/null +++ b/src/main/java/fr/pasteur/ida/zellige/surfaceConstruction/parameters/UserParameters.java @@ -0,0 +1,72 @@ +package fr.pasteur.ida.zellige.surfaceConstruction.parameters; + +public class UserParameters +{ + + private double amplitude; + private double threshold; + private int sigmas; + private int delta; + private String projectionType; + + + public UserParameters( double amplitude, double threshold, int sigmas, int delta , String projectionType) + { + this.amplitude = amplitude; + this.threshold = threshold; + this.sigmas = sigmas; + this.delta = delta; + this.projectionType = projectionType; + + } + + public double getAmplitude() + { + return amplitude; + } + + public void setAmplitude( double amplitude ) + { + this.amplitude = amplitude; + } + + public double getThreshold() + { + return threshold; + } + + public void setThreshold( double threshold ) + { + this.threshold = threshold; + } + + public int getSigmas() + { + return sigmas; + } + + public void setSigmas( int sigmas ) + { + this.sigmas = sigmas; + } + + public int getDelta() + { + return delta; + } + + public void setDelta( int delta ) + { + this.delta = delta; + } + + public String getProjectionType() + { + return projectionType; + } + + public void setProjectionType( String projectionType ) + { + this.projectionType = projectionType; + } +}