package fr.unistra.pelican.algorithms.arithmetic; import fr.unistra.pelican.Algorithm; import fr.unistra.pelican.AlgorithmException; import fr.unistra.pelican.DoubleImage; import fr.unistra.pelican.Image; import fr.unistra.pelican.util.mask.MaskStack; /** * Combine many images with weighting coefficients. * outputPixel = inputPixel1 * coef1 + inputPixel2 * coef2 + ... + inputPixeln * coefn * * Works on double precision. * The outputImage format is DoubleImage * * @author ?, Benjamin Perret */ public class LinearCombination extends Algorithm { /** * Array of input images */ public Image[] inputImage; /** * Array of weighting coefficients */ public Double[] coef; /** * Combinaison image */ public Image outputImage; /** * Constructor * */ public LinearCombination() { super.inputs = "inputImage,coef"; super.outputs = "outputImage"; } /* * (non-Javadoc) * * @see fr.unistra.pelican.Algorithm#launch() */ public void launch() throws AlgorithmException { // check data types if (inputImage.length == 0 || coef.length == 0 || inputImage.length != coef.length) throw new AlgorithmException("Arrays are not of appropriate size"); for (int k = 1; k < inputImage.length; k++) if (!Image.haveSameDimensions(inputImage[0], inputImage[k])) throw new AlgorithmException("Images are not all comparable"); // generate output outputImage = new DoubleImage(inputImage[0].getXDim(), inputImage[0] .getYDim(), inputImage[0].getZDim(), inputImage[0].getTDim(), inputImage[0].getBDim()); int size = inputImage[0].size(); int nb = inputImage.length; double val; for (int i = 0; i < size; ++i) { val = 0; for (int k = 0; k < nb; k++) if ( inputImage[k].isPresent(i) ) val += inputImage[k].getPixelDouble(i) * coef[k]; outputImage.setPixelDouble(i, val); } MaskStack mask = new MaskStack( MaskStack.AND ); for ( int k = 0 ; k < nb ; k++ ) mask.push( this.inputImage[k].getMask() ); this.outputImage.setMask( mask ); } /** * Combine many images with weighting coefficients. * outputPixel = inputPixel1 * coef1 + inputPixel2 * coef2 + ... + inputPixeln * coefn * * Works on double precision. * The outputImage format is DoubleImage * * @param inputImage Array of images to combine * @param coef Array of weights * @return Linear combination of inputs images */ public static Image exec(Image [] inputImage, Double [] coef) { return (Image)new LinearCombination().process(inputImage, coef); } }