package fr.unistra.pelican.algorithms.spatial; 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; /** * Standard convolution for linear filters * * @author Lefevre */ public class Convolution extends Algorithm { /** * Input image */ public Image input; /** * Structuring element used for the convolution */ public GrayStructuringElement kernel; /** * Output image */ public Image output; /** * Constructor * */ public Convolution() { super(); super.inputs = "input,kernel"; super.outputs = "output"; } /* * (non-Javadoc) * * @see fr.unistra.pelican.Algorithm#launch() */ public void launch() throws AlgorithmException { int xDim = input.getXDim(); int yDim = input.getYDim(); int bDim = input.getBDim(); // reflect... kernel = kernel.getReflection(); // create empty output output = input.copyImage(true); //TODO: use a different SE for each band Point[] points = kernel.getPoints().get(0); // convolve and fill it up for (int b = 0; b < bDim; b++) { for (int x = 0; x < xDim; x++) { for (int y = 0; y < yDim; y++) { double gcc = 0.0; double syc = 0.0; for (int i = 0; i < points.length; i++) { int _x = x - kernel.getCenter().x + points[i].x; int _y = y - kernel.getCenter().y + points[i].y; if (_x < 0 || _x >= xDim || _y < 0 || _y >= yDim) continue; // rows,columns double p = kernel.getValue(points[i].x, points[i].y); gcc += p * input.getPixelXYBDouble(_x, _y, b); syc += p; } output.setPixelXYBDouble(x, y, b, gcc / (double) syc); } } } } /** * Standard convolution for linear filters * @param input Input image * @param kernel Structuring element used for the convolution * @return Output image */ public static <T extends Image> T exec(T input, GrayStructuringElement kernel) { return (T) new Convolution().process(input,kernel); } }