Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • ida-public/zellige-core
1 result
Show changes
Commits on Source (73)
Showing
with 863 additions and 316 deletions
......@@ -6,7 +6,8 @@
<parent>
<groupId>org.scijava</groupId>
<artifactId>pom-scijava</artifactId>
<version>31.1.0</version>
<version>39.0.0</version>
<relativePath />
</parent>
<groupId>org.example</groupId>
......@@ -48,7 +49,13 @@
</repository>
</repositories>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
......@@ -124,11 +131,11 @@
<artifactId>imagej-legacy</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/net.imglib2/imglib2-script -->
<dependency>
<groupId>net.imglib2</groupId>
<artifactId>imglib2-script</artifactId>
</dependency>
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/net.imglib2/imglib2-script &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>net.imglib2</groupId>-->
<!-- <artifactId>imglib2-script</artifactId>-->
<!-- </dependency>-->
<!-- https://mvnrepository.com/artifact/net.imglib2/imglib2 -->
<dependency>
......
......@@ -29,23 +29,49 @@
package fr.pasteur.ida.zellige;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
import fr.pasteur.ida.zellige.element.ReferenceSurface;
import fr.pasteur.ida.zellige.steps.construction.Construction;
import fr.pasteur.ida.zellige.steps.construction.rounds.ConstructionParameters;
import fr.pasteur.ida.zellige.steps.projection.DisplayParameters;
import fr.pasteur.ida.zellige.steps.projection.ProjectionParameters;
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.postTreatment.PostTreatmentParameters;
import fr.pasteur.ida.zellige.steps.selection.pretreatment.PretreatmentParameters;
import ij.IJ;
import ij.ImageJ;
import io.scif.img.IO;
import io.scif.img.SCIFIOImgPlus;
import fr.pasteur.ida.zellige.steps.selection.util.ArgumentCheck;
import io.scif.img.ImgSaver;
import net.imagej.Dataset;
import net.imagej.ImageJ;
import net.imagej.ImgPlus;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.display.ColorTable;
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.integer.UnsignedShortType;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.view.Views;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.text.RandomStringGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static fr.pasteur.ida.zellige.utils.Util.create4dimImage;
/**
......@@ -54,108 +80,13 @@ import java.awt.*;
public class Main
{
private final static Logger LOGGER = LoggerFactory.getLogger( Main.class );
@SuppressWarnings( "unchecked" )
public static < T extends RealType< T > & NativeType< T > > void main( String[] args ) throws Exception
{
// Launch ImageJ.
ImageJ ij = new ImageJ();
// Input of the image.
final String imagePath =// "C:\\Users\\ctrebeau\\Desktop\\Zellige analysis\\files\\SNR\\snr_000\\multiSurfaces\\phantoms_snr0.mat.tif";
args[ 0 ]; /* The image path goes here !!!! */
LOGGER.debug( imagePath );
/* JY version for opening files. */
final SCIFIOImgPlus< ? > imgPlus = IO.openAll( imagePath ).get( 0 );
final Img< T > stackImage = ( Img< T > ) imgPlus.getImg();
/* User Parameters AKA arguments to run the program*/
int amplitude = Integer.parseInt( args[ 1 ] );
int otsu = Integer.parseInt( args[ 2 ] );
int islandSize = Integer.parseInt( args[ 3 ] );
int connexity = Integer.parseInt( args[ 4 ] );
double sigmaXY = Double.parseDouble( args[ 5 ] );
double sigmaZ = Double.parseDouble( args[ 6 ] );
double startingOsSize1 = Double.parseDouble( args[ 7 ] );
int overlap1 = Integer.parseInt( args[ 8 ] );
double connexityRate1 = Double.parseDouble( args[ 9 ] );
double startingOsSize2 = Double.parseDouble( args[ 10 ] );
int overlap2 = Integer.parseInt( args[ 11 ] );
double connexityRate2 = Double.parseDouble( args[ 12 ] );
double surfaceMinSizeFactor = Double.parseDouble( args[ 13 ] );
int delta = Integer.parseInt( args[ 14 ] );
/* End of parameters. */
// Fixed parameters for now...
String filter = "GaussianBlur";
double filterParameter = 2;
/* Print parameters.*/
LOGGER.debug( "Input image : " + imagePath );
LOGGER.debug( "filter : " + filter );
LOGGER.debug( "filter parameter : " + filterParameter );
LOGGER.debug( "amplitude : " + amplitude );
LOGGER.debug( "threshold : " + otsu );
LOGGER.debug( "connexity : " + connexity );
LOGGER.debug( "island size : " + islandSize );
LOGGER.debug( "sigmaXY : " + sigmaXY );
LOGGER.debug( "sigmaZ : " + sigmaZ );
LOGGER.debug( "starting os size1 : " + startingOsSize1 );
LOGGER.debug( "overlap1 :" + overlap1 );
LOGGER.debug( "connexityRate1 :" + connexityRate1 );
LOGGER.debug( "starting os size2 : " + startingOsSize2 );
LOGGER.debug( "overlap2 :" + overlap2 );
LOGGER.debug( "connexityRate2 :" + connexityRate2 );
LOGGER.debug( "surface Minimum size factor : " + surfaceMinSizeFactor );
LOGGER.debug( "delta : " + delta );
LOGGER.debug( System.lineSeparator() );
/* End of Print parameters.*/
PretreatmentParameters pretreatmentParameters = new PretreatmentParameters( filter, filterParameter );
ClassificationParameters classificationParameters = new ClassificationParameters( amplitude, otsu );
PostTreatmentParameters postTreatmentParameters = new PostTreatmentParameters( sigmaXY, sigmaZ, islandSize, connexity );
ProjectionParameters projectionParameters = new ProjectionParameters( delta, "MIP" );// no other method implemented yet.
ConstructionParameters[] constructionParameters = new ConstructionParameters[]{
new ConstructionParameters( startingOsSize1, overlap1, connexityRate1, surfaceMinSizeFactor ),
new ConstructionParameters( startingOsSize2, overlap2, connexityRate2, surfaceMinSizeFactor ) };
DisplayParameters displayParameters = new DisplayParameters(
true,
true,
true,
true,
true, true );
IJ.log( "Type: " + imgPlus.firstElement().getClass().toGenericString() );
if ( stackImage.numDimensions() == 3 )// Is it a stack ?
{
ReferenceSurfaceExtraction< T > rse = new ReferenceSurfaceExtraction<>
( stackImage, stackImage.factory() );
rse.select( pretreatmentParameters, classificationParameters, postTreatmentParameters );
rse.construct( constructionParameters );
rse.project( projectionParameters, displayParameters );
if ( ! GraphicsEnvironment.isHeadless() )
{
try
{
rse.project( projectionParameters, displayParameters );
}
catch ( Exception e )
{
LOGGER.debug( e.getMessage() );
}
}
}
else
{
LOGGER.debug( " This image has to be a z-stack ! " );
}
public static < T extends RealType< T > & NativeType< T > > void main( String [] args ) throws Exception
{
String CSV_FILE ="doc/test.csv";
ReferenceSurfaceExtraction.run( CSV_FILE );
}
}
......@@ -28,46 +28,78 @@
*/
package fr.pasteur.ida.zellige;
import fr.pasteur.ida.zellige.element.Pixels;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
import fr.pasteur.ida.zellige.element.ReferenceSurface;
import fr.pasteur.ida.zellige.element.Surface;
import fr.pasteur.ida.zellige.gui.exception.NoA3DStackException;
import fr.pasteur.ida.zellige.gui.exception.TimeLapseException;
import fr.pasteur.ida.zellige.steps.construction.Construction;
import fr.pasteur.ida.zellige.steps.construction.ConstructionCompletion;
import fr.pasteur.ida.zellige.steps.construction.exception.NoSurfaceFoundException;
import fr.pasteur.ida.zellige.steps.construction.rounds.ConstructionParameters;
import fr.pasteur.ida.zellige.steps.construction.rounds.FirstRoundConstruction;
import fr.pasteur.ida.zellige.steps.construction.rounds.SecondRoundConstruction;
import fr.pasteur.ida.zellige.steps.projection.DisplayParameters;
import fr.pasteur.ida.zellige.steps.projection.NoPossibleDisplayException;
import fr.pasteur.ida.zellige.steps.projection.ProjectionParameters;
import fr.pasteur.ida.zellige.steps.projection.ReferenceSurfaceProjection;
import fr.pasteur.ida.zellige.steps.projection.*;
import fr.pasteur.ida.zellige.steps.selection.Selection;
import fr.pasteur.ida.zellige.steps.selection.SelectionParameters;
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.exception.ParameterException;
import fr.pasteur.ida.zellige.steps.selection.postTreatment.PostTreatmentParameters;
import fr.pasteur.ida.zellige.steps.selection.pretreatment.PretreatmentParameters;
import fr.pasteur.ida.zellige.steps.selection.util.ArgumentCheck;
import io.scif.img.ImgSaver;
import net.imagej.Dataset;
import net.imagej.ImageJ;
import net.imagej.ImgPlus;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.display.ColorTable;
import net.imglib2.img.Img;
import net.imglib2.img.ImgFactory;
import net.imglib2.img.display.imagej.ImageJFunctions;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.type.numeric.integer.UnsignedShortType;
import net.imglib2.type.numeric.real.FloatType;
import net.imglib2.view.Views;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.text.RandomStringGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static fr.pasteur.ida.zellige.steps.selection.util.Derivative.FORWARD;
import static fr.pasteur.ida.zellige.utils.Util.create4dimImage;
public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T > >
{
private final static Logger LOGGER = LoggerFactory.getLogger( ReferenceSurfaceExtraction.class );
private static final String SEMI_COLON_DELIMITER = ";";
private static final int RADIUS = 2;
private static final String FILTER = "GaussianBlur";
private static final int CONNEXITY = 4;
private static LogFile fileAppender;
@SuppressWarnings( "unchecked" )
private final ArrayList< ReferenceSurface< T > > referenceSurfaces = new ArrayList<>();
private final RandomAccessibleInterval< T > input;
private final ImgFactory< T > factory;
private Pixels[][] maximums;
private Img< FloatType > maximums;
private final static double adequacy = 1;
private long FS_OSConstructionProcessingTime;
......@@ -85,27 +117,252 @@ 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 static < T extends RealType< T > & NativeType< T > > void run(String CSV_FILE)throws IOException, ParameterException
{
this.input = input;
this.factory = factory;
ImageJ ij = new ImageJ();
// ij.launch( args );
setLogStatus();
try ( Stream< String > lines = Files.lines( Paths.get( CSV_FILE ) ) )
{
List< List< String > > records = lines.map( line -> Arrays.asList( line.split( SEMI_COLON_DELIMITER ) ) )
.collect( Collectors.toList() );
LOGGER.debug( "the csv is loaded" );
for ( int i = 1; i < records.size(); i++ ) // skip the header
{
List< String > line = records.get( i );
// Input
String inputPath = line.get( 0 );
Dataset dataset = ArgumentCheck.input( ij.scifio().datasetIO().open( inputPath ) );
String inputName = FilenameUtils.removeExtension(dataset.getName());
String id = uniqueID();
Path datasetLocation = Paths.get(inputPath).getParent();
Path outputPath = Files.createDirectories(Paths.get(String.format("%s\\%s%s",datasetLocation.toString() , inputName, id)));
setLogFilePath( String.format("%s\\log.txt", outputPath) );
int nbChannel = ( int ) dataset.getChannels() > 0 ? ( int ) dataset.getChannels(): 1;
ArrayList< ColorTable > colorTables = new ArrayList<>();
for ( int channel = 0; channel < nbChannel ; channel++ )
{
colorTables.add(dataset.getImgPlus().getColorTable( channel ));
}
// Preprocessing Parameters
LOGGER.info( "Preprocessing parameters" );
LOGGER.info( "------------------------" );
int bin = ArgumentCheck.bin( line.get( 1 ) );
int channel = ArgumentCheck.channel( line.get( 2 ), nbChannel );
// Selection Parameters
LOGGER.info( "Selection parameters" );
LOGGER.info( "--------------------" );
int amplitude = ArgumentCheck.amplitude( line.get( 3 ) );
int otsu = ArgumentCheck.otsu( line.get( 4 ) );
int islandSize = ArgumentCheck.islandSize( line.get( 5 ) );
double sigmaXY = ArgumentCheck.sigmaXY( line.get( 6 ) );
double sigmaZ = ArgumentCheck.sigmaZ( line.get( 7 ) );
// Construction Parameters
LOGGER.info( "Construction parameters" );
LOGGER.info( "-----------------------" );
int FIRST_ROUND = 1;
double startingOsSize1 = ArgumentCheck.startingOsSize( line.get( 8 ), FIRST_ROUND );
int overlap1 = ArgumentCheck.overlap( line.get( 9 ), FIRST_ROUND );
double connexityRate1 = ArgumentCheck.connexity( line.get( 10 ), FIRST_ROUND );
int SECOND_ROUND = 2;
double startingOsSize2 = ArgumentCheck.startingOsSize( line.get( 11 ), SECOND_ROUND );
int overlap2 = ArgumentCheck.overlap( line.get( 12 ), SECOND_ROUND );
double connexityRate2 = ArgumentCheck.connexity( line.get( 13 ), SECOND_ROUND );
double surfaceMinSizeFactor = Double.parseDouble( line.get( 14 ) );
// Projection Parameters
LOGGER.info( "\nProjection parameters" );
LOGGER.info( "--------------------" );
ArrayList< ChannelProjectionParameter > pp = new ArrayList<>();
for ( int n = 0; n < nbChannel; n++ )
{
LOGGER.info( " Channel {}", (n+1 ));
// int channelNb = n * 1;
int delta = ArgumentCheck.delta( line.get( 15 + (3 * n) ), n );
int offset = ArgumentCheck.offset( line.get( 16 + (3 * n) ), n );
String method = ArgumentCheck.method( line.get( 17 +(3 * n) ), n );
ChannelProjectionParameter parameters = new ChannelProjectionParameter( delta, offset, method );
pp.add( parameters );
}
ProjectionParameters projectionParameters =new ProjectionParameters( pp );
LOGGER.debug( "All argument are checked." );
//Parameters
SelectionParameters selectionParameters = new SelectionParameters( amplitude, otsu, sigmaZ, sigmaXY, islandSize );
PretreatmentParameters pretreatmentParameters = new PretreatmentParameters( channel, bin );
// ClassificationParameters classificationParameters = new ClassificationParameters( amplitude, otsu );
// PostTreatmentParameters postTreatmentParameters = new PostTreatmentParameters( sigmaXY, sigmaZ, islandSize, CONNEXITY );
ConstructionParameters[] constructionParameters = new ConstructionParameters[2];
constructionParameters [0] = new ConstructionParameters( startingOsSize1, overlap1, connexityRate1, surfaceMinSizeFactor );
constructionParameters [1] = new ConstructionParameters( startingOsSize2, overlap2, connexityRate2, surfaceMinSizeFactor );
//set the input
Img<T> input ;
if ( nbChannel == 1 )
{
try
{
input = ( create4dimImage( dataset ) );
}
catch ( Exception e )
{
throw new RuntimeException( e );
}
}
else
{
input = ( ( Img< T > ) dataset.getImgPlus() );
}
// Set the target channel
RandomAccessibleInterval<T> inputChannel = Views.hyperSlice( input, 2, (channel -1) );
// Preprocessing and selection steps
ImageJFunctions.show(input, "input");
Img <FloatType > selectedPixels = Selection.run(inputChannel, pretreatmentParameters, selectionParameters );
// Construction step
ArrayList< ReferenceSurface< T > > referenceSurfaces = Construction.run(constructionParameters, input, input.factory(), selectedPixels, bin);
// Projection step
ArrayList< ImgPlus<T> > finalProjections = new ArrayList<>();
for ( int j = 0; j < referenceSurfaces.size(); j++ )
{
ArrayList<Img<T>> channelProjections = new ArrayList<>();
Img< UnsignedShortType > zMap = referenceSurfaces.get(j).getzMap();
for ( int k = 0; k < nbChannel; k++ )
{
ChannelProjectionParameter cpp = projectionParameters.getChannelProjectionParameters().get( k );
RandomAccessibleInterval<T> channelImg = Views.hyperSlice( input, 2, k );
Img<T> subVolume = ReferenceSurfaceProjection.getSubStack( channelImg, input.factory(),zMap, cpp.getDelta(), cpp.getOffset());
Img<T> p = ReferenceSurfaceProjection.run( subVolume, cpp.getMethod());
channelProjections.add(k, p );
}
Img<T> temp = ReferenceSurfaceProjection.regroupChannels( channelProjections );
String projectionName = String.format( "%s_proj_%d", inputName, (j+1) );
ImgPlus< T > finalProjection = ReferenceSurfaceProjection.setColorsAndName( temp, colorTables, projectionName );
finalProjections.add( finalProjection );
}
ImgSaver saver = new ImgSaver();
for ( int j = 0; j < referenceSurfaces.size(); j++ )
{
ImgPlus<T> projection = finalProjections.get(j);
String imgLocation = String.format( "%s\\%s%s",outputPath , projection.getName(), ".tif");
saver.saveImg(imgLocation, projection ) ;
}
LOGGER.debug("End of process");
fileAppender.stop();
}
}
catch ( TimeLapseException e )
{
throw new RuntimeException( e );
}
catch ( DataValidationException e )
{
throw new RuntimeException( e );
}
catch ( NoSurfaceFoundException e )
{
throw new RuntimeException( e );
}
catch ( NoClassificationException e )
{
throw new RuntimeException( e );
}
catch ( ImageTooLargeException e )
{
throw new RuntimeException( e );
}
catch ( NoA3DStackException e )
{
throw new RuntimeException( e );
}
}
/**
* Creates a new LogAppender to display the program state in the GUI.
*/
public static void setLogStatus()
{
LoggerContext context = ( LoggerContext ) LoggerFactory.getILoggerFactory();
ch.qos.logback.classic.Logger rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME);
// Encoder
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext( context );
encoder.setPattern( "%msg%n" );
encoder.start();
// Creates a new FileAppender
fileAppender = new LogFile();
fileAppender.setContext( context );
fileAppender.setFile( ".\\log.txt" );
fileAppender.setEncoder( encoder );
fileAppender.start();
// Attach the appender to the logger
rootLogger.addAppender( fileAppender );
}
public static void setLogFilePath(String path)
{
fileAppender.stop();
fileAppender.setFile( path );
fileAppender.start();
}
public static String uniqueID()
{
RandomStringGenerator generator = new RandomStringGenerator.Builder()
.withinRange('A', 'Z').get();
RandomStringGenerator generator2 = new RandomStringGenerator.Builder()
.withinRange('1', '9').get();
return String.format("_%s%s", generator.generate(2), generator2.generate(2));
}
public static class LogFile extends FileAppender< ILoggingEvent >
{
@Override
protected void append( ILoggingEvent iLoggingEvent )
{
String level = iLoggingEvent.getLevel().toString();
if ( level.equals( Level.INFO.toString() ) )
{
super.append(iLoggingEvent);
}
}
}
public static double getAdequacy()
{
return adequacy;
}
public void select( PretreatmentParameters pretreatmentParameters, ClassificationParameters classificationParameters, PostTreatmentParameters postTreatmentParameters ) throws NoClassificationException, DataValidationException
public void select( RandomAccessibleInterval<T> input, PretreatmentParameters pretreatmentParameters, SelectionParameters selectionParameters ) throws NoClassificationException, DataValidationException, ImageTooLargeException
{
/* First step : Pixel selection */
LOGGER.debug( "Running selection..." );
maximums = Selection.run( input, pretreatmentParameters, classificationParameters, postTreatmentParameters );
maximums = Selection.run( input, pretreatmentParameters, selectionParameters );
}
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*/
......@@ -119,7 +376,7 @@ public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T
FS_finalizedSurfaces = tempSurfaces.size();
FS_OSConstructionProcessingTime = step1.getOSConstructionProcessingTime();
FS_SurfaceConstructionProcessingTime = step1.getConstructionProcessingTime();
LOGGER.debug( "first round surfaces = " + tempSurfaces.size() );
LOGGER.debug( "first round surfaces = {}", tempSurfaces.size() );
/* Second round construction */
SecondRoundConstruction step2 =
new SecondRoundConstruction( tempSurfaces, constructionParameters[ 1 ] );
......@@ -132,44 +389,28 @@ 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 project( ProjectionParameters projectionParameters, DisplayParameters displayParameters ) throws NoPossibleDisplayException
{
LOGGER.debug( "Running projection..." );
for ( ReferenceSurface< T > referenceSurface : referenceSurfaces )
{
referenceSurface.init();
ReferenceSurfaceProjection.run( referenceSurface, projectionParameters, displayParameters );
}
}
// public void construct( RandomAccessibleInterval<T> input,ImgFactory<T> factory, ConstructionParameters[] constructionParameters ) throws NoSurfaceFoundException
// {
// construct( input, factory, constructionParameters);
// }
public void project( int delta, String projectionType, boolean projectionDisplay,
boolean rawHeightMapDisplay,
boolean extractedHeightMapDisplay,
boolean reduced3DSpaceDisplay,
boolean segmentedSurfaceDisplay,
boolean segmentedSurfaceMaskDisplay, int delta2 ) throws NoPossibleDisplayException
public void project( ProjectionParameters projectionParameters, DisplayParameters displayParameters ) throws NoPossibleDisplayException
{
LOGGER.debug( "Running projection..." );
for ( ReferenceSurface< T > referenceSurface : referenceSurfaces )
{
referenceSurface.init();
ReferenceSurfaceProjection.run( referenceSurface, delta, projectionType,
projectionDisplay,
rawHeightMapDisplay,
extractedHeightMapDisplay,
reduced3DSpaceDisplay,
segmentedSurfaceDisplay,
segmentedSurfaceMaskDisplay, delta2 );
}
LOGGER.debug( "Running projection1..." );
// for ( ReferenceSurface< T > referenceSurface : referenceSurfaces )
// {
// referenceSurface.init();
// ReferenceSurfaceProjection.run( referenceSurface, projectionParameters, displayParameters );
// }
}
public void setMaximums( Pixels[][] maximums )
public void setMaximums( Img<FloatType> maximums )
{
this.maximums = maximums;
}
......@@ -179,7 +420,7 @@ public class ReferenceSurfaceExtraction< T extends RealType< T > & NativeType< T
return referenceSurfaces;
}
public Pixels[][] getMaximums()
public Img<FloatType> getMaximums()
{
return maximums;
}
......
......@@ -50,18 +50,19 @@ public class Zellige extends ContextCommand
.getPath( "" )
.toAbsolutePath()
.toString();
// String imageFilePath = "C:\\Users\\ctrebeau\\Desktop\\channel_test.tif";
String imageFilePath = "doc/Mouche.tif";
// Launch ImageJ.
ImageJ ij = new ImageJ();
ij.launch( args );
// Load the image.
Object obj = ij.io().open( new File( currentFolder, imageFilePath ).getAbsolutePath() );
Object obj = ij.io().open( new File( imageFilePath ).getAbsolutePath() );
// Display it.
ij.ui().show( obj );
ij.command().run( Zellige.class, true );
}
......
......@@ -30,67 +30,64 @@ package fr.pasteur.ida.zellige.element;
import net.imglib2.img.Img;
import net.imglib2.type.NativeType;
import net.imglib2.type.logic.BitType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.type.numeric.integer.UnsignedShortType;
public class Projection< T extends RealType< T > & NativeType< T > >
{
private final int offset;
private final int deltaZ;
private String method;
private final ReferenceSurface<T> referenceSurface;
private Img< T > projection;
private Img< UnsignedShortType > extractedHeightMap;
private Img< T > segmentedSurface;
private Img< T > reduced3DSpace;
private Img< BitType > segmentedSurfaceMask;
private int index;
private Img<T> subVolume;
public Img< T > getSegmentedSurface()
public Projection( int offset, int deltaZ, String method, ReferenceSurface< T > referenceSurface )
{
return segmentedSurface;
this.offset = offset;
this.deltaZ = deltaZ;
this.method = method;
this.referenceSurface = referenceSurface;
}
public void setSegmentedSurface( Img< T > segmentedSurface )
public Img< T > get()
{
this.segmentedSurface = segmentedSurface;
return projection;
}
public Img< UnsignedShortType > getExtractedHeightMap()
public void setProjection( Img< T > projection )
{
return extractedHeightMap;
this.projection = projection;
}
public void setExtractedHeightMap( Img< UnsignedShortType > extractedHeightMap )
public Img< T > getSubVolume()
{
this.extractedHeightMap = extractedHeightMap;
return subVolume;
}
public Img< T > get()
public int getOffset()
{
return projection;
return offset;
}
public void setProjection( Img< T > projection )
public int getDeltaZ()
{
this.projection = projection;
return deltaZ;
}
public Img< T > getReduced3DSpace()
public String getMethod()
{
return reduced3DSpace;
return method;
}
public void setReduced3DSpace( Img< T > reduced3DSpace )
public void setSubVolume( Img< T > subVolume )
{
this.reduced3DSpace = reduced3DSpace;
this.subVolume = subVolume;
}
public Img< BitType > getSegmentedSurfaceMask()
public void setMethod( String method )
{
return segmentedSurfaceMask;
this.method = method;
}
public void setSegmentedSurfaceMask( Img< BitType > segmentedSurfaceMask )
{
this.segmentedSurfaceMask = segmentedSurfaceMask;
}
}
......@@ -28,6 +28,7 @@
*/
package fr.pasteur.ida.zellige.element;
import net.imglib2.RandomAccess;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.img.Img;
import net.imglib2.img.ImgFactory;
......@@ -35,14 +36,18 @@ import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.type.numeric.integer.UnsignedShortType;
import static fr.pasteur.ida.zellige.steps.Utils.setPositionAndGet;
public class ReferenceSurface< T extends RealType< T > & NativeType< T > >
{
private final RandomAccessibleInterval< T > input;
private final ImgFactory< T > factory;
private final Img< UnsignedShortType > zMap;
private final int index;
private Projection< T > projection;
private final String name;
private final Img <T> rawProjection;
public ReferenceSurface( RandomAccessibleInterval< T > input,
ImgFactory< T > factory, Img< UnsignedShortType > zMap, int index )
......@@ -50,13 +55,35 @@ public class ReferenceSurface< T extends RealType< T > & NativeType< T > >
this.input = input;
this.factory = factory;
this.zMap = zMap;
this.projection = new Projection<>();
this.rawProjection = factory.create(zMap);
this.index = index;
this.name = "Reference Surface n°" + (index + 1);
setRawProjection();
}
public Projection< T > getProjection()
/**
* Creates the raw height map projection
*/
private void setRawProjection()
{
return projection;
RandomAccess<T> projectionAccess = rawProjection.randomAccess();
RandomAccess< UnsignedShortType > zMapAccess = zMap.randomAccess();
RandomAccess <T > inputAccess = input.randomAccess();
for ( int x = 0; x < zMap.dimension (0 ); x++ )
{
for ( int y = 0; y <zMap.dimension (1 ); y++ )
{
// Z value on Height Map
int z = setPositionAndGet( zMapAccess, x, y ).getInteger();
if( z > 0 )
{
// pixel value on input
T value = setPositionAndGet( inputAccess, x, y, z - 1 );
// Set value on projection
setPositionAndGet( projectionAccess, x, y ).set( value );
}
}
}
}
public RandomAccessibleInterval< T > getInput()
......@@ -74,14 +101,14 @@ public class ReferenceSurface< T extends RealType< T > & NativeType< T > >
return zMap;
}
public int getIndex()
public String getName()
{
return index;
return name;
}
public void init()
public int getIndex()
{
this.projection = new Projection<>();
return index;
}
}
......
......@@ -149,43 +149,6 @@ public class Surface
return inCommon / ( double ) count;
}
public boolean isTheSameSurfaceAs( Surface other )
{
for ( int i = 0; i <= this.getHeight() - 1; i++ )
{
SurfaceLine refLine = this.get( i );
if ( refLine != null )
{
SurfaceLine toTest = other.get( i );
if ( toTest != null )
{
for ( int j = 0; j < refLine.getLength(); j++ )
{
Pixels refPixels = refLine.get( j );
if ( refPixels != null )
{
Pixels pixelsToTest = toTest.get( j );
if ( pixelsToTest != null )
{
// return false;
// }
if ( ! refPixels.equals( pixelsToTest ) )
{
return false;
}
}
}
}
}
}
}
return true;
}
/**
* Checks if this object shares a majority of {@link Pixels} with another {@link Surface} object.
*
......
......@@ -36,9 +36,7 @@ import java.util.ArrayList;
public abstract class AbstractOSE extends ArrayList< Coordinate >
{
/* Not necessary for the program.*/
private final OSEStartingStatus startingStatus;
/*-------------*/
/**
* The visited status for the 1D and 2D reconstructions.
......@@ -62,10 +60,8 @@ public abstract class AbstractOSE extends ArrayList< Coordinate >
*/
public void set()
{
Integer j = startingStatus.get( this.size() );
startingStatus.put( this.size(), ( j == null ) ? 1 : j + 1 );
startingStatus.compute( this.size(), ( k, j ) -> ( j == null ) ? 1 : j + 1 );
startingStatus.setOSCount();
}
/**
......
......@@ -37,7 +37,6 @@ import java.util.Collection;
public class OSEList extends ArrayList< AbstractOSE >
{
public OSEList()
{
}
......@@ -66,6 +65,10 @@ public class OSEList extends ArrayList< AbstractOSE >
return add;
}
/**
*
* @return the size of the OSE list
*/
public int getSize()
{
int size = 0;
......@@ -76,6 +79,9 @@ public class OSEList extends ArrayList< AbstractOSE >
return size;
}
/**
* Resets to false the visited status
*/
public void reset()
{
for ( AbstractOSE os : this )
......@@ -84,6 +90,10 @@ public class OSEList extends ArrayList< AbstractOSE >
}
}
/**
*
* @return true if the OSE list contains a starting OSE
*/
public boolean containsAStart()
{
for ( AbstractOSE os : this )
......
......@@ -74,14 +74,15 @@ public abstract class SurfaceLine
this.dimension = new Pixels[ length ] ;
set( os );
}
public SurfaceLine( AbstractOSE os, int size )
{
this.dimension = new Pixels[ size] ;
set( os );
}
/**
*
* @param os
* @param overlap
* @param connexity
* @param surfaceLine
* @return
*/
public SurfaceLine match2( AbstractOSE os, int overlap, double connexity, SurfaceLine surfaceLine )
{
int match = 0;
......
......@@ -44,6 +44,15 @@ public class SurfaceLineX extends SurfaceLine
this.setLine( os.get( 0 ).getY() );
}
/**
* Tests if the OS matches the SurfaceLine instance and creates a new SurfaceLine object if so.
*
* @param os - the OS to test against the SurfaceLine instance.
* @param direction - an integer witch indicates the line of the resulting SurfaceLine.
* @param overlap - the minimum number of matching coordinates.
* @param connexity - the minimum percentage of match between the OS and the current instance.
* @return - a new SurfaceLine if there is a match, null otherwise.
*/
public SurfaceLine match( AbstractOSE os, int direction, int overlap, double connexity )
{
SurfaceLineX surfaceLineX = new SurfaceLineX( this.getLength(), this.getLine() + direction );
......@@ -61,12 +70,4 @@ public class SurfaceLineX extends SurfaceLine
super(length, line );
}
public SurfaceLineX( AbstractOSE os, int size )
{
super( os , size);
this.setLine( os.get( 0 ).getY() );
}
}
......@@ -66,8 +66,6 @@ public class SurfaceLineY extends SurfaceLine
* @param connexity - the minimum percentage of match between the OS and the current instance.
* @return - a new SurfaceLine if there is a match, null otherwise.
*/
public SurfaceLine match( AbstractOSE os, int direction, int overlap, double connexity )
{
SurfaceLineY surfaceLineY = new SurfaceLineY( this.getLength(), this.getLine() + direction );
......
package fr.pasteur.ida.zellige.gui;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.layout.Pane;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class ChannelPanel extends Pane implements Initializable
{
@FXML
private Spinner<Integer> deltaZ;
@FXML
private ChoiceBox<String> method;
@FXML
private Spinner<Integer> offset;
@FXML
private Button view;
public ChannelPanel( )
{
FXMLLoader fxmlLoader = new FXMLLoader( ChannelPanel.class.getClassLoader().
getResource( "fr.pasteur.ida.zellige.gui.view/ChannelProjection.fxml" ) );
fxmlLoader.setRoot(this);
fxmlLoader.setController( this );
try
{
fxmlLoader.load();
}
catch ( IOException e )
{
e.printStackTrace();
}
}
@Override
public void initialize( URL url, ResourceBundle resourceBundle )
{
SpinnerValueFactory< Integer > valueFactory =
new SpinnerValueFactory.IntegerSpinnerValueFactory( 0, 30, 1, 1 );
deltaZ.setValueFactory( valueFactory );
ObservableList< String > list = FXCollections.observableArrayList( "MIP", "Mean" );
method.setItems( list );
method.getSelectionModel().selectFirst();
SpinnerValueFactory< Integer > valueFactory2 =
new SpinnerValueFactory.IntegerSpinnerValueFactory( 0, 30, 0, 1 );
offset.setValueFactory( valueFactory2 );
}
public Spinner< Integer > getDeltaZ()
{
return deltaZ;
}
public ChoiceBox< String > getMethod()
{
return method;
}
public Spinner< Integer > getOffset()
{
return offset;
}
public Button getView()
{
return view;
}
}
package fr.pasteur.ida.zellige.gui;
import javafx.beans.property.*;
import net.imglib2.img.Img;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
public class ChannelToolProperty < T extends RealType< T > & NativeType< T > >
{
private final IntegerProperty deltaZ = new SimpleIntegerProperty();
private final IntegerProperty offset = new SimpleIntegerProperty();
private final StringProperty method = new SimpleStringProperty("");
private final SimpleObjectProperty< Img< T > > subVolume = new SimpleObjectProperty<>();
private final SimpleObjectProperty< Img< T > > projection = new SimpleObjectProperty<>();
// private final SimpleObjectProperty< RandomAccessibleInterval<T> > reducedStack = new SimpleObjectProperty<>();
// private final BooleanProperty parameterChanged = new SimpleBooleanProperty( true );
// private final SimpleObjectProperty< RandomAccessibleInterval<T>> projection = new SimpleObjectProperty<>();
public StringProperty getMethod()
{
return method;
}
public IntegerProperty getOffset()
{
return offset;
}
public IntegerProperty getDeltaZ()
{
return deltaZ;
}
// public void setProperties(int delta, int offset, String method)
// {
//
// getDeltaZ().set( delta);
// getOffset().set( offset );
// getMethod().set( method );
// }
public ChannelToolProperty()
{
deltaZ.addListener(( observableValue, number, newValue ) ->
{
if (number.intValue() != newValue.intValue())
{
subVolume.set( null );
projection.set( null );
}
});
offset.addListener(( observableValue, number, newValue ) ->
{
if (number.intValue() != newValue.intValue())
{
subVolume.set( null );
projection.set( null );
}
});
method.addListener(( observableValue, number, newValue ) ->
{
if (! number.equals( newValue))
{
projection.set( null );
}
});
}
public SimpleObjectProperty< Img< T > > getSubVolume()
{
return subVolume;
}
public SimpleObjectProperty< Img< T > > getProjection()
{
return projection;
}
}
package fr.pasteur.ida.zellige.gui;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import java.io.IOException;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.VBox;
public class ConstructionDisplay extends VBox
{
@FXML
private Label surfaceNb;
@FXML
private FlowPane display;
@FXML
private Label log;
@FXML
private Button minus;
@FXML
private Button plus;
private int surfaceNumber = 1;
private int nbOfSurfaces;
public ConstructionDisplay( )
{
FXMLLoader fxmlLoader = new FXMLLoader( ConstructionDisplay.class.getClassLoader().getResource(
"fr.pasteur.ida.zellige.gui.view/ConstructionDisplay.fxml" ) );
fxmlLoader.setRoot( this );
fxmlLoader.setController( this );
try
{
fxmlLoader.load();
}
catch ( IOException e )
{
e.printStackTrace();
}
}
public void next()
{
if (surfaceNumber == nbOfSurfaces)
{
surfaceNumber = 1;
}
else
{
surfaceNumber++;
}
}
public void previous()
{
if (surfaceNumber == 1)
{
surfaceNumber = nbOfSurfaces;
}
else
{
surfaceNumber--;
}
}
public void set( ImageView image, int index )
{
display.getChildren().add( image );
surfaceNb.setText( "Height map n°" + index );
if ( nbOfSurfaces == 1 )
{
log.setText( "Extraction of " + nbOfSurfaces + " height map." );
}
else
{
log.setText( "Extraction of " + nbOfSurfaces + " height maps." );
}
}
public void setNbOfSurfaces( int nbOfSurfaces )
{
this.nbOfSurfaces = nbOfSurfaces;
}
public Label getLog()
{
return log;
}
public Button getMinus()
{
return minus;
}
public Button getPlus()
{
return plus;
}
public int getSurfaceNumber()
{
return surfaceNumber;
}
public int getNbOfSurfaces()
{
return nbOfSurfaces;
}
public void setSurfaceNumber( int surfaceNumber )
{
this.surfaceNumber = surfaceNumber;
}
public FlowPane getDisplay()
{
return display;
}
}
......@@ -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
......@@ -28,60 +28,50 @@
*/
package fr.pasteur.ida.zellige.gui;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.image.*;
import net.imglib2.Cursor;
import net.imglib2.IterableInterval;
import net.imglib2.type.logic.BitType;
import net.imglib2.algorithm.stats.Normalize;
import net.imglib2.img.Img;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.util.ImgUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ImageFXDisplay
{
private final static Logger LOGGER = LoggerFactory.getLogger( ImageFXDisplay.class );
private final IterableInterval< BitType > input;
private final ImageView[] imageViews;
private final int width;
private final int height;
private final int depth;
public ImageFXDisplay( IterableInterval< BitType > input )
{
this.input = input;
width = ( int ) input.dimension( 0 );
height = ( int ) input.dimension( 1 );
depth = ( int ) input.dimension( 2 );
this.imageViews = new ImageView[ depth ];
}
public void set()
public static < T extends RealType< T > & NativeType< T > > void setSelectedPixels( Img< T > input, ImageView[] imageViews )
{
int[] data2 = convert2( input );
int width = ( int ) input.dimension( 0 );
int height = ( int ) input.dimension( 1 );
int depth = ( int ) input.dimension( 2 );
int[] data = convertToBinary( input, width, height, depth );
for ( int z = 0; z < depth; z++ )
{
WritableImage writableImage = new WritableImage( width, height );
PixelWriter pixelWriter = writableImage.getPixelWriter();
pixelWriter.setPixels( 0, 0, width, height, PixelFormat.getIntArgbInstance(), data2, height * width * z, width );
this.imageViews[ z ] = new ImageView( writableImage );
setImageViews( this.imageViews[ z ] );
pixelWriter.setPixels( 0, 0, width, height, PixelFormat.getIntArgbInstance(), data, height * width * z, width );
ImageView imageView = new ImageView( writableImage );
setImageViews( imageView, width, height , 270);
imageViews[ z ] = imageView;
}
LOGGER.debug( "Selected pixels ImageViews set." );
}
public int[] convert2( IterableInterval< BitType > input )
public static < T extends RealType< T > & NativeType< T > > int[] convertToBinary( IterableInterval< T > input, int width, int height, int depth )
{
int[] data = new int[ height * width * depth ];
Cursor< BitType > cursor = input.cursor();
Cursor< T > cursor = input.cursor();
int index = 0;
System.out.println( 0xFFFFFFFF );
while ( cursor.hasNext() )
{
cursor.fwd();
if ( cursor.get().get() )
if ( cursor.next().getRealFloat() > 0 )
{
data[ index++ ] = ( 0xFFFFFFFF );
}
......@@ -89,37 +79,101 @@ public class ImageFXDisplay
{
data[ index++ ] = 0xFF000000;
}
}
LOGGER.debug( "Selected pixels data converted for selected pixels display.");
return data;
}
public ImageView[] getImageViews()
public static < T extends RealType< T > & NativeType< T > > void setHM( Img< T > input, ImageView[] imageViews, int index )
{
return this.imageViews;
int width = ( int ) input.dimension( 0 );
int height = ( int ) input.dimension( 1 );
int[] data = convertToGrays( normalize( input ), width, height );
WritableImage writableImage = new WritableImage( width, height );
PixelWriter pixelWriter = writableImage.getPixelWriter();
pixelWriter.setPixels( 0, 0, width, height, PixelFormat.getIntArgbInstance(), data, 0, width );
ImageView imageView = new ImageView( writableImage );
setImageViews( imageView, width, height, 300 );
imageViews[ index ] = imageView;
LOGGER.debug( "Height Map ImageView set." );
}
public void setImageViews( ImageView imageView )
public static < T extends RealType< T > & NativeType< T > > int[] convertToGrays( IterableInterval< T > input, int width, int height )
{
imageView.setPreserveRatio( true );
setFit( imageView );
int[] data = new int[ height * width ];
Cursor< T > cursor = input.cursor();
int index = 0;
while ( cursor.hasNext() )
{
int value = ( int ) cursor.next().getRealFloat();
data[ index++ ] = ( 255 ) << 24 | ( 0xFF & value ) << 16 | ( 0xFF & value ) << 8 | ( 0xFF & value );
}
LOGGER.debug( "Height map data converted for construction display.");
return data;
}
public static void setImageViews( ImageView imageView, int width, int height, int size )
{
imageView.setPreserveRatio( true );
setFit( imageView, width, height , size);
imageView.setSmooth( true );
imageView.setCache( true );
}
public void setFit( ImageView imageView )
public static void setFit( ImageView imageView, int width, int height, int size )
{
if ( width >= height )
{
imageView.setFitWidth( 254 );
imageView.setFitWidth( size );
}
else
{
imageView.setFitHeight( 254 );
imageView.setFitHeight( size );
}
}
public static < T extends RealType< T > & NativeType< T > > Img< T > normalize( Img< T > input )
{
Img< T > normalizedImage = input.factory().create( input.dimensionsAsLongArray() );
ImgUtil.copy( input, normalizedImage );
T min = normalizedImage.firstElement().createVariable();
min.setReal( 0 );
T max = normalizedImage.firstElement().copy().createVariable();
max.setReal( 255 );
Normalize.normalize( normalizedImage, min, max );
return normalizedImage;
}
/**
* Creates a copy of an array of ImageView objects.
*
* Each ImageView in the new array is a separate instance
* with the same image and properties as the original.
*
* @param original The original array of ImageView objects to copy.
* @return A new array of ImageView objects with the same content.
*/
public static ImageView[] copyImageViewArray(ImageView[] original) {
if (original == null) {
return null;
}
ImageView[] copy = new ImageView[original.length];
for (int i = 0; i < original.length; i++) {
if (original[i] != null) {
ImageView originalView = original[i];
ImageView newView = new ImageView(originalView.getImage());
// Optional: Copy some properties
newView.setFitWidth(originalView.getFitWidth());
newView.setFitHeight(originalView.getFitHeight());
newView.setPreserveRatio(originalView.isPreserveRatio());
newView.setSmooth(originalView.isSmooth());
copy[i] = newView;
}
}
return copy;
}
}
......@@ -51,7 +51,7 @@ public class LogAppender extends AppenderBase< ILoggingEvent >
protected void append( ILoggingEvent iLoggingEvent )
{
String level = iLoggingEvent.getLevel().toString();
if ( level.equals( Level.INFO.toString() ) )
if ( level.equals( Level.INFO.toString()) && iLoggingEvent.getMarker().contains( "GUI" ))
{
logMessage.setValue( iLoggingEvent.getFormattedMessage() );
}
......
......@@ -45,6 +45,8 @@ import org.scijava.log.LogService;
import org.scijava.plugin.Parameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import javax.swing.*;
import java.awt.*;
......@@ -57,7 +59,7 @@ import java.util.ResourceBundle;
public class MainAppFrame extends JFrame
{
private final static Logger LOGGER = LoggerFactory.getLogger( MainAppFrame.class );
public static final Marker GUI_MARKER = MarkerFactory.getMarker("GUI");
private ImageJ ij;
private final ImageDisplayService image;
@Parameter
......@@ -86,15 +88,21 @@ public class MainAppFrame extends JFrame
*/
public void setLogStatus()
{
LoggerContext lc = ( LoggerContext ) LoggerFactory.getILoggerFactory();
PatternLayoutEncoder ple = new PatternLayoutEncoder();
ple.setPattern( "%msg%n" );
ple.setContext( lc );
ple.start();
LogAppender appender = new LogAppender();
// Get the logger context
LoggerContext context = ( LoggerContext ) LoggerFactory.getILoggerFactory();
// Configure the log pattern
PatternLayoutEncoder layout = new PatternLayoutEncoder();
layout.setPattern( "%msg%n" );
layout.setContext( context );
layout.start();
appender.setContext( lc );
// Create and start the custom LogAppender
LogAppender appender = new LogAppender();
appender.setContext( context );
appender.start();
// Get the root logger and add the appender
ch.qos.logback.classic.Logger logbackLogger =
( ch.qos.logback.classic.Logger ) LoggerFactory.getLogger( Logger.ROOT_LOGGER_NAME );
logbackLogger.addAppender( appender );
......@@ -102,7 +110,6 @@ public class MainAppFrame extends JFrame
public MainAppFrame( Context context )
{
// this.ij = context.;
this.image = context.getService( ImageDisplayService.class );
this.logService = context.getService( LogService.class );
this.setIconImages( ICONS );
......@@ -160,21 +167,19 @@ public class MainAppFrame extends JFrame
{
ResourceBundle bundle = ResourceBundle.getBundle( "gui" );// access to properties f
FXMLLoader loader = new FXMLLoader( MainAppFrame.class.getClassLoader().getResource( "fr.pasteur.ida.zellige.gui.view/Main.fxml" ), bundle );
VBox rootLayout = loader.load();
// Get the controller and add an ImageJ context to it.
MainController< T > controller = loader.getController();
controller.setMainApp( this );
// Show the scene containing the root layout.
scene = new Scene( rootLayout );
this.fxPanel.setScene( scene );
// Resize the JFrame to the JavaFX scene
this.setSize( ( int ) scene.getWidth() + 20, ( int ) scene.getHeight() + 50 );
controller.initExtraction();
// controller.initExtraction();
}
catch ( IOException e )
{
......@@ -183,4 +188,6 @@ public class MainAppFrame extends JFrame
}
}
......@@ -29,7 +29,9 @@
package fr.pasteur.ida.zellige.gui;
import javafx.beans.NamedArg;
import javafx.beans.binding.NumberExpressionBase;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.Property;
import javafx.beans.property.StringProperty;
import javafx.css.PseudoClass;
import javafx.fxml.FXML;
......@@ -134,6 +136,8 @@ public abstract class ParameterSlider extends GridPane
}
public void enable()
{
this.getSlider().setDisable( false );
......@@ -186,6 +190,16 @@ public abstract class ParameterSlider extends GridPane
{
this.sliderProperty().set( value );
}
public Number getValue ()
{
return this.sliderProperty().getValue();
}
public String getName()
{
return name;
}
}
......
......@@ -75,4 +75,6 @@ public class ParameterSliderInteger extends ParameterSlider
}
}