package fr.unistra.pelican.algorithms.segmentation.labels; import java.util.ArrayList; import fr.unistra.pelican.Algorithm; import fr.unistra.pelican.AlgorithmException; import fr.unistra.pelican.BooleanImage; import fr.unistra.pelican.Image; /** * Sets to {@link #value} pixels of the label image {@link #labels} that belong to the classes * specified by the list {@link #classes} in the samples image {@link #samples}. By default, * pixels are set to zero. * * @see fr.unistra.pelican.Algorithm * @author Régis Witz */ public class MergeLabelsFromSpecificClasses extends Algorithm { //////////// // INPUTS // //////////// /** Label image.*/ public Image labels; /** Samples wich define the classes. */ public BooleanImage samples; /** Numbers of the classes wich must be set to {@link #value}. * These are strictly positive integers. */ public ArrayList<Integer> classes; ///////////// // OPTIONS // ///////////// /** The value to wich pixels belonging to any class of {@link #classes} must be set. * By default, this field equals to 0. */ public int value = 0; ///////////// // OUTPUTS // ///////////// public Image output; ///////////////// // CONSTRUCTOR // ///////////////// public MergeLabelsFromSpecificClasses() { super(); super.inputs = "labels,samples,classes"; super.options = "overwrite,value"; super.outputs = "output"; } /////////////////// // LAUNCH METHOD // /////////////////// /** Launches this algorithm. * @see fr.unistra.pelican.Algorithm#launch() */ @Override public void launch() throws AlgorithmException { if ( this.samples.getXDim() != this.labels.getXDim() || this.samples.getYDim() != this.labels.getYDim() || this.samples.getZDim() != this.labels.getZDim() || this.samples.getTDim() != this.labels.getTDim() ) throw new AlgorithmException( this.getClass().getName() + "can't be performed with " + "these inputs. Be sure that X,Y,Z and T dimensions of label image are equal " + "to X,Y,Z and T dimensions of samples image." ); this.output = this.labels.copyImage( true ); ArrayList<Integer> deadpx = new ArrayList<Integer>(); int pxval; boolean dead; for ( int x = 0 ; x < this.samples.getXDim() ; x++ ) for ( int y = 0 ; y < this.samples.getYDim() ; y++ ) for ( int z = 0 ; z < this.samples.getZDim() ; z++ ) for ( int t = 0 ; t < this.samples.getTDim() ; t++ ) for ( int b = 0 ; b < this.samples.getBDim() ; b++ ) if ( this.classes.contains( b+1 ) ) { dead = this.samples.getPixelXYZTBBoolean( x,y,z,t,b ); if ( dead ) { pxval = this.labels.getPixelXYZTInt( x,y,z,t ); if ( !deadpx.contains( pxval ) ) deadpx.add( pxval ); } } for ( int x = 0 ; x < this.labels.getXDim() ; x++ ) for ( int y = 0 ; y < this.labels.getYDim() ; y++ ) for ( int z = 0 ; z < this.labels.getZDim() ; z++ ) for ( int t = 0 ; t < this.labels.getTDim() ; t++ ) { pxval = this.labels.getPixelXYZTInt( x,y,z,t ); if ( deadpx.contains( pxval ) ) this.output.setPixelXYZTInt( x,y,z,t, this.value ); } } ////////////////// // EXEC METHODS // ////////////////// /** Gets a copy of <tt>labels</tt> where pixels belonging to the classes specified by * <tt>classes</tt> in <tt>samples</tt> are set to zero. * * @param labels Label image. * @param samples Samples wich define the classes. * @param classes Classes wich must be set to <tt>value</tt>. * These are strictly positive integers. * * @return A rewrited label image. */ public static Image exec( Image labels, BooleanImage samples, ArrayList<Integer> classes ) { return ( Image ) new MergeLabelsFromSpecificClasses().process( labels, samples, classes ); } /** Gets a copy of <tt>labels</tt> where pixels belonging to the classes specified by * <tt>classes</tt> in <tt>samples</tt> are set to <tt>value</tt>. * * @param labels Label image. * @param samples Samples wich define the classes. * @param classes Classes wich must be set to <tt>value</tt>. * These are strictly positive integers. * @param value Value to wich pixels belonging to any class of <tt>classes</tt> must be set. * * @return A rewrited label image. */ public static Image exec( Image labels, BooleanImage samples, ArrayList<Integer> classes, int value ) { return ( Image ) new MergeLabelsFromSpecificClasses().process( labels, samples, classes, value ); } /** Gets a copy of <tt>labels</tt> where pixels belonging to the classes specified by * <tt>classes</tt> in <tt>samples</tt> are set to <tt>value</tt> if * <tt>changeOtherClassesThanThese</tt> equals <tt>false</tt>. * <p> * Gets a copy of <tt>labels</tt> where pixels <i>not</i> belonging to the classes specified * by <tt>classes</tt> in <tt>samples</tt> are set to <tt>value</tt> if * <tt>changeOtherClassesThanThese</tt> equals <tt>true</tt>. * * @param labels Label image. * @param samples Samples wich define the classes. * @param classes Classes wich must be set to <tt>value</tt>. * These are strictly positive integers. * @param value Value to wich pixels belonging to any class of <tt>classes</tt> must be set. * @param changeOtherClassesThanThese See method description. * * @return A rewrited label image. */ public static Image exec( Image labels, BooleanImage samples, ArrayList<Integer> classes, int value, boolean changeOtherClassesThanThese ) { ArrayList<Integer> relevantClasses; if ( changeOtherClassesThanThese ) { relevantClasses = new ArrayList<Integer>(); for ( int b = 0 ; b < samples.getBDim() ; b++ ) if ( !classes.contains( b+1 ) ) relevantClasses.add( b+1 ); } else relevantClasses = classes; return ( Image ) new MergeLabelsFromSpecificClasses().process( labels, samples, relevantClasses, value ); } /** Gets a copy of <tt>labels</tt> where pixels belonging to the classes specified by * <tt>classes</tt> in <tt>samples</tt> are set to 0 if <tt>changeOtherClassesThanThese</tt> * equals <tt>false</tt>. * <p> * Gets a copy of <tt>labels</tt> where pixels <i>not</i> belonging to the classes specified * by <tt>classes</tt> in <tt>samples</tt> are set to 0 if <tt>changeOtherClassesThanThese</tt> * equals <tt>true</tt>. * * @param labels Label image. * @param samples Samples wich define the classes. * @param classes Classes wich must be set to <tt>value</tt>. * These are strictly positive integers. * @param changeOtherClassesThanThese See method description. * * @return A rewrited label image. */ public static Image exec( Image labels, BooleanImage samples, ArrayList<Integer> classes, boolean changeOtherClassesThanThese ) { return ( Image ) new MergeLabelsFromSpecificClasses().process( labels, samples, classes, 0, changeOtherClassesThanThese ); } }