package fr.unistra.pelican.algorithms.morphology.generalGray;
import java.awt.Point;
import fr.unistra.pelican.Algorithm;
import fr.unistra.pelican.AlgorithmException;
import fr.unistra.pelican.Image;
import fr.unistra.pelican.util.morphology.GrayStructuringElement;
/**
* Perform a gray erosion with a functional structuring element.
* Work on a double precision.
*
* @author Benjamin Perret
*
*/
public class GeneralGrayErosion extends Algorithm {
/**
* Input image
*/
public Image inputImage;
/**
* Input functional structuring element
*/
public GrayStructuringElement se;
/**
* Result
*/
public Image outputImage;
/**
* Constructor
*/
public GeneralGrayErosion()
{
super.inputs="inputImage,se";
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, Point[] points ) {
double min = Double.MAX_VALUE;
boolean flag = false;
for(int i = 0; i < points.length; i++){
int valX = x - se.getCenter().x + points[i].x;
int valY = y - se.getCenter().y + points[i].y;
if( valX >= 0 && valX < inputImage.getXDim()
&& valY >=0 && valY <inputImage.getYDim()
&& inputImage.isPresent( valX,valY,z,t,b ) ) {
double value = inputImage.getPixelDouble(valX,valY,z,t,b);
double valueSE = se.getPixelXYDouble(points[i].x, points[i].y);
double diff = value-valueSE;
if(min > diff)
min = diff;
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();
int size = 0;
for(int i = 0; i < se.getXDim(); i++)
for(int j = 0 ; j < se.getYDim(); j++)
if(se.isValue(i,j) == true) size++;
Point[] points = new Point[size];
int k = 0;
for(int i = 0; i < se.getXDim(); i++){
for(int j = 0 ; j < se.getYDim(); j++){
if(se.isValue(i,j) == true) points[k++] = new Point(i,j);
}
}
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, points ) );
}
}
/**
* Performs a gray erosion with a 2-D functional structuring element
*
* @param image
* The input image
* @param se
* The gray structuring element used in the morphological
* operation
* @return The output image
*/
@SuppressWarnings("unchecked")
public static <T extends Image> T exec(T image, GrayStructuringElement se) {
return (T) new GeneralGrayErosion().process(image, se);
}
}