/** * */ package fr.unistra.pelican.algorithms.morphology.connected; import fr.unistra.pelican.Algorithm; import fr.unistra.pelican.AlgorithmException; import fr.unistra.pelican.BooleanImage; import fr.unistra.pelican.Image; import fr.unistra.pelican.algorithms.conversion.ProcessChannels; import fr.unistra.pelican.algorithms.io.ImageLoader; import fr.unistra.pelican.algorithms.visualisation.MViewer; import fr.unistra.pelican.util.connectivityTrees.ComponentTree; import fr.unistra.pelican.util.connectivityTrees.ComponentTreeUtil.TreeType; import fr.unistra.pelican.util.connectivityTrees.connectivity.Connectivity3D; import fr.unistra.pelican.util.connectivityTrees.connectivity.TrivialConnectivity; import fr.unistra.pelican.util.vectorial.ordering.LexicographicalOrdering; import fr.unistra.pelican.util.vectorial.ordering.VectorialBasedComponentOrdering; import fr.unistra.pelican.util.vectorial.ordering.VectorialOrdering; /** * Extract local minima or maxima of a multiband image with respect to a given connectivity and vectorial ordering. * * Maxima are just leaves of a max tree and minima leaves o a min tree * * Note that in a natural unfiltered image there will probably be a lot of maxima or minima * * @author Benjamin Perret * */ public class ExtractMinimaOrMaxima extends Algorithm { /** * Minima or maxima? * @author Benjamin Perret * */ public static enum Operation{Minima, Maxima}; /** * Input image */ public Image inputImage; /** * Operation to perform (default is extract maxima) */ public Operation op=Operation.Minima; /** * Connectivity to use (default is TrivialConnectivity.getFourNeighbourhood()) */ public Connectivity3D co= TrivialConnectivity.getFourNeighbourhood(); /** * Vectorial ordering o use */ public VectorialOrdering vo = new LexicographicalOrdering(); /** * Result */ public BooleanImage outputImage; public ExtractMinimaOrMaxima(){ super.inputs="inputImage"; super.options="op,co,vo"; super.outputs="outputImage"; } /* (non-Javadoc) * @see fr.unistra.pelican.Algorithm#launch() */ @Override public void launch() throws AlgorithmException { outputImage= new BooleanImage(inputImage.xdim,inputImage.ydim,inputImage.zdim,1,1); outputImage.fill(false); ComponentTree tree; switch (op) { case Minima: tree=BuildComponentTreeVectorial.exec(inputImage, co, new VectorialBasedComponentOrdering(vo),TreeType.Min); break; case Maxima: tree=BuildComponentTreeVectorial.exec(inputImage, co, new VectorialBasedComponentOrdering(vo),TreeType.Max); break; default: throw new AlgorithmException("Wow! you managed to create and undefnied element in an enum structure, i can't let you do that!"); } Image res=ReconstructImageFromTree.exec(tree,true); res=ProcessChannels.exec(res,ProcessChannels.MAXIMUM); for(int i=0;i<outputImage.size();i++) { double v=res.getPixelDouble(i); if(!Double.isNaN(v) && v > -Double.MAX_VALUE) outputImage.setPixelBoolean(i, true); } } public static BooleanImage exec(Image inputImage) { return (BooleanImage) new ExtractMinimaOrMaxima().process(inputImage); } public static BooleanImage exec(Image inputImage, Operation op) { return (BooleanImage) new ExtractMinimaOrMaxima().process(inputImage, op); } public static BooleanImage exec(Image inputImage, Operation op, Connectivity3D co) { return (BooleanImage) new ExtractMinimaOrMaxima().process(inputImage, op, co); } public static BooleanImage exec(Image inputImage, Operation op, Connectivity3D co, VectorialOrdering vo) { return (BooleanImage) new ExtractMinimaOrMaxima().process(inputImage, op, co, vo); } /** * @param args */ public static void main(String[] args) { Image im = ImageLoader.exec("samples/lennaGray256.png"); Image res=ExtractMinimaOrMaxima.exec(im, Operation.Maxima, TrivialConnectivity.getHeightNeighbourhood()); MViewer.exec(im,res); } }