package fr.unistra.pelican.algorithms.arithmetic;
import fr.unistra.pelican.Algorithm;
import fr.unistra.pelican.AlgorithmException;
import fr.unistra.pelican.Image;
import fr.unistra.pelican.InvalidParameterException;
import fr.unistra.pelican.util.mask.MaskStack;
/**
* Compute a normalized difference (image1-image2)/(image1+image2).
* The domain of results [-1;1] is normalized to [0;1].
*
* outputPixel = ( ( inputPixel1 - inputPixel2 ) / ( inputPixel1 + inputPixel2 ) + 1 ) / 2
*
* Works on double precision.
* Result is of same type as first input.
*
* @author Jonathan Weber, Benjamin Perret
*
*/
public class NormalizedDifference extends Algorithm {
/**
* First input image
*/
public Image image1;
/**
* Second input image
*/
public Image image2;
/**
* Result
*/
public Image outputImage;
/**
* Constructor
*
*/
public NormalizedDifference() {
super();
super.inputs = "image1,image2";
super.outputs = "outputImage";
}
/*
* (non-Javadoc)
*
* @see fr.unistra.pelican.Algorithm#launch()
*/
public void launch() throws AlgorithmException {
if(Image.haveSameDimensions(image1, image2))
{
outputImage = image1.copyImage(false);
MaskStack mask = new MaskStack( MaskStack.OR );
mask.push( image1.getMask() );
mask.push( image2.getMask() );
outputImage.setMask( mask );
boolean isHere1, isHere2;
for ( int b = 0 ; b < image1.getBDim() ; b++ )
for ( int t = 0 ; t < image1.getTDim() ; t++ )
for ( int z = 0 ; z < image1.getZDim() ; z++ )
for ( int y = 0 ; y < image1.getYDim() ; y++ )
for ( int x = 0 ; x < image1.getXDim() ; x++ ) {
isHere1 = image1.isPresent( x,y,z,t,b );
isHere2 = image2.isPresent( x,y,z,t,b );
double pixel1 = image1.getPixelDouble( x,y,z,t,b );
double pixel2 = image2.getPixelDouble( x,y,z,t,b );
double ND = 0.;
if ( isHere1 && isHere2 )
ND = ((( pixel1 - pixel2 ) / ( pixel1+pixel2 )) +1. ) /2.;
else if ( isHere1 && !isHere2 ) ND = pixel1;
else if ( !isHere1 && isHere2 ) ND = pixel2;
//For undefined reasons sometimes values are > 1 or < 0 so we checked them.
if( ND > 1 ) ND = 1;
else if( ND < 0 ) ND = 0;
this.outputImage.setPixelDouble( x,y,z,t,b, ND );
}
}
else throw (new InvalidParameterException("The images must have the same dimensions"));
}
/*
* Static fonction that use this algorithm.
*
* @param image
* @param number
* of band 1
* @param number
* of band 2
* @return result
* @throws InvalidTypeOfParameterException
* @throws AlgorithmException
* @throws InvalidNumberOfParametersException
public Image process(Image image, Number Band1, Number Band2)
throws InvalidTypeOfParameterException, AlgorithmException,
InvalidNumberOfParametersException {
return (Image) new NormalizedDifference().process(image.getImage4D(
((Number) Band1).intValue(), Image.B), image.getImage4D(
((Number) Band2).intValue(), Image.B));
}
*/
/**
* Compute a normalized difference (image1-image2)/(image1+image2).
* The domain of results [-1;1] is normalized to [0;1].
*
* outputPixel = ( ( inputPixel1 - inputPixel2 ) / ( inputPixel1 + inputPixel2 ) + 1 ) / 2
*
* Works on double precision.
* Result is of same type as first input.
*
* @param image1 First Input Image
* @param image2 Second Input Image
* @return Normalized Difference of inputs
*/
public static Image exec(Image image1, Image image2) {
return (Image)new NormalizedDifference().process(image1, image2);
}
}