diff --git a/src/main/java/fr/pasteur/ida/zellige/Main.java b/src/main/java/fr/pasteur/ida/zellige/Main.java index 1dfe551211cfecd9dc8d26ddba88b8ad3adab5a3..795b005cebdd16599caa5fd9932b2ae37e1b23d8 100644 --- a/src/main/java/fr/pasteur/ida/zellige/Main.java +++ b/src/main/java/fr/pasteur/ida/zellige/Main.java @@ -69,7 +69,7 @@ public class Main // Input of the image. - final String imagePath = "doc/Scan1_volume.tif"; + final String imagePath = "doc/Scan1_volume_crop.tif"; //args[ 0 ]; /* The image path goes here !!!! */ //args[ 0 ]; /* The image path goes here !!!! */ LOGGER.debug( imagePath ); @@ -86,7 +86,7 @@ public class Main .getPath( "" ) .toAbsolutePath() .toString(); - String imageFilePath = "doc/Scan1_volume_crop.tif"; + String imageFilePath = "doc/Cochlée1.tif"; Object obj = ij.io(). open( new File( currentFolder, imageFilePath ).getAbsolutePath() ); @@ -118,7 +118,7 @@ public class Main - int bin = 4;//TODO order of arguments + int bin = 2;//TODO order of arguments int amplitude = 10; int otsu = 10; int islandSize =5; diff --git a/src/main/java/fr/pasteur/ida/zellige/ReferenceSurfaceExtraction.java b/src/main/java/fr/pasteur/ida/zellige/ReferenceSurfaceExtraction.java index b8599c2460a50a46db2cf2cbd8ecfd0116014119..bc087d6b595a19e4a028fb92ce81178801cb957a 100644 --- a/src/main/java/fr/pasteur/ida/zellige/ReferenceSurfaceExtraction.java +++ b/src/main/java/fr/pasteur/ida/zellige/ReferenceSurfaceExtraction.java @@ -43,10 +43,12 @@ import fr.pasteur.ida.zellige.steps.projection.ReferenceSurfaceProjection; import fr.pasteur.ida.zellige.steps.selection.Selection; import fr.pasteur.ida.zellige.steps.selection.classification.ClassificationParameters; import fr.pasteur.ida.zellige.steps.selection.exception.DataValidationException; +import fr.pasteur.ida.zellige.steps.selection.exception.ImageTooLargeException; import fr.pasteur.ida.zellige.steps.selection.exception.NoClassificationException; import fr.pasteur.ida.zellige.steps.selection.postTreatment.PostTreatmentParameters; import fr.pasteur.ida.zellige.steps.selection.pretreatment.PretreatmentParameters; import net.imglib2.RandomAccessibleInterval; +import net.imglib2.img.Img; import net.imglib2.img.ImgFactory; import net.imglib2.type.NativeType; import net.imglib2.type.numeric.RealType; @@ -64,8 +66,8 @@ public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T private final static Logger LOGGER = LoggerFactory.getLogger( ReferenceSurfaceExtraction.class ); private final ArrayList< ReferenceSurface< T > > referenceSurfaces = new ArrayList<>(); - private final RandomAccessibleInterval< T > input; - private final ImgFactory< T > factory; +// private final RandomAccessibleInterval< T > input; +// private final ImgFactory< T > factory; private Pixels[][] maximums; private final static double adequacy = 1; @@ -85,12 +87,17 @@ public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T private int SS_goodSurfaces; private static final String derivativeMethod = FORWARD; - public ReferenceSurfaceExtraction( RandomAccessibleInterval< T > input, ImgFactory< T > factory ) +// public ReferenceSurfaceExtraction( RandomAccessibleInterval< T > input, ImgFactory< T > factory ) +// { +// this.input = input; +// this.factory = factory; +// } + + + public ReferenceSurfaceExtraction( ) { - this.input = input; - this.factory = factory; - } + } public static double getAdequacy() { return adequacy; @@ -98,14 +105,21 @@ public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T - public void select( PretreatmentParameters pretreatmentParameters, ClassificationParameters classificationParameters, PostTreatmentParameters postTreatmentParameters ) throws NoClassificationException, DataValidationException +// public void select( PretreatmentParameters pretreatmentParameters, ClassificationParameters classificationParameters, PostTreatmentParameters postTreatmentParameters ) throws NoClassificationException, DataValidationException, ImageTooLargeException +// { +// /* First step : Pixel selection */ +// LOGGER.debug( "Running selection..." ); +// maximums = Selection.run( input, pretreatmentParameters, classificationParameters, postTreatmentParameters ); +// } + + public void select( Img<T> input, PretreatmentParameters pretreatmentParameters, ClassificationParameters classificationParameters, PostTreatmentParameters postTreatmentParameters ) throws NoClassificationException, DataValidationException, ImageTooLargeException { /* First step : Pixel selection */ LOGGER.debug( "Running selection..." ); maximums = Selection.run( input, pretreatmentParameters, classificationParameters, postTreatmentParameters ); } - public void construct( ConstructionParameters[] constructionParameters ) throws NoSurfaceFoundException + public void construct( RandomAccessibleInterval<T> input, ImgFactory<T> factory,ConstructionParameters[] constructionParameters ) throws NoSurfaceFoundException { LOGGER.debug( "Running construction..." ); /* First round construction*/ @@ -132,7 +146,40 @@ public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T SS_OSConstructionProcessingTime = step2.getOSConstructionProcessingTime(); SS_SurfaceConstructionProcessingTime = step2.getConstructionProcessingTime(); /* Building reference surfaces */ - referenceSurfaces.addAll( ConstructionCompletion.run( input, factory, finalSurfaces ) ); + referenceSurfaces.addAll( ConstructionCompletion.run( input, factory, finalSurfaces , 2) ); +// referenceSurfaceInstantiation( finalSurfaces ); + LOGGER.debug( " Constructions of {} surfaces.", referenceSurfaces.size() ); + + } + + public void construct( Img<T> input,ConstructionParameters[] constructionParameters ) throws NoSurfaceFoundException + { + LOGGER.debug( "Running construction..." ); + /* First round construction*/ + FirstRoundConstruction step1 = new FirstRoundConstruction( maximums, constructionParameters[ 0 ] ); + step1.process(); + ArrayList< Surface > tempSurfaces = step1.getSurfaces(); + FS_startingOS_count = step1.getStartingOSCount(); + FS_OS_count = step1.getOSCount(); + FS_goodSurfaces = step1.getGoodSurfacesCount(); + FS_smallSurfaces = step1.getSmallSurfacesCount(); + FS_finalizedSurfaces = tempSurfaces.size(); + FS_OSConstructionProcessingTime = step1.getOSConstructionProcessingTime(); + FS_SurfaceConstructionProcessingTime = step1.getConstructionProcessingTime(); + LOGGER.debug( "first round surfaces = " + tempSurfaces.size() ); + /* Second round construction */ + SecondRoundConstruction step2 = + new SecondRoundConstruction( tempSurfaces, constructionParameters[ 1 ] ); + step2.process(); + ArrayList< Surface > finalSurfaces = step2.getSurfaces(); + SS_startingOS_count = step2.getStartingOSCount(); + SS_OS_count = step2.getOSCount(); + SS_goodSurfaces = step2.getGoodSurfacesCount(); + SS_smallSurfaces = step2.getSmallSurfacesCount(); + SS_OSConstructionProcessingTime = step2.getOSConstructionProcessingTime(); + SS_SurfaceConstructionProcessingTime = step2.getConstructionProcessingTime(); + /* Building reference surfaces */ + referenceSurfaces.addAll( ConstructionCompletion.run( input, input.factory(), finalSurfaces, 2 ) ); // referenceSurfaceInstantiation( finalSurfaces ); LOGGER.debug( " Constructions of {} surfaces.", referenceSurfaces.size() ); @@ -140,7 +187,7 @@ public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T public void project( ProjectionParameters projectionParameters, DisplayParameters displayParameters ) throws NoPossibleDisplayException { - LOGGER.debug( "Running projection..." ); + LOGGER.debug( "Running projection1..." ); for ( ReferenceSurface< T > referenceSurface : referenceSurfaces ) { referenceSurface.init(); diff --git a/src/main/java/fr/pasteur/ida/zellige/command/Zellige.java b/src/main/java/fr/pasteur/ida/zellige/command/Zellige.java index 4bb0426aca7cb5fea923e121521219d93c27e308..37d50048c4693da277437302f62d9884e6897f6c 100644 --- a/src/main/java/fr/pasteur/ida/zellige/command/Zellige.java +++ b/src/main/java/fr/pasteur/ida/zellige/command/Zellige.java @@ -50,7 +50,7 @@ public class Zellige extends ContextCommand .getPath( "" ) .toAbsolutePath() .toString(); - String imageFilePath = "doc/Scan1_volume_crop.tif"; + String imageFilePath = "doc/Cochlée1.tif"; // Launch ImageJ. ImageJ ij = new ImageJ(); diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/PreprocessingPanel.java b/src/main/java/fr/pasteur/ida/zellige/gui/PreprocessingPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..9a6599bd2649a44ecb3171b75f0d771160c58fc0 --- /dev/null +++ b/src/main/java/fr/pasteur/ida/zellige/gui/PreprocessingPanel.java @@ -0,0 +1,71 @@ +/*- + * #%L + * Zellige + * %% + * Copyright (C) 2020 - 2023 Institut Pasteur + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ +package fr.pasteur.ida.zellige.gui; + +import javafx.beans.NamedArg; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.control.Label; +import javafx.scene.control.Spinner; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; + +import java.io.IOException; + +public class PreprocessingPanel extends HBox +{ + + + + + + public PreprocessingPanel( ) + { + FXMLLoader fxmlLoader = new FXMLLoader( PreprocessingPanel.class.getClassLoader().getResource( + "fr.pasteur.ida.zellige.gui.view/PreprocessingPanel.fxml" ) ); + fxmlLoader.setRoot( this ); + fxmlLoader.setController( this ); + try + { + fxmlLoader.load(); + } + catch ( IOException e ) + { + e.printStackTrace(); + } + } + + @FXML + public void initialize() + { + + } + + +} diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java b/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java index 0cb8622c376ff0048978f80fe2f551e3bf93850b..267530c10293dc85544162291ccd146143ac1f85 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/controller/MainController.java @@ -34,18 +34,13 @@ import fr.pasteur.ida.zellige.gui.MainAppFrame; import fr.pasteur.ida.zellige.gui.exception.NoA3DStackException; import fr.pasteur.ida.zellige.gui.exception.NoInputException; import fr.pasteur.ida.zellige.gui.exception.TimeLapseException; -import fr.pasteur.ida.zellige.gui.model.ConstructionModel; -import fr.pasteur.ida.zellige.gui.model.MainModel; -import fr.pasteur.ida.zellige.gui.model.ProjectionModel; +import fr.pasteur.ida.zellige.gui.model.*; import fr.pasteur.ida.zellige.gui.model.SelectionModel; import fr.pasteur.ida.zellige.gui.parameter.ConstructionParameter; import fr.pasteur.ida.zellige.gui.parameter.ProjectionParameter; import fr.pasteur.ida.zellige.gui.parameter.SelectionParameter; import fr.pasteur.ida.zellige.gui.parameter.ZelligeParameters; -import fr.pasteur.ida.zellige.gui.task.AbstractTask; -import fr.pasteur.ida.zellige.gui.task.ComputeClassificationImagesTask; -import fr.pasteur.ida.zellige.gui.task.DisplayDatasetChoicesTask; -import fr.pasteur.ida.zellige.gui.task.PretreatmentTask; +import fr.pasteur.ida.zellige.gui.task.*; import javafx.application.Platform; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; @@ -53,10 +48,7 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.Initializable; -import javafx.scene.control.Alert; -import javafx.scene.control.Button; -import javafx.scene.control.ComboBox; -import javafx.scene.control.Label; +import javafx.scene.control.*; import javafx.stage.FileChooser; import net.imagej.Dataset; import net.imagej.ImgPlus; @@ -85,18 +77,24 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme private final SimpleBooleanProperty changedParameters = new SimpleBooleanProperty(); @FXML ComboBox< Dataset > activeDatasets; + @FXML private Button runButton; + + + @FXML + private PreprocessingController< T > preprocessingController; + @FXML + private SelectionController< T > selectionController; @FXML private ConstructionController< T > constructionController; + @FXML + private ProjectionController< T > projectionController; + @FXML private Label logInfo; private MainAppFrame mainAppFrame; - @FXML - private ProjectionController< T > projectionController; - @FXML - private SelectionController< T > selectionController; MainModel< T > model; @@ -107,24 +105,30 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme alert.setTitle( "Error alert" ); alert.setHeaderText( exception.getMessage() ); alert.showAndWait(); - // throw new RuntimeException(exception); + // throw new RuntimeException(exception); } @Override public void initialize( URL url, ResourceBundle resourceBundle ) { - model = new MainModel<>( selectionController.getSelectionModel(), constructionController.getConstructionModel(), projectionController.getModel() ); + + + model = new MainModel<>( preprocessingController.getModel(), selectionController.getModel(), constructionController.getConstructionModel(), projectionController.getModel() ); + + + + /* Control of the files comboBox*/ activeDatasets.setOnMousePressed( event -> setAndDisplayDatasetChoices() );// Update of the list of opened Fiji images activeDatasets.getSelectionModel().selectedItemProperty().addListener( ( observableValue, oldValue, newValue ) -> { - LOGGER.debug( "selectedItemProperty : old value = {}, new value = {} ", oldValue, newValue ); - if(newValue!= null && isValid( newValue )) + LOGGER.debug( "selectedItemProperty : old value = {}, new value = {} ", oldValue, newValue ); + if ( newValue != null && isValid( newValue ) ) { - setCurrentDataset( newValue ); + setCurrentDataset( newValue ); } else { @@ -132,6 +136,8 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme } } ); + + currentDataset.addListener( ( observableValue, dataset, t1 ) -> { if ( t1 != null ) @@ -147,6 +153,7 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme } } ); + pretreatedImg.addListener( ( observable, oldValue, newValue ) -> { if ( newValue != null ) @@ -163,6 +170,7 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme disableGUI.addListener( ( observable, oldValue, newValue ) -> runButton.setDisable( newValue ) ); + // run button initialization runButton.setOnAction( actionEvent -> { @@ -172,9 +180,11 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme } ); /* Binding properties*/ - selectionController.getSelectionModel().pretreatedImgProperty().bind( pretreatedImg ); - selectionController.getSelectionModel().imagesProperty().bind( images ); - constructionController.getConstructionModel().maximumsProperty().bind( selectionController.getSelectionModel().selectedPixelsProperty() ); + preprocessingController.getModel().currentDatasetProperty().bind( currentDataset ); + preprocessingController.getModel().pretreatedImgProperty().bind( pretreatedImg ); + selectionController.getModel().pretreatedImgProperty().bind( pretreatedImg ); + selectionController.getModel().imagesProperty().bind( images ); + constructionController.getConstructionModel().maximumsProperty().bind( selectionController.getModel().selectedPixelsProperty() ); projectionController.getModel().referenceSurfacesProperty().bind( constructionController.getConstructionModel().referenceSurfacesProperty() ); changedParameters.bindBidirectional( selectionController.changedParametersProperty() ); selectionController.changedParametersProperty().bindBidirectional( constructionController.changedParametersProperty() ); @@ -201,26 +211,28 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme public void initExtraction() { - LOGGER.debug( "Init Extraction" ); Dataset dataset = mainAppFrame.getImage().getActiveDataset(); - LOGGER.debug( dataset.getImgPlus().firstElement().getClass().toGenericString() ); - LOGGER.debug( "Function getFrames() :{}", dataset.getFrames() ); - LOGGER.debug( "Properties :{}", dataset.getImgPlus().getProperties() ); + if ( dataset == null ) { showError( new NoInputException() ); return; } + LOGGER.debug( dataset.getImgPlus().firstElement().getClass().toGenericString() ); + LOGGER.debug( "Function getFrames() :{}", dataset.getFrames() ); + LOGGER.debug( "Properties :{}", dataset.getImgPlus().getProperties() ); activeDatasets.getItems().add( dataset ); LOGGER.debug( "Init Extraction completed" ); } + + public void run2() { - if ( selectionController.getSelectionModel().selectedPixelsProperty().getValue() != null ) + if ( selectionController.getModel().selectedPixelsProperty().getValue() != null ) { if ( constructionController.getConstructionModel().referenceSurfacesProperty().getValue() != null ) { @@ -233,14 +245,19 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme } else { - selectionController.getSelectionModel().runPixelSelection(); + selectionController.runPixelSelection(); } LOGGER.debug( "###########################################---NEW RUN---###########################################" ); } + private void runPreprocessing( Dataset dataset ) + { + // AbstractTask< Img<T> > task = new BinningTask<>( pr ) + } + private void runPretreatment( Dataset dataset ) { - AbstractTask< Img< FloatType > > task = new PretreatmentTask<>( dataset);//TODO default value to change + AbstractTask< Img< FloatType > > task = new PreprocessingTask<>( dataset, 2, 2 );//TODO default value to change task.setOnSucceeded( workerStateEvent -> pretreatedImg.setValue( task.getValue() ) ); task.start(); @@ -268,12 +285,12 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme } @SuppressWarnings( "unchecked" ) - public void setCurrentDataset( Dataset dataset ) + public void setCurrentDataset( Dataset dataset ) // TODO modify for channel selection { - currentDataset.setValue( dataset ); - Img< T > input = ( ImgPlus< T > ) dataset.getImgPlus(); - constructionController.getConstructionModel().setInput( input ); - constructionController.getConstructionModel().setFactory( input.factory() ); + currentDataset.setValue( dataset ); + Img< T > input = ( ImgPlus< T > ) dataset.getImgPlus(); + constructionController.getConstructionModel().setInput( input ); + constructionController.getConstructionModel().setFactory( input.factory() ); } @@ -316,7 +333,7 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme ConstructionParameter cp = build( model.getConstructionModel() ); ProjectionParameter pp = build( model.getProjectionModel() ); - ZelligeParameters.serialize( new ZelligeParameters( sp, cp, pp ), file ); + ZelligeParameters.serialize( new ZelligeParameters( 2, sp, cp, pp ), file ); } } @@ -372,7 +389,7 @@ public class MainController< T extends RealType< T > & NativeType< T > > impleme projectionController.setParameters( parameters ); } - private boolean isValid(Dataset dataset) + private boolean isValid( Dataset dataset ) { int numZ = ( int ) dataset.getDepth(); int numFrames = ( int ) dataset.getFrames(); diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/controller/PreprocessingController.java b/src/main/java/fr/pasteur/ida/zellige/gui/controller/PreprocessingController.java new file mode 100644 index 0000000000000000000000000000000000000000..78f3212bede7ca12b262e889d914ed48ae1d2cc4 --- /dev/null +++ b/src/main/java/fr/pasteur/ida/zellige/gui/controller/PreprocessingController.java @@ -0,0 +1,72 @@ +package fr.pasteur.ida.zellige.gui.controller; + +import fr.pasteur.ida.zellige.gui.PreprocessingPanel; +import fr.pasteur.ida.zellige.gui.exception.NoA3DStackException; +import fr.pasteur.ida.zellige.gui.exception.NoInputException; +import fr.pasteur.ida.zellige.gui.exception.TimeLapseException; +import fr.pasteur.ida.zellige.gui.model.PreprocessingModel; +import fr.pasteur.ida.zellige.gui.task.DisplayDatasetChoicesTask; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.fxml.Initializable; +import javafx.scene.control.ComboBox; +import javafx.scene.control.Spinner; +import javafx.scene.control.SpinnerValueFactory; +import net.imagej.Dataset; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.RealType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URL; +import java.util.ResourceBundle; + + + +public class PreprocessingController < T extends RealType< T > & NativeType< T > > implements Initializable +{ + + private final static Logger LOGGER = LoggerFactory.getLogger( PreprocessingController.class ); + + @FXML + private Spinner<Integer> bin; + + + private PreprocessingModel model; + + public PreprocessingController() + { + FXMLLoader fxmlLoader = new FXMLLoader( PreprocessingPanel.class.getClassLoader().getResource( + "fr.pasteur.ida.zellige.gui.view/PreprocessingPanel.fxml" ) ); + fxmlLoader.setRoot( this ); + fxmlLoader.setController( this ); + + } + + + @Override + public void initialize( URL url, ResourceBundle resourceBundle ) + { + //Model + model = new PreprocessingModel(); + + //link Model with View + model.binProperty().bind(bin.valueProperty()); // link between model and controller + + /* Control of the bin Spinner*/ + SpinnerValueFactory< Integer > valueFactory = + new SpinnerValueFactory.IntegerSpinnerValueFactory( 1, 10, 1 ); + bin.setValueFactory( valueFactory ); + + bin.valueProperty().addListener( ( observableValue, number, newValue ) -> + model.runPreprocessingTask()); + + } + + public PreprocessingModel getModel() + { + return model; + } +} \ No newline at end of file diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/controller/SelectionController.java b/src/main/java/fr/pasteur/ida/zellige/gui/controller/SelectionController.java index 31fdbf2e31543a891fcb414b2d9e7951084c7357..a00d308a8a3dc5fedb80a11fc10315d0f959c16f 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/controller/SelectionController.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/controller/SelectionController.java @@ -32,7 +32,7 @@ import fr.pasteur.ida.zellige.gui.ParameterSliderInteger; import fr.pasteur.ida.zellige.gui.ZSlicesSlider; import fr.pasteur.ida.zellige.gui.model.SelectionModel; import fr.pasteur.ida.zellige.gui.parameter.ZelligeParameters; -import fr.pasteur.ida.zellige.gui.task.ImageFXDisplayTask; +import fr.pasteur.ida.zellige.gui.task.*; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ChangeListener; import javafx.fxml.FXML; @@ -57,7 +57,7 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im private final SimpleBooleanProperty changedParameters = new SimpleBooleanProperty(); private final SimpleBooleanProperty disableGUI = new SimpleBooleanProperty(); - private SelectionModel selectionModel; + private SelectionModel model; @FXML private ParameterSliderInteger amplitude; @@ -78,25 +78,25 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im public void initialize( URL url, ResourceBundle resourceBundle ) { // model - selectionModel = new SelectionModel(); + model = new SelectionModel(); //link Model with View - selectionModel.amplitudeProperty().bind( amplitude.sliderProperty() ); - selectionModel.otsuProperty().bind( otsu.sliderProperty() ); - selectionModel.islandProperty().bind( island.sliderProperty() ); - selectionModel.xyBlurProperty().bind( xyBlur.sliderProperty() ); - selectionModel.zBlurProperty().bind( zBlur.sliderProperty() ); - selectionModel.disableGUIProperty().bindBidirectional( disableGUI ); + model.amplitudeProperty().bind( amplitude.sliderProperty() ); + model.otsuProperty().bind( otsu.sliderProperty() ); + model.islandProperty().bind( island.sliderProperty() ); + model.xyBlurProperty().bind( xyBlur.sliderProperty() ); + model.zBlurProperty().bind( zBlur.sliderProperty() ); + model.disableGUIProperty().bindBidirectional( disableGUI ); /* JavaFx Components */ /* Amplitude slider initialization */ amplitude.sliderProperty().addListener( ( observableValue, number, newValue ) -> { - if ( amplitude.hasChanged( newValue ) && selectionModel.selectedAmplitudeProperty().getValue() != null ) + if ( amplitude.hasChanged( newValue ) && model.selectedAmplitudeProperty().getValue() != null ) { disableGUI.setValue( true ); - selectionModel.runAmplitudeTask(); + runAmplitudeTask(); changedParameters.setValue( true ); } } ); @@ -104,10 +104,10 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im /* Otsu slider initialization */ otsu.sliderProperty().addListener( ( observableValue, number, newValue ) -> { - if ( otsu.hasChanged( newValue ) && selectionModel.selectedOtsuProperty().getValue() != null ) + if ( otsu.hasChanged( newValue ) && model.selectedOtsuProperty().getValue() != null ) { disableGUI.setValue( true ); - selectionModel.runOtsuTask(); + runOtsuTask(); changedParameters.setValue( true ); } } ); @@ -116,7 +116,7 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im { if ( island.hasChanged( t1 ) ) { - selectionModel.setIslandSearchImage( null ); + model.setIslandSearchImage( null ); changedParameters.setValue( true ); } } ); @@ -125,7 +125,7 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im { if ( xyBlur.hasChanged( newValue ) ) { - selectionModel.setSelectedPixels( null ); + model.setSelectedPixels( null ); changedParameters.setValue( true ); } } ); @@ -133,7 +133,7 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im { if ( zBlur.hasChanged( newValue ) ) { - selectionModel.setSelectedPixels( null ); + model.setSelectedPixels( null ); changedParameters.setValue( true ); } } ); @@ -162,73 +162,139 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im enableParameters(); } } ); - selectionModel.imagesProperty().addListener( ( observableValue, classifiedImages, t1 ) -> + model.imagesProperty().addListener( ( observableValue, classifiedImages, t1 ) -> { if ( t1 != null ) { - selectionModel.runAmplitudeTask(); - selectionModel.runOtsuTask(); + runAmplitudeTask(); + runOtsuTask(); } else { LOGGER.debug( "IMAGES is NULL" ); - selectionModel.selectedAmplitudeProperty().setValue( null ); - selectionModel.selectedOtsuProperty().setValue( null ); - selectionModel.interClassifiedImageProperty().setValue( null ); + model.selectedAmplitudeProperty().setValue( null ); + model.selectedOtsuProperty().setValue( null ); + model.interClassifiedImageProperty().setValue( null ); } } ); ChangeListener< Img< BitType > > listener = ( observableValue, bitTypeClassifiedImages, t1 ) -> { - if ( selectionModel.selectedAmplitudeProperty().getValue() != null && selectionModel.selectedOtsuProperty().getValue() != null ) + if ( model.selectedAmplitudeProperty().getValue() != null && model.selectedOtsuProperty().getValue() != null ) { - selectionModel.runInterClassification(); + runInterClassification(); LOGGER.debug( "Inter classification" ); } else { LOGGER.debug( "SELECTED_AMPLITUDE or SELECTED_OTSU is NULL" ); - selectionModel.interClassifiedImageProperty().setValue( null ); + model.interClassifiedImageProperty().setValue( null ); } }; - selectionModel.selectedAmplitudeProperty().addListener( listener ); - selectionModel.selectedOtsuProperty().addListener( listener ); + model.selectedAmplitudeProperty().addListener( listener ); + model.selectedOtsuProperty().addListener( listener ); - selectionModel.interClassifiedImageProperty().addListener( ( observable, oldValue, newValue ) -> + model.interClassifiedImageProperty().addListener( ( observable, oldValue, newValue ) -> { LOGGER.info( "Computing double classification..." ); if ( newValue != null ) { computeImageFXDisplay(); } - selectionModel.islandSearchImageProperty().setValue( null ); + model.islandSearchImageProperty().setValue( null ); } ); - selectionModel.islandSearchImageProperty().addListener( ( observableValue, bitTypes, t1 ) -> + model.islandSearchImageProperty().addListener( ( observableValue, bitTypes, t1 ) -> { if ( t1 == null ) { LOGGER.debug( "ISLAND_SEARCH is NULL" ); - selectionModel.selectedPixelsProperty().setValue( null ); + model.selectedPixelsProperty().setValue( null ); } else { - selectionModel.runSmoothing(); + runSmoothing(); } } ); } + public void runAmplitudeTask() + { + AmplitudeThresholdingTask amplitudeTask = new AmplitudeThresholdingTask( model.imagesProperty().get().getAmplitudeImg(), model.amplitudeProperty().getValue().intValue() ); + amplitudeTask.setOnSucceeded( workerStateEvent -> + { + model.selectedAmplitudeProperty().setValue( amplitudeTask.getValue() ); + disableGUI.setValue( false ); + } ); + amplitudeTask.setOnFailed( workerStateEvent -> LOGGER.debug( "Amplitude classification has failed." ) ); + amplitudeTask.start(); + } + + public void runOtsuTask() + { + OtsuThresholdingTask otsuTask = new OtsuThresholdingTask( model.pretreatedImgProperty(), model.imagesProperty().get().getOtsuImg(), model.otsuProperty().getValue().intValue() ); + otsuTask.setOnSucceeded( workerStateEvent -> + { + model.selectedOtsuProperty().setValue( otsuTask.getValue() ); + disableGUI.setValue( false ); + } ); + otsuTask.setOnFailed( workerStateEvent -> LOGGER.debug( "Otsu classification has failed." ) ); + otsuTask.start(); + } + + public void runInterClassification() + { + InterClassificationTask interClassificationTask = new InterClassificationTask( model.selectedAmplitudeProperty(), model.selectedOtsuProperty() ); + interClassificationTask.setOnSucceeded( event -> model.interClassifiedImageProperty().setValue( interClassificationTask.getValue() ) ); + interClassificationTask.start(); + } + + + public void runIslandSearch() + { + IslandSearchTask islandSearchTask = new IslandSearchTask( model.interClassifiedImageProperty(), model.islandProperty() ); + islandSearchTask.setOnSucceeded( workerStateEvent -> + model.islandSearchImageProperty().setValue( islandSearchTask.getValue() ) ); + islandSearchTask.setOnFailed( workerStateEvent -> LOGGER.debug( "FAILED" ) ); + islandSearchTask.start(); + } + + public void runSmoothing() + { + SmoothingTask smoothingTask = new SmoothingTask( model.islandSearchImageProperty(), model.xyBlurProperty(), model.zBlurProperty() ); + smoothingTask.setOnSucceeded( event -> + { + model.selectedPixelsProperty().setValue( smoothingTask.getValue() ); + LOGGER.debug( "max is set" ); + } ); + smoothingTask.start(); + } + + public void runPixelSelection() + { + if ( model.islandSearchImageProperty().getValue() == null ) + { + LOGGER.debug( "Island search image is NULL" ); + runIslandSearch(); + } + else if ( model.selectedPixelsProperty().getValue() == null ) + { + LOGGER.debug( "Island search image is not NULL" ); + runSmoothing(); + } + } + public void computeImageFXDisplay() { - ImageFXDisplayTask imageFXDisplayTask = new ImageFXDisplayTask( selectionModel.interClassifiedImageProperty() ); + ImageFXDisplayTask imageFXDisplayTask = new ImageFXDisplayTask( model.interClassifiedImageProperty() ); imageFXDisplayTask.setOnSucceeded( workerStateEvent -> { LOGGER.info( "Double classification done." ); - selectionModel.imageViewsProperty().setValue( imageFXDisplayTask.getValue() ); + model.imageViewsProperty().setValue( imageFXDisplayTask.getValue() ); setDisplay(); } ); imageFXDisplayTask.start(); @@ -237,12 +303,12 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im public void setDisplay() { stack.getChildren().clear(); - ImageView i = selectionModel.imageViewsProperty().getValue()[ zSlices.getUserValue() ]; + ImageView i = model.imageViewsProperty().getValue()[ zSlices.getUserValue() ]; stack.getChildren().add( i ); // setting of ZSlider - this.setSliceNumber( ( int ) selectionModel.pretreatedImgProperty().getValue().dimension( 2 ) ); + this.setSliceNumber( ( int ) model.pretreatedImgProperty().getValue().dimension( 2 ) ); int width = ( int ) i.boundsInParentProperty().get().getWidth(); this.zSlices.getSlider().setMaxWidth( width ); this.zSlices.getSlider().setVisible( true ); @@ -258,7 +324,7 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im public void refreshDisplay( int value ) { this.stack.getChildren().clear();// Removal of previous slice - ImageView i = selectionModel.imageViewsProperty().getValue()[ value ]; + ImageView i = model.imageViewsProperty().getValue()[ value ]; stack.getChildren().add( i ); // display of selected z slice } @@ -269,7 +335,7 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im public void set() { - this.setSliceNumber( ( int ) selectionModel.pretreatedImgProperty().getValue().dimension( 2 ) ); + this.setSliceNumber( ( int ) model.pretreatedImgProperty().getValue().dimension( 2 ) ); } public void enableParameters() @@ -326,9 +392,9 @@ public class SelectionController< T extends RealType< T > & NativeType< T > > im return disableGUI; } - public SelectionModel getSelectionModel() + public SelectionModel getModel() { - return selectionModel; + return model; } public void setParameters( ZelligeParameters parameters ) diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/model/MainModel.java b/src/main/java/fr/pasteur/ida/zellige/gui/model/MainModel.java index 0277933bda39614dfeda5e0bf3687c908be56437..30e8989a4332a9e4588f794376c26002d81c58bd 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/model/MainModel.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/model/MainModel.java @@ -33,18 +33,25 @@ import net.imglib2.type.numeric.RealType; public class MainModel< T extends RealType< T > & NativeType< T > > { - + private final PreprocessingModel preprocessingModel; private final SelectionModel selectionModel; private final ConstructionModel< T > constructionModel; private final ProjectionModel< T > projectionModel; - public MainModel( SelectionModel selectionModel, ConstructionModel< T > constructionModel, ProjectionModel< T > projectionModel ) + public MainModel( PreprocessingModel preprocessingModel, SelectionModel selectionModel, ConstructionModel< T > constructionModel, ProjectionModel< T > projectionModel ) { + this.preprocessingModel = preprocessingModel; this.selectionModel = selectionModel; this.constructionModel = constructionModel; this.projectionModel = projectionModel; } + + public PreprocessingModel getPreprocessingModel() + { + return preprocessingModel; + } + public SelectionModel getSelectionModel() { return selectionModel; diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/model/PreprocessingModel.java b/src/main/java/fr/pasteur/ida/zellige/gui/model/PreprocessingModel.java new file mode 100644 index 0000000000000000000000000000000000000000..cd571811dc0058256fa3a0e2b6c4b75381a139c3 --- /dev/null +++ b/src/main/java/fr/pasteur/ida/zellige/gui/model/PreprocessingModel.java @@ -0,0 +1,71 @@ +package fr.pasteur.ida.zellige.gui.model; + +import fr.pasteur.ida.zellige.gui.task.AbstractTask; +import fr.pasteur.ida.zellige.gui.task.PreprocessingTask; +import javafx.beans.property.IntegerProperty; +import javafx.beans.property.SimpleIntegerProperty; +import javafx.beans.property.SimpleObjectProperty; +import net.imagej.Dataset; +import net.imglib2.img.Img; +import net.imglib2.type.numeric.real.FloatType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PreprocessingModel +{ + private final static Logger LOGGER = LoggerFactory.getLogger( PreprocessingModel.class ); + + private final IntegerProperty bin; + private final SimpleObjectProperty< Dataset > currentDataset = new SimpleObjectProperty<>(); + private final SimpleObjectProperty< Img< FloatType > > pretreatedImg = new SimpleObjectProperty<>(); + + public PreprocessingModel() + { + this.bin = new SimpleIntegerProperty(); + } + + public void runBinningTask() + { + + } + + public void runPreprocessingTask() + { + AbstractTask< Img< FloatType > > task = new PreprocessingTask<>(currentDataset.get(), 2, getBin() ); + task.setOnSucceeded( workerStateEvent -> + pretreatedImg.setValue( task.getValue() ) ); + task.start(); + } + + public int getBin() + { + return bin.get(); + } + + public IntegerProperty binProperty() + { + return bin; + } + + public Dataset getCurrentDataset() + { + return currentDataset.get(); + } + + public Img< FloatType > getPretreatedImg() + { + return pretreatedImg.get(); + } + + public SimpleObjectProperty< Img< FloatType > > pretreatedImgProperty() + { + return pretreatedImg; + } + + public SimpleObjectProperty< Dataset > currentDatasetProperty() + { + return currentDataset; + + + } +} diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/model/SelectionModel.java b/src/main/java/fr/pasteur/ida/zellige/gui/model/SelectionModel.java index b703deff5be5cbd0bc21fb34881aa919a3cb8a2e..7a7b4284c3e28a07095843fa6850fea9c7936e7e 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/model/SelectionModel.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/model/SelectionModel.java @@ -69,69 +69,71 @@ public class SelectionModel zBlur = new SimpleDoubleProperty(); } - public void runAmplitudeTask() - { - AmplitudeThresholdingTask amplitudeTask = new AmplitudeThresholdingTask( images, amplitude.getValue().intValue() ); - amplitudeTask.setOnSucceeded( workerStateEvent -> - { - selectedAmplitude.setValue( amplitudeTask.getValue() ); - disableGUI.setValue( false ); - } ); - amplitudeTask.start(); - } - - public void runOtsuTask() - { - OtsuThresholdingTask otsuTask = new OtsuThresholdingTask( pretreatedImg, images, otsu.getValue().intValue() ); - otsuTask.setOnSucceeded( workerStateEvent -> - { - selectedOtsu.setValue( otsuTask.getValue() ); - disableGUI.setValue( false ); - } ); - otsuTask.start(); - } - - public void runInterClassification() - { - InterClassificationTask interClassificationTask = new InterClassificationTask( selectedAmplitude, selectedOtsu ); - interClassificationTask.setOnSucceeded( event -> interClassifiedImage.setValue( interClassificationTask.getValue() ) ); - interClassificationTask.start(); - } - - - public void runIslandSearch() - { - IslandSearchTask islandSearchTask = new IslandSearchTask( interClassifiedImage, island ); - islandSearchTask.setOnSucceeded( workerStateEvent -> - islandSearchImage.setValue( islandSearchTask.getValue() ) ); - islandSearchTask.setOnFailed( workerStateEvent -> LOGGER.debug( "FAILED" ) ); - islandSearchTask.start(); - } - - public void runSmoothing() - { - SmoothingTask smoothingTask = new SmoothingTask( islandSearchImage, xyBlur, zBlur ); - smoothingTask.setOnSucceeded( event -> - { - selectedPixels.setValue( smoothingTask.getValue() ); - LOGGER.debug( "max is set" ); - } ); - smoothingTask.start(); - } - - public void runPixelSelection() - { - if ( islandSearchImage.getValue() == null ) - { - LOGGER.debug( "Island search image is NULL" ); - runIslandSearch(); - } - else if ( selectedPixelsProperty().getValue() == null ) - { - LOGGER.debug( "Island search image is not NULL" ); - runSmoothing(); - } - } +// public void runAmplitudeTask() +// { +// AmplitudeThresholdingTask amplitudeTask = new AmplitudeThresholdingTask( images, amplitude.getValue().intValue() ); +// amplitudeTask.setOnSucceeded( workerStateEvent -> +// { +// selectedAmplitude.setValue( amplitudeTask.getValue() ); +// disableGUI.setValue( false ); +// } ); +// amplitudeTask.setOnFailed( workerStateEvent -> LOGGER.debug( "Amplitude classification has failed." ) ); +// amplitudeTask.start(); +// } +// +// public void runOtsuTask() +// { +// OtsuThresholdingTask otsuTask = new OtsuThresholdingTask( pretreatedImg, images, otsu.getValue().intValue() ); +// otsuTask.setOnSucceeded( workerStateEvent -> +// { +// selectedOtsu.setValue( otsuTask.getValue() ); +// disableGUI.setValue( false ); +// } ); +// otsuTask.setOnFailed( workerStateEvent -> LOGGER.debug( "Otsu classification has failed." ) ); +// otsuTask.start(); +// } +// +// public void runInterClassification() +// { +// InterClassificationTask interClassificationTask = new InterClassificationTask( selectedAmplitude, selectedOtsu ); +// interClassificationTask.setOnSucceeded( event -> interClassifiedImage.setValue( interClassificationTask.getValue() ) ); +// interClassificationTask.start(); +// } +// +// +// public void runIslandSearch() +// { +// IslandSearchTask islandSearchTask = new IslandSearchTask( interClassifiedImage, island ); +// islandSearchTask.setOnSucceeded( workerStateEvent -> +// islandSearchImage.setValue( islandSearchTask.getValue() ) ); +// islandSearchTask.setOnFailed( workerStateEvent -> LOGGER.debug( "FAILED" ) ); +// islandSearchTask.start(); +// } +// +// public void runSmoothing() +// { +// SmoothingTask smoothingTask = new SmoothingTask( islandSearchImage, xyBlur, zBlur ); +// smoothingTask.setOnSucceeded( event -> +// { +// selectedPixels.setValue( smoothingTask.getValue() ); +// LOGGER.debug( "max is set" ); +// } ); +// smoothingTask.start(); +// } +// +// public void runPixelSelection() +// { +// if ( islandSearchImage.getValue() == null ) +// { +// LOGGER.debug( "Island search image is NULL" ); +// runIslandSearch(); +// } +// else if ( selectedPixelsProperty().getValue() == null ) +// { +// LOGGER.debug( "Island search image is not NULL" ); +// runSmoothing(); +// } +// } public double getAmplitude() { @@ -183,37 +185,17 @@ public class SelectionModel return xyBlur; } - public double getzBlur() - { - return zBlur.get(); - } - public DoubleProperty zBlurProperty() { return zBlur; } - public boolean isDisableGUI() - { - return disableGUI.get(); - } - - public void setDisableGUI( boolean disableGUI ) - { - this.disableGUI.set( disableGUI ); - } - public SimpleBooleanProperty disableGUIProperty() { return disableGUI; } - public Pixels[][] getSelectedPixels() - { - return selectedPixels.get(); - } - public void setSelectedPixels( Pixels[][] selectedPixels ) { this.selectedPixels.set( selectedPixels ); @@ -239,11 +221,6 @@ public class SelectionModel return images; } - public Img< BitType > getIslandSearchImage() - { - return islandSearchImage.get(); - } - public void setIslandSearchImage( Img< BitType > islandSearchImage ) { this.islandSearchImage.set( islandSearchImage ); @@ -254,71 +231,26 @@ public class SelectionModel return islandSearchImage; } - public Img< FloatType > getPretreatedImg() - { - return pretreatedImg.get(); - } - - public void setPretreatedImg( Img< FloatType > pretreatedImg ) - { - this.pretreatedImg.set( pretreatedImg ); - } - public SimpleObjectProperty< Img< FloatType > > pretreatedImgProperty() { return pretreatedImg; } - public Img< BitType > getSelectedAmplitude() - { - return selectedAmplitude.get(); - } - - public void setSelectedAmplitude( Img< BitType > selectedAmplitude ) - { - this.selectedAmplitude.set( selectedAmplitude ); - } - public SimpleObjectProperty< Img< BitType > > selectedAmplitudeProperty() { return selectedAmplitude; } - public Img< BitType > getSelectedOtsu() - { - return selectedOtsu.get(); - } - - public void setSelectedOtsu( Img< BitType > selectedOtsu ) - { - this.selectedOtsu.set( selectedOtsu ); - } - public SimpleObjectProperty< Img< BitType > > selectedOtsuProperty() { return selectedOtsu; } - public Img< BitType > getInterClassifiedImage() - { - return interClassifiedImage.get(); - } - - public void setInterClassifiedImage( Img< BitType > interClassifiedImage ) - { - this.interClassifiedImage.set( interClassifiedImage ); - } - public SimpleObjectProperty< Img< BitType > > interClassifiedImageProperty() { return interClassifiedImage; } - public ImageView[] getImageViews() - { - return imageViews.get(); - } - public SimpleObjectProperty< ImageView[] > imageViewsProperty() { return imageViews; diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/parameter/SelectionParameter.java b/src/main/java/fr/pasteur/ida/zellige/gui/parameter/SelectionParameter.java index 4dccfcb4a8c3ba2ef8b666322ac7ca7112c2f38f..b065e90147f4aa5f0303258801980b9fd9de22d9 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/parameter/SelectionParameter.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/parameter/SelectionParameter.java @@ -72,3 +72,5 @@ public class SelectionParameter return zBlur; } } + +// TODO verify why the amplitude and otsu parameters are Double property instead of IntegerProperty diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/parameter/ZelligeParameters.java b/src/main/java/fr/pasteur/ida/zellige/gui/parameter/ZelligeParameters.java index 3e247c73265b20797d84176bb9d8e2b3dcd44c61..088d589a670eeb488b9d91b8ee25739c538f331f 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/parameter/ZelligeParameters.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/parameter/ZelligeParameters.java @@ -42,6 +42,7 @@ import java.util.stream.Stream; public class ZelligeParameters { + private final int bin; //selection private final int amplitude; private final int otsu; @@ -62,26 +63,27 @@ public class ZelligeParameters private final String method; - public ZelligeParameters( SelectionParameter sp, ConstructionParameter cp, ProjectionParameter pp ) + public ZelligeParameters( int bin, SelectionParameter sp, ConstructionParameter cp, ProjectionParameter pp ) { + this.bin = bin; // selection - amplitude = sp.getAmplitude(); - otsu = sp.getOtsu(); - island = sp.getIsland(); - xyBlur = sp.getXyBlur(); - zBlur = sp.getzBlur(); + this.amplitude = sp.getAmplitude(); + this.otsu = sp.getOtsu(); + this.island = sp.getIsland(); + this.xyBlur = sp.getXyBlur(); + this.zBlur = sp.getzBlur(); // construction - c1 = cp.getC1(); - r1 = cp.getR1(); - st1 = cp.getSt1(); - c2 = cp.getC2(); - r2 = cp.getR2(); - st2 = cp.getSt2(); - surfaceSize = cp.getSurfaceSize(); + this.c1 = cp.getC1(); + this.r1 = cp.getR1(); + this.st1 = cp.getSt1(); + this.c2 = cp.getC2(); + this.r2 = cp.getR2(); + this.st2 = cp.getSt2(); + this.surfaceSize = cp.getSurfaceSize(); // projection - delta1 = pp.getDelta1(); - delta2 = pp.getDelta2(); - method = pp.getMethod(); + this.delta1 = pp.getDelta1(); + this.delta2 = pp.getDelta2(); + this.method = pp.getMethod(); } diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/task/AmplitudeThresholdingTask.java b/src/main/java/fr/pasteur/ida/zellige/gui/task/AmplitudeThresholdingTask.java index 69b7d4f5803b90ec7f6b0354c397c7b851811a1b..3077ef1a745392068aee21911bcaf58473fbff9a 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/task/AmplitudeThresholdingTask.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/task/AmplitudeThresholdingTask.java @@ -28,9 +28,7 @@ */ package fr.pasteur.ida.zellige.gui.task; -import fr.pasteur.ida.zellige.gui.ClassifiedImages; import fr.pasteur.ida.zellige.steps.selection.classification.AmplitudeClassification; -import javafx.beans.property.SimpleObjectProperty; import net.imglib2.img.Img; import net.imglib2.type.logic.BitType; import net.imglib2.type.numeric.real.FloatType; @@ -41,13 +39,13 @@ public class AmplitudeThresholdingTask extends AbstractTask< Img< BitType > > { private final static Logger LOGGER = LoggerFactory.getLogger( AmplitudeThresholdingTask.class ); - private final SimpleObjectProperty< ClassifiedImages< FloatType > > images; + private final Img<FloatType> input; private final int amplitudeThreshold; - public AmplitudeThresholdingTask( SimpleObjectProperty< ClassifiedImages< FloatType > > images, int amplitudeThreshold ) + public AmplitudeThresholdingTask( Img<FloatType> input, int amplitudeThreshold ) { - this.images = images; + this.input = input; this.amplitudeThreshold = amplitudeThreshold; } @@ -55,6 +53,8 @@ public class AmplitudeThresholdingTask extends AbstractTask< Img< BitType > > protected Img< BitType > call() { LOGGER.info( "Computing amplitude thresholding..." ); - return AmplitudeClassification.applyThreshold( images.getValue().getAmplitudeImg(), amplitudeThreshold ); + Img< BitType > output = AmplitudeClassification.applyThreshold( input, amplitudeThreshold ); + LOGGER.info( "Amplitude thresholds computed..." ); + return output; } } diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/task/BinningTask.java b/src/main/java/fr/pasteur/ida/zellige/gui/task/BinningTask.java new file mode 100644 index 0000000000000000000000000000000000000000..df3517509a9abd19f2d7ba3e1db277c51be8c502 --- /dev/null +++ b/src/main/java/fr/pasteur/ida/zellige/gui/task/BinningTask.java @@ -0,0 +1,30 @@ +package fr.pasteur.ida.zellige.gui.task; + +import fr.pasteur.ida.zellige.steps.selection.util.Binning; +import net.imglib2.RandomAccessibleInterval; +import net.imglib2.img.Img; +import net.imglib2.type.NativeType; +import net.imglib2.type.numeric.RealType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BinningTask < T extends RealType< T > & NativeType< T > > extends AbstractTask<Img<T>> +{ + private final static Logger LOGGER = LoggerFactory.getLogger( BinningTask.class ); + private final int bin; + private final RandomAccessibleInterval<T> input; + + public BinningTask( int bin, RandomAccessibleInterval< T > input ) + { + this.bin = bin; + this.input = input; + } + + @Override + protected Img<T> call() { + LOGGER.info( "Binning" ); + Img<T> binnedImage = Binning.run( input, bin ); + LOGGER.info( "Image binned !" ); + return binnedImage; + } +} diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/task/ConstructionCompletionTask.java b/src/main/java/fr/pasteur/ida/zellige/gui/task/ConstructionCompletionTask.java index d3aee6782fbef6509413403dc3501977acd199ef..3afab1e1a2dff87144780ae704f66ef145b2831c 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/task/ConstructionCompletionTask.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/task/ConstructionCompletionTask.java @@ -59,7 +59,7 @@ public class ConstructionCompletionTask< T extends RealType< T > & NativeType< T protected ArrayList< ReferenceSurface< T > > call() { LOGGER.info( "Processing construction completion..." ); - return ConstructionCompletion.run( input, factory, finalSurfaces ); + return ConstructionCompletion.run( input, factory, finalSurfaces , 2); } } diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/task/OtsuThresholdingTask.java b/src/main/java/fr/pasteur/ida/zellige/gui/task/OtsuThresholdingTask.java index 9709e35eabf951d8fa312194620b3ccf64443ce8..982b55216e4ffd06211191c26ff462b66d88f358 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/task/OtsuThresholdingTask.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/task/OtsuThresholdingTask.java @@ -28,7 +28,6 @@ */ package fr.pasteur.ida.zellige.gui.task; -import fr.pasteur.ida.zellige.gui.ClassifiedImages; import fr.pasteur.ida.zellige.steps.selection.classification.OtsuClassification; import javafx.beans.property.SimpleObjectProperty; import net.imglib2.img.Img; @@ -42,14 +41,14 @@ public class OtsuThresholdingTask extends AbstractTask< Img< BitType > > private final static Logger LOGGER = LoggerFactory.getLogger( OtsuThresholdingTask.class ); private final SimpleObjectProperty< Img< FloatType > > pretreatedImage; - private final SimpleObjectProperty< ClassifiedImages< FloatType > > images; + private final Img<FloatType> input; private final int otsuThreshold; - public OtsuThresholdingTask( SimpleObjectProperty< Img< FloatType > > pretreatedImage, SimpleObjectProperty< ClassifiedImages< FloatType > > images, int otsuThreshold ) + public OtsuThresholdingTask( SimpleObjectProperty< Img< FloatType > > pretreatedImage, Img<FloatType> input, int otsuThreshold ) { this.pretreatedImage = pretreatedImage; - this.images = images; + this.input = input; this.otsuThreshold = otsuThreshold; } @@ -57,6 +56,8 @@ public class OtsuThresholdingTask extends AbstractTask< Img< BitType > > protected Img< BitType > call() { LOGGER.info( "Computing otsu thresholding..." ); - return OtsuClassification.applyLocalThreshold( pretreatedImage.getValue(), images.getValue().getOtsuImg(), otsuThreshold ); + Img< BitType > output = OtsuClassification.applyLocalThreshold( pretreatedImage.getValue(), input, otsuThreshold ); + LOGGER.info( "Amplitude thresholds computed..." ); + return output; } } diff --git a/src/main/java/fr/pasteur/ida/zellige/gui/task/PretreatmentTask.java b/src/main/java/fr/pasteur/ida/zellige/gui/task/PreprocessingTask.java similarity index 86% rename from src/main/java/fr/pasteur/ida/zellige/gui/task/PretreatmentTask.java rename to src/main/java/fr/pasteur/ida/zellige/gui/task/PreprocessingTask.java index bbb6fb4ee955e89579ecee899efdd15dd1b7b7b1..596a54ce78ec7bb3bb6566600824094ccda38cc8 100644 --- a/src/main/java/fr/pasteur/ida/zellige/gui/task/PretreatmentTask.java +++ b/src/main/java/fr/pasteur/ida/zellige/gui/task/PreprocessingTask.java @@ -38,15 +38,19 @@ import net.imglib2.type.numeric.real.FloatType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PretreatmentTask< T extends RealType< T > & NativeType< T > > extends AbstractTask< Img< FloatType > > +public class PreprocessingTask< T extends RealType< T > & NativeType< T > > extends AbstractTask< Img< FloatType > > { - private final static Logger LOGGER = LoggerFactory.getLogger( PretreatmentTask.class ); + private final static Logger LOGGER = LoggerFactory.getLogger( PreprocessingTask.class ); private final Dataset dataset; + private final double radius; + private final int bin; - public PretreatmentTask( Dataset dataset ) + public PreprocessingTask( Dataset dataset, double radius, int bin) { this.dataset = dataset; + this.radius = radius; + this.bin = bin; } @Override @@ -55,7 +59,7 @@ public class PretreatmentTask< T extends RealType< T > & NativeType< T > > exten { LOGGER.info( "Computing pretreatment..." ); ImgPlus< T > input = ( ImgPlus< T > ) dataset.getImgPlus(); - Img< FloatType > pretreatedImg = Pretreatment.run( input ); + Img< FloatType > pretreatedImg = Pretreatment.run( input, radius, bin ); LOGGER.debug( "Done." ); return pretreatedImg; } diff --git a/src/main/java/fr/pasteur/ida/zellige/steps/construction/ConstructionCompletion.java b/src/main/java/fr/pasteur/ida/zellige/steps/construction/ConstructionCompletion.java index b779899a33f457be5f46bb60aacdb88a2a42e71c..72aa7276356ca7359013a2515326e23f8d6ab0eb 100644 --- a/src/main/java/fr/pasteur/ida/zellige/steps/construction/ConstructionCompletion.java +++ b/src/main/java/fr/pasteur/ida/zellige/steps/construction/ConstructionCompletion.java @@ -61,18 +61,19 @@ public class ConstructionCompletion< T extends RealType< T > & NativeType< T > > private final static Logger LOGGER = LoggerFactory.getLogger( ConstructionCompletion.class ); private final ArrayList< ReferenceSurface< T > > referenceSurfaces; + private final int bin; - - public ConstructionCompletion() + public ConstructionCompletion( int bin) { this.referenceSurfaces = new ArrayList<>(); + this.bin = bin; } public static < T extends RealType< T > & NativeType< T > > ArrayList< ReferenceSurface< T > > run( - RandomAccessibleInterval< T > input, ImgFactory< T > factory, ArrayList< Surface > surfaces ) + RandomAccessibleInterval< T > input, ImgFactory< T > factory, ArrayList< Surface > surfaces, int bin ) { - ConstructionCompletion< T > completion = new ConstructionCompletion<>(); + ConstructionCompletion< T > completion = new ConstructionCompletion<>( bin ); completion.referenceSurfaceInstantiation( input, factory, surfaces ); return completion.getReferenceSurfaces(); } @@ -84,7 +85,11 @@ public class ConstructionCompletion< T extends RealType< T > & NativeType< T > > for ( Surface surface : finalSurfaces ) { Img< UnsignedShortType > processedZMap = processedZMap( surface ); - + if (bin > 1) + { + processedZMap = Unbinning.run( processedZMap, bin ); + LOGGER.info("Height map unbinned"); + } ReferenceSurface< T > referenceSurface = new ReferenceSurface<>( input, factory, processedZMap, index++ ); referenceSurfaces.add( referenceSurface ); } diff --git a/src/main/java/fr/pasteur/ida/zellige/steps/projection/ReferenceSurfaceProjection.java b/src/main/java/fr/pasteur/ida/zellige/steps/projection/ReferenceSurfaceProjection.java index 6e6bbc70de4f82d99674c63b14a33cf7788984c0..bdd7f55a61bace62d3c5daeee4d40dc5c75bc3dd 100644 --- a/src/main/java/fr/pasteur/ida/zellige/steps/projection/ReferenceSurfaceProjection.java +++ b/src/main/java/fr/pasteur/ida/zellige/steps/projection/ReferenceSurfaceProjection.java @@ -396,11 +396,11 @@ public class ReferenceSurfaceProjection< T extends RealType< T > & NativeType< T projectionType.equals( "Minimum Intensity" ) ) { referenceSurface.getProjection().setExtractedHeightMap( getProjectionHeightMap( referenceSurface, projectionType, delta ) ); - referenceSurface.getProjection().setReduced3DSpace( getExtractedHeightMapSubStack( referenceSurface, delta ) ); +// referenceSurface.getProjection().setReduced3DSpace( getExtractedHeightMapSubStack( referenceSurface, delta ) ); referenceSurface.getProjection().setProjection( projection1( referenceSurface, projectionType ) ); - referenceSurface.getProjection().setSegmentedSurface( getSegmentedSurface( referenceSurface.getProjection().getExtractedHeightMap(), - referenceSurface.getInput(), - referenceSurface.getFactory() ) ); +// referenceSurface.getProjection().setSegmentedSurface( getSegmentedSurface( referenceSurface.getProjection().getExtractedHeightMap(), +// referenceSurface.getInput(), +// referenceSurface.getFactory() ) ); } else { diff --git a/src/main/java/fr/pasteur/ida/zellige/steps/selection/Selection.java b/src/main/java/fr/pasteur/ida/zellige/steps/selection/Selection.java index e88cd6a27d7fcf5a949ed8dccf2c5e9c572a1953..de99155bc69b544cbcc8601e203ad32f7a8eb733 100644 --- a/src/main/java/fr/pasteur/ida/zellige/steps/selection/Selection.java +++ b/src/main/java/fr/pasteur/ida/zellige/steps/selection/Selection.java @@ -57,7 +57,7 @@ public class Selection< T extends RealType< T > & NativeType< T > > { private final static Logger LOGGER = LoggerFactory.getLogger( Selection.class ); - private final double radius; + private final PretreatmentParameters pretreatmentParameters; private final ClassificationParameters classificationParameters; private final PostTreatmentParameters postTreatmentParameters; private final RandomAccessibleInterval< T > input; @@ -70,14 +70,15 @@ public class Selection< T extends RealType< T > & NativeType< T > > public Selection( PretreatmentParameters pretreatmentParameters, ClassificationParameters classificationParameters, PostTreatmentParameters postTreatmentParameters, RandomAccessibleInterval< T > input ) { - this.radius = pretreatmentParameters.getParameter(); + this.pretreatmentParameters = pretreatmentParameters; this.classificationParameters = classificationParameters; this.postTreatmentParameters = postTreatmentParameters; this.input = input; + //this.factory = factory; } public static < T extends RealType< T > & NativeType< T > > Pixels[][] - run( RandomAccessibleInterval< T > input, PretreatmentParameters pretreatmentParameters, ClassificationParameters classificationParameters, PostTreatmentParameters postTreatmentParameters ) throws NoClassificationException, DataValidationException + run( RandomAccessibleInterval< T > input, PretreatmentParameters pretreatmentParameters, ClassificationParameters classificationParameters, PostTreatmentParameters postTreatmentParameters ) throws NoClassificationException, DataValidationException, ImageTooLargeException { LOGGER.debug( "Starting process..." ); Selection< T > selection = new Selection<>( pretreatmentParameters, classificationParameters, postTreatmentParameters, input ); @@ -86,6 +87,35 @@ public class Selection< T extends RealType< T > & NativeType< T > > return selection.output; } + /** + * @throws NoClassificationException if the no classification was performed + * @throws DataValidationException if one of the input parameters is not valid + */ + public void run() throws NoClassificationException, DataValidationException, ImageTooLargeException + { + + /* Pretreatment of the image.*/ + Img< FloatType > pretreatedImage = Pretreatment.run( input, pretreatmentParameters.getRadius() , pretreatmentParameters.getBin() ); + if (pretreatedImage != null) + { + /* Classification. */ + Img< BitType > classifiedPixel = Classification.run( pretreatedImage, pretreatedImage.factory(), classificationParameters ); + amplitudePT = AmplitudeClassification.getProcessingTime(); + otsuPT = OtsuClassification.getProcessingTime(); + /* PostTreatment and output*/ + output = PostTreatment.run( classifiedPixel, postTreatmentParameters ); + islandSearchPT = IslandSearch.getProcessingTime(); + } + else + { + throw new ImageTooLargeException(); + } + } + + public Pixels[][] getOutput() + { + return output; + } public static Logger getLOGGER() { @@ -106,26 +136,4 @@ public class Selection< T extends RealType< T > & NativeType< T > > { return islandSearchPT; } - - /** - * @throws NoClassificationException if the no classification was performed - * @throws DataValidationException if one of the input parameters is not valid - */ - public void run() throws NoClassificationException, DataValidationException - { - /* Pretreatment of the image.*/ - Img< FloatType > pretreatedImage = Pretreatment.run( input, radius ); - /* Classification. */ - Img< BitType > classifiedPixel = Classification.run( pretreatedImage, pretreatedImage.factory(), classificationParameters ); - amplitudePT = AmplitudeClassification.getProcessingTime(); - otsuPT = OtsuClassification.getProcessingTime(); - /* PostTreatment and output*/ - output = PostTreatment.run( classifiedPixel, postTreatmentParameters ); - islandSearchPT = IslandSearch.getProcessingTime(); - } - - public Pixels[][] getOutput() - { - return output; - } } diff --git a/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/Binning.java b/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/Binning.java deleted file mode 100644 index 4b1d14a4887cebd5318294f68a259c98a607c482..0000000000000000000000000000000000000000 --- a/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/Binning.java +++ /dev/null @@ -1,228 +0,0 @@ -package fr.pasteur.ida.zellige.steps.selection.pretreatment; - -import io.scif.img.ImgOpener; -import net.imagej.ImageJ; -import net.imglib2.*; -import net.imglib2.algorithm.util.Grids; -import net.imglib2.img.Img; -import net.imglib2.img.display.imagej.ImageJFunctions; -import net.imglib2.type.NativeType; -import net.imglib2.type.numeric.RealType; -import net.imglib2.type.numeric.real.FloatType; -import net.imglib2.view.IntervalView; -import net.imglib2.view.Views; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.stream.Collectors; - -public class Binning< T extends RealType< T > & NativeType< T > > -{ - - private final static Logger LOGGER = LoggerFactory.getLogger( Binning.class ); - private final Img< T > input; - - - private int bin = 2; - - public ArrayList< Img< T > > getOutputs() - { - return outputs; - } - - private final ArrayList< Img< T > > outputs; - - - public static < T extends RealType< T > & NativeType< T > > ArrayList< Img< T > > binning( Img< T > input, int bin ) - { - Binning< T > binning = new Binning<>( input, bin ); - final int numberOfChunks = Runtime.getRuntime().availableProcessors() / 2; - - final List< Integer > chunks = new ArrayList<>(); - for ( int i = 0; i < input.dimension( 2 ); i++ ) - { - chunks.add( i ); - } - final List< Runnable > runnables = - chunks.stream() - .map( chunk -> new PixelAttribution<>( input, binning.getOutputs(), chunk ) ) - .collect( Collectors.toList() ); - - final ExecutorService executorService = Executors.newFixedThreadPool( numberOfChunks ); - runnables.forEach( executorService::submit ); - for ( int i = 0; i < binning.getOutputs().size(); i++ ) - { - ImageJFunctions.show( binning.getOutputs().get( i ), "output " + i ); - } - - return binning.getOutputs(); - } - - - public Binning( Img< T > input, int bin ) - { - this.bin = bin; - this.input = input; - outputs = new ArrayList<>( bin ); - int[] dimensions = new int[]{ ( int ) input.dimension( 0 ) / ( bin / 2 ), ( int ) input.dimension( 1 ) / ( bin / 2 ), 1, 1, ( int ) input.dimension( 2 ) }; // X and Y dimensions are divided by the bin value - for ( int i = 0; i < this.bin; i++ ) - { - outputs.add( i, input.factory().create( dimensions ) ); - } - } - - - public Binning( Img< T > input ) - { - this.input = input; - outputs = new ArrayList<>( bin ); - int[] dimensions = new int[]{ ( int ) input.dimension( 0 ) / ( bin / 2 ), ( int ) input.dimension( 1 ) / ( bin / 2 ), 1, 1, ( int ) input.dimension( 2 ) }; // X and Y dimensions are divided by the bin value - for ( int i = 0; i < this.bin; i++ ) - { - outputs.add( i, input.factory().create( dimensions ) ); - } - } - - public void run() - { - int[] dimensions = new int[]{ ( int ) input.dimension( 0 ) / ( bin / 2 ), ( int ) input.dimension( 1 ) / ( bin / 2 ), 1, 1, ( int ) input.dimension( 2 ) }; // X and Y dimensions are divided by the bin value - for ( int i = 0; i < this.bin; i++ ) - { - outputs.add( i, input.factory().create( dimensions ) ); - } - - for ( int Z = 0; Z < input.dimension( 2 ); Z++ )// iteration section by section - { - pixelAttribution1( input, Z ); - } - - for ( int i = 0; i < outputs.size(); i++ ) - { - ImageJFunctions.show( outputs.get( i ), "output " + i ); - } - } - - private void pixelAttribution1( Img< T > input, int sliceNUmber ) - { - IntervalView< T > slice = Views.hyperSlice( input, 2, sliceNUmber ); - ArrayList< Cursor< T > > cursors = new ArrayList<>( this.bin ); - for ( int i = 0; i < outputs.size(); i++ ) - { - cursors.add( i, Views.hyperSlice( outputs.get( i ), 2, sliceNUmber ).cursor() ); - } - pixelAttribution1( slice, cursors ); - } - - private void pixelAttribution1( IntervalView< T > slice, ArrayList< Cursor< T > > cursors ) - { - - List< Interval > intervals = Grids.collectAllContainedIntervals( slice.dimensionsAsLongArray(), new int[]{ 2, 2 } ); // section split into grid - for ( Interval interval : intervals ) // iteration over each grid - { - pixelAttribution1( slice, interval, cursors ); - } - } - - private void pixelAttribution1( IntervalView< T > slice, Interval interval, ArrayList< Cursor< T > > cursors ) - { - IntervalView< T > viewGrid = Views.offsetInterval( slice, interval ); - Cursor< T > viewGridCursor = viewGrid.cursor(); - assignPixel1( viewGridCursor, cursors ); - } - - private void assignPixel1( Cursor< T > gridCursor, ArrayList< Cursor< T > > cursors ) - { - for ( Cursor< T > cursor : cursors ) - { - assignPixel( gridCursor, cursor ); - } - } - - private void assignPixel( Cursor< T > gridCursor, Cursor< T > outputCursor ) - { - gridCursor.fwd(); - outputCursor.fwd(); - outputCursor.get().set( gridCursor.get() ); - } - - - private static final class PixelAttribution< T extends RealType< T > & NativeType< T > > implements Runnable - { - private final Img< T > input; - private final ArrayList< Img< T > > outputs; - private final int sliceNUmber; - - private PixelAttribution( final Img< T > input, ArrayList< Img< T > > outputs, int sliceNumber ) - { - this.input = input; - this.outputs = outputs; - this.sliceNUmber = sliceNumber; - } - - @Override - public void run() - { - IntervalView< T > slice = Views.hyperSlice( input, 2, sliceNUmber ); - ArrayList< Cursor< T > > cursors = new ArrayList<>( this.outputs.size() ); - for ( int i = 0; i < outputs.size(); i++ ) - { - cursors.add( i, Views.hyperSlice( outputs.get( i ), 2, sliceNUmber ).cursor() ); - } - pixelAttribution( slice, cursors ); - } - - private void pixelAttribution( IntervalView< T > slice, ArrayList< Cursor< T > > cursors ) - { - - List< Interval > intervals = Grids.collectAllContainedIntervals( slice.dimensionsAsLongArray(), new int[]{ 2, 2 } ); // section split into grid - for ( Interval interval : intervals ) // iteration over each grid - { - pixelAttribution( slice, interval, cursors ); - } - } - - private void pixelAttribution( IntervalView< T > slice, Interval interval, ArrayList< Cursor< T > > cursors ) - { - IntervalView< T > viewGrid = Views.offsetInterval( slice, interval ); - Cursor< T > viewGridCursor = viewGrid.cursor(); - assignPixel( viewGridCursor, cursors ); - } - - private void assignPixel( Cursor< T > gridCursor, ArrayList< Cursor< T > > cursors ) - { - for ( Cursor< T > cursor : cursors ) - { - assignPixel( gridCursor, cursor ); - } - } - - private void assignPixel( Cursor< T > gridCursor, Cursor< T > outputCursor ) - { - gridCursor.fwd(); - outputCursor.fwd(); - outputCursor.get().set( gridCursor.get() ); - } - } - - - public static void main( String[] args ) - { - ImageJ ij = new ImageJ(); - ij.launch( args ); - final ImgOpener io = new ImgOpener(); - final Img< FloatType > kernel = ( Img< FloatType > ) io.openImgs( "doc/Scan1_volume_Supercrop.tif" ).get( 0 ); - ImageJFunctions.show( kernel, "original" ); - Binning< FloatType > b = new Binning<>( kernel, 4 ); - double time1 = System.currentTimeMillis(); - Binning.binning( kernel, 4 ); - double time2 = System.currentTimeMillis(); - b.run(); - double time3 = System.currentTimeMillis(); - LOGGER.debug( "Single thread time = {}", (time3 - time2) / 1000 ); - LOGGER.debug( "Multithreading time = {}", (time2 - time1 )/ 1000 ); - } -} diff --git a/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/Pretreatment.java b/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/Pretreatment.java index d803581738f93fe12bcbc9ce4ff8bfeee3cebdaa..3562d86ad3e82d95629d3125ac356ed57f1b4aaf 100644 --- a/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/Pretreatment.java +++ b/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/Pretreatment.java @@ -50,7 +50,6 @@ import org.slf4j.LoggerFactory; import static fr.pasteur.ida.zellige.steps.Utils.setPosition; import static fr.pasteur.ida.zellige.steps.Utils.setPositionAndGet; -import static fr.pasteur.ida.zellige.steps.selection.pretreatment.PretreatmentParameters.getBin; public class Pretreatment< T extends RealType< T > & NativeType< T > > { @@ -58,32 +57,34 @@ public class Pretreatment< T extends RealType< T > & NativeType< T > > public static < T extends RealType< T > & NativeType< T > > Img< FloatType > - run( Img< T > input, double radius ) + run( RandomAccessibleInterval< T > input, double radius, int bin ) { Pretreatment< T > pretreatment = new Pretreatment<>(); - return pretreatment.runSteps( input, radius ); + return pretreatment.runSteps( input, radius, bin ); } - public static < T extends RealType< T > & NativeType< T > > Img< FloatType > - run( Img< T > input ) - { - return run( input, 2 ); - } - private Img< FloatType > runSteps( Img< T > input, double radius ) + private Img< FloatType > runSteps( RandomAccessibleInterval< T > input, double radius, int bin ) { LOGGER.debug( "Starting process..." ); + Img< FloatType > output; try { - Img< T > temp = Binning.run( input, getBin() ); // Binning op - if (temp == null) + if (bin == 1) { - throw new BinningFailedException(); + output = gaussianBlurFilterDenoising( input, radius ); + } + else + { + Img< T > temp = Binning.run( input, bin ); // Binning op + if (temp == null) + { + throw new BinningFailedException(); + } + output = gaussianBlurFilterDenoising( temp, radius ); // Filtering op } - Img< FloatType > output = gaussianBlurFilterDenoising( temp, radius ); // Filtering op - // The denoised image is normalized between 0 and 255 output = normalizeImage( output, output.factory() ); // normalizing op return output; diff --git a/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/PretreatmentParameters.java b/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/PretreatmentParameters.java index ca379a6609bed849815769a083c960fce02d7d78..dd154d432fd2e7c229ca694c699db5f197856fc1 100644 --- a/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/PretreatmentParameters.java +++ b/src/main/java/fr/pasteur/ida/zellige/steps/selection/pretreatment/PretreatmentParameters.java @@ -35,14 +35,17 @@ public class PretreatmentParameters public static final String GAUSSIAN_BLUR = "GaussianBlur"; public static final String NOT_IMPLEMENTED = "not implemented"; private final String method; - private final double parameter; + private final double radius; + private int bin = 8; - public PretreatmentParameters( String method, double parameter ) throws DataValidationException + + public PretreatmentParameters( String method, double radius, int bin ) throws DataValidationException { - this.checkParameters( method, parameter ); + this.checkParameters( method, radius ); this.method = method; - this.parameter = parameter; + this.radius = radius; + this.bin = bin; } /** @@ -92,8 +95,16 @@ public class PretreatmentParameters return method; } - public double getParameter() + public double getRadius() + { + return radius; + } + + public int getBin() { - return parameter; + return bin; } + + + } diff --git a/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/Binning.java b/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/Binning.java index 97b1e5e60e9c2c64cccb8b345ab3a766c0baecdc..37cdd269cf1bae3bd7c99813b6b1e316c431aa0a 100644 --- a/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/Binning.java +++ b/src/main/java/fr/pasteur/ida/zellige/steps/selection/util/Binning.java @@ -48,10 +48,6 @@ public class Binning< T extends RealType< T > & NativeType< T > > public static < T extends RealType< T > & NativeType< T > > Img< T > run( final RandomAccessibleInterval< T > input, int bin ) { - if ( bin == 1 ) - { - return null; - } LOGGER.debug( "Staring process...." ); double startTime = System.currentTimeMillis(); final int threads = Runtime.getRuntime().availableProcessors() / 2; diff --git a/src/main/java/fr/pasteur/ida/zellige/utils/test/ZelligePipelineAnalyse.java b/src/main/java/fr/pasteur/ida/zellige/utils/test/ZelligePipelineAnalyse.java index 604778b85f53e2c572b787c39934aa72c60ab99b..13f5b24164e78e134a9045cba98e91ff5a6286f2 100644 --- a/src/main/java/fr/pasteur/ida/zellige/utils/test/ZelligePipelineAnalyse.java +++ b/src/main/java/fr/pasteur/ida/zellige/utils/test/ZelligePipelineAnalyse.java @@ -6,13 +6,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -65,10 +65,9 @@ public class ZelligePipelineAnalyse< T extends RealType< T > & NativeType< T >, long startTime = System.currentTimeMillis(); ImgFactory< R > factory = tested.factory(); - extraction = new ReferenceSurfaceExtraction<>( tested, factory - ); + extraction = new ReferenceSurfaceExtraction<>(); long extractionStartTime = System.currentTimeMillis(); - extraction.select( parameters.getPretreatmentParameters(), parameters.getClassificationParameters(), parameters.getPostTreatmentParameters() ); + extraction.select(tested, parameters.getPretreatmentParameters(), parameters.getClassificationParameters(), parameters.getPostTreatmentParameters() ); long extractionStopTime = System.currentTimeMillis(); selectionProcessingTime = extractionStopTime - extractionStartTime; LOGGER.debug( "Extraction processing time : {} ms", selectionProcessingTime ); @@ -78,7 +77,7 @@ public class ZelligePipelineAnalyse< T extends RealType< T > & NativeType< T >, try { extractionStartTime = System.currentTimeMillis(); - extraction.construct( parameters.getConstructionParameters() ); + extraction.construct(tested, factory, parameters.getConstructionParameters() ); stopTime = System.currentTimeMillis(); constructionProcessingTime = stopTime - extractionStartTime; LOGGER.debug( "Construction processing time : {} ms", constructionProcessingTime ); diff --git a/src/main/resources/fr.pasteur.ida.zellige.gui.view/Main.fxml b/src/main/resources/fr.pasteur.ida.zellige.gui.view/Main.fxml index b22f97166fbc38cef4cce29a62376af30f8fe166..3fecfe8052272a00fa97cdf5dae651e117b7ba7a 100644 --- a/src/main/resources/fr.pasteur.ida.zellige.gui.view/Main.fxml +++ b/src/main/resources/fr.pasteur.ida.zellige.gui.view/Main.fxml @@ -1,41 +1,45 @@ <?xml version="1.0" encoding="UTF-8"?> <!--suppress JavaFxDefaultTag, JavaFxUnresolvedFxIdReference --> + <?import javafx.geometry.Insets?> -<?import javafx.scene.control.*?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.Label?> <?import javafx.scene.image.Image?> <?import javafx.scene.image.ImageView?> -<?import javafx.scene.layout.*?> +<?import javafx.scene.layout.BorderPane?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.StackPane?> +<?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> -<VBox xmlns:fx="http://javafx.com/fxml" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" - minHeight="-Infinity" minWidth="-Infinity" prefHeight="786.0" prefWidth="866.0" spacing="5.0" - stylesheets="@theme2.css" xmlns="http://javafx.com/javafx" - fx:controller="fr.pasteur.ida.zellige.gui.controller.MainController"> + +<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="786.0" prefWidth="866.0" spacing="5.0" stylesheets="@theme2.css" xmlns="http://javafx.com/javafx/23.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fr.pasteur.ida.zellige.gui.controller.MainController"> <padding> - <Insets left="10.0" right="10.0" top="5.0"/> + <Insets left="10.0" right="10.0" top="5.0" /> </padding> - <HBox alignment="CENTER_LEFT" prefHeight="26.0" prefWidth="774.0" spacing="5.0" VBox.vgrow="ALWAYS"> + <HBox alignment="CENTER_LEFT" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="846.0" spacing="5.0" VBox.vgrow="ALWAYS"> <padding> - <Insets left="10.0"/> + <Insets left="10.0" /> </padding> - <HBox alignment="CENTER_LEFT" prefHeight="45.0" prefWidth="494.0"> + <HBox alignment="CENTER_LEFT" prefHeight="26.0" prefWidth="266.0"> <children> <Label prefHeight="12.0" prefWidth="71.0" text="File : "> <font> - <Font size="14.0"/> + <Font size="14.0" /> </font> </Label> - <ComboBox fx:id="activeDatasets" minHeight="-Infinity" minWidth="-Infinity" prefHeight="26.0" - prefWidth="262.0"/> + <ComboBox fx:id="activeDatasets" minHeight="-Infinity" minWidth="-Infinity" prefHeight="26.0" prefWidth="262.0" /> </children> </HBox> - <HBox alignment="CENTER_RIGHT" prefHeight="45.0" prefWidth="333.0" spacing="10.0"> + <fx:include fx:id="preprocessing" prefHeight="30.0" prefWidth="200.0" source="testBin.fxml" /> + <HBox alignment="CENTER_RIGHT" prefHeight="26.0" prefWidth="383.0" spacing="10.0"> <children> <Button mnemonicParsing="false" onAction="#loadParameters" text="Load parameters"> <graphic> <ImageView fitHeight="15.0" fitWidth="22.0" pickOnBounds="true" preserveRatio="true"> <image> - <Image url="@/icons/script_add.png"/> + <Image url="@/icons/script_add.png" /> </image> </ImageView> </graphic> @@ -44,7 +48,7 @@ <graphic> <ImageView fitHeight="15.0" fitWidth="26.0" pickOnBounds="true" preserveRatio="true"> <image> - <Image url="@../icons/script_save.png"/> + <Image url="@../icons/script_save.png" /> </image> </ImageView> </graphic> @@ -52,23 +56,18 @@ </children> </HBox> </HBox> - <fx:include fx:id="selection" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" - minHeight="-Infinity" minWidth="-Infinity" source="Selection.fxml" VBox.vgrow="ALWAYS"/> + <fx:include fx:id="selection" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" source="Selection.fxml" VBox.vgrow="ALWAYS" /> <HBox alignment="CENTER_LEFT" prefHeight="319.0" prefWidth="700.0" spacing="5.0"> - <fx:include fx:id="construction" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" - minHeight="-Infinity" minWidth="-Infinity" source="Construction.fxml" HBox.hgrow="ALWAYS"/> - <fx:include fx:id="projection" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" - minHeight="-Infinity" minWidth="-Infinity" source="Projection.fxml" HBox.hgrow="ALWAYS"/> + <fx:include fx:id="construction" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" source="Construction.fxml" HBox.hgrow="ALWAYS" /> + <fx:include fx:id="projection" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" source="Projection.fxml" HBox.hgrow="ALWAYS" /> </HBox> <StackPane prefHeight="51.0" prefWidth="747.0" VBox.vgrow="ALWAYS"> <BorderPane prefHeight="27.0" prefWidth="846.0"> <left> - <Label fx:id="logInfo" alignment="CENTER" prefHeight="32.0" prefWidth="418.0" - BorderPane.alignment="CENTER"/> + <Label fx:id="logInfo" alignment="CENTER" prefHeight="32.0" prefWidth="418.0" BorderPane.alignment="CENTER" /> </left> <center> - <Button fx:id="runButton" disable="true" mnemonicParsing="false" text="Run Zellige !" - BorderPane.alignment="TOP_CENTER"/> + <Button fx:id="runButton" disable="true" mnemonicParsing="false" text="Run Zellige !" BorderPane.alignment="TOP_CENTER" /> </center> </BorderPane> </StackPane> diff --git a/src/main/resources/fr.pasteur.ida.zellige.gui.view/StepPanel.fxml b/src/main/resources/fr.pasteur.ida.zellige.gui.view/StepPanel.fxml index b49b698657c34246376cdc01c912fcea90b2cca6..07460b8f5f77f18b4e781ae1cdaabe4d5d5eee0e 100644 --- a/src/main/resources/fr.pasteur.ida.zellige.gui.view/StepPanel.fxml +++ b/src/main/resources/fr.pasteur.ida.zellige.gui.view/StepPanel.fxml @@ -6,8 +6,10 @@ <?import javafx.scene.control.Separator?> <?import javafx.scene.layout.VBox?> <?import java.lang.String?> -<fx:root xmlns:fx="http://javafx.com/fxml" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" - minHeight="-Infinity" minWidth="-Infinity" prefHeight="303.0" prefWidth="322.0" stylesheets="@theme2.css" +<fx:root xmlns:fx="http://javafx.com/fxml" maxHeight="1.7976931348623157E308" + maxWidth="1.7976931348623157E308" + minHeight="-Infinity" minWidth="-Infinity" prefHeight="303.0" + prefWidth="322.0" stylesheets="@theme2.css" type="VBox" xmlns="http://javafx.com/javafx"> <children> <Label fx:id="Label2" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" maxWidth="-Infinity" diff --git a/src/test/java/fr/pasteur/ida/zellige/behavior/StartingOSESameSurfaceTest.java b/src/test/java/fr/pasteur/ida/zellige/behavior/StartingOSESameSurfaceTest.java index 8ec2228443fab09c0535e87d5cb67cf703a75674..89c27cd1bdb83c8a4838b34bdbdc179f153f7f70 100644 --- a/src/test/java/fr/pasteur/ida/zellige/behavior/StartingOSESameSurfaceTest.java +++ b/src/test/java/fr/pasteur/ida/zellige/behavior/StartingOSESameSurfaceTest.java @@ -39,6 +39,7 @@ import fr.pasteur.ida.zellige.steps.construction.rounds.surface.SurfaceConstruct import fr.pasteur.ida.zellige.steps.selection.Selection; import fr.pasteur.ida.zellige.steps.selection.classification.ClassificationParameters; import fr.pasteur.ida.zellige.steps.selection.exception.DataValidationException; +import fr.pasteur.ida.zellige.steps.selection.exception.ImageTooLargeException; import fr.pasteur.ida.zellige.steps.selection.exception.NoClassificationException; import fr.pasteur.ida.zellige.steps.selection.postTreatment.PostTreatmentParameters; import fr.pasteur.ida.zellige.steps.selection.pretreatment.PretreatmentParameters; @@ -64,7 +65,7 @@ public class StartingOSESameSurfaceTest @Ignore @DisplayName( "Two starting OSE from the same surface don't necessarily produce the exact same surface" ) @Test - < T extends RealType< T > & NativeType< T > > void TwoStartingOSEFromTheSameSurface_whenUseForStartASurface_DonTProduceTheExactSameSurface() throws DataValidationException, NoClassificationException + < T extends RealType< T > & NativeType< T > > void TwoStartingOSEFromTheSameSurface_whenUseForStartASurface_DonTProduceTheExactSameSurface() throws DataValidationException, NoClassificationException, ImageTooLargeException { /* Parameters*/ int amplitude = 5; @@ -83,7 +84,7 @@ public class StartingOSESameSurfaceTest @SuppressWarnings( "unchecked" ) final Img< T > source = ( Img< T > ) imgPlus.getImg(); - Pixels[][] maximums = Selection.run( source, source.factory(), pretreatmentParameters, classificationParameters, postTreatmentParameters ); + Pixels[][] maximums = Selection.run( source, pretreatmentParameters, classificationParameters, postTreatmentParameters ); OSEListArray oseLists = OseConstructionXZ.run( maximums, startingSizeThreshold ); int width = maximums[ 0 ].length;