/** * */ package fr.unistra.pelican.algorithms.morphology.fuzzy; import fr.unistra.pelican.Algorithm; import fr.unistra.pelican.AlgorithmException; import fr.unistra.pelican.Image; import fr.unistra.pelican.util.morphology.GrayStructuringElement; import fr.unistra.pelican.util.morphology.complements.FuzzyComplement; import fr.unistra.pelican.util.morphology.fuzzyNorms.FuzzyTCoNorm; /** * Fuzzy erosion as defined by Bloch and Maitre * Works with double image with values in [0;1] * @author Benjamin Perret * */ public class FuzzyErosion extends Algorithm { /** * Input image */ public Image inputImage; /** * Structuring function */ public GrayStructuringElement se; /** * TcoNorm */ public FuzzyTCoNorm s; /** * Complementing function */ public FuzzyComplement c; /** * Result */ public Image outputImage; /** * Constructor * */ public FuzzyErosion() { super(); super.inputs = "inputImage,se,s,c"; super.outputs = "outputImage"; } /** * Return the min value under a flat structuring element. * * @param x * @param y * @param z * @param t * @param b * @return */ private double getMinGray( int x, int y, int z, int t, int b ) { double min = Double.MAX_VALUE; boolean flag = false; int col = se.getXDim(); int row = se.getYDim(); for ( int i = 0 ; i < col ; i++ ) for ( int j = 0 ; j < row ; j++ ) { int valX = x - se.getCenter().x + i; int valY = y - se.getCenter().y + j; if ( valX >= 0 && valX < inputImage.getXDim() && valY >= 0 && valY < inputImage.getYDim() && inputImage.isPresent( valX,valY,z,t,b ) ) { double value = s.tCoDistance( c.complement( se.getPixelXYDouble(row-j-1, col-i-1) ), inputImage.getPixelDouble( valX,valY,z,t,b ) ); if ( min > value ) min = value; flag = true; } } // FIXME: Strange, if nothing is under the se, what is the right way? return (flag == true) ? min : inputImage.getPixelDouble(x, y, z, t, b); } /* * (non-Javadoc) * * @see fr.unistra.pelican.Algorithm#launch() */ public void launch() throws AlgorithmException { outputImage = inputImage.copyImage(false); int xDim = inputImage.getXDim(); int yDim = inputImage.getYDim(); int tDim = inputImage.getTDim(); int bDim = inputImage.getBDim(); int zDim = inputImage.getZDim(); boolean isHere; for ( int b = 0 ; b < bDim ; b++ ) for ( int t = 0 ; t < tDim ; t++ ) for ( int z = 0 ; z < zDim ; z++ ) for ( int y = 0 ; y < yDim ; y++ ) for ( int x = 0 ; x < xDim ; x++ ) { isHere = this.inputImage.isPresent( x,y,z,t,b ); if ( !isHere ) continue; outputImage.setPixelDouble( x,y,z,t,b, getMinGray( x,y,z,t,b ) ); } } /** * Fuzzy erosion as defined by Bloch and Maitre * Works with double image with values in [0;1] * * @param inputImage Input image * @param se Functional Structuring Element * @param s TCoNorm * @param c Complement function * @return eroded image */ public static Image exec(Image inputImage, GrayStructuringElement se, FuzzyTCoNorm s, FuzzyComplement c) { return (Image) new FuzzyErosion().process(inputImage,se,s,c); } }