package fr.unistra.pelican.algorithms.spatial; import fr.unistra.pelican.Algorithm; import fr.unistra.pelican.ByteImage; import fr.unistra.pelican.Image; import fr.unistra.pelican.algorithms.arithmetic.Inversion; import fr.unistra.pelican.algorithms.io.ImageLoader; import fr.unistra.pelican.algorithms.io.ImageSave; import fr.unistra.pelican.algorithms.visualisation.Viewer2D; import fr.unistra.pelican.util.morphology.StructuringElement; /** * This class performs a cyclic transform. WORKS ONLY WITH IMAGES OF 2^n PIXELS * * @author */ public class CyclicTransform extends Algorithm { /** * The input image */ public Image inputImage; /** * The size of the transform, default value -1 for transform until convergence */ public int size = -1; /** * Flag to perform the dual transform */ public boolean dual = false; /** * The output image */ public Image outputImage; /** * Default constructor */ public CyclicTransform() { super.inputs = "inputImage"; super.options = "size,dual"; super.outputs = "outputImage"; } /** * Performs a cyclic transform * * @param inputImage * The input image * @param size * The size of the transform * @return The output image */ public static Image exec(Image inputImage, int size, boolean dual) { return (Image) new CyclicTransform().process(inputImage, size, dual); } public static Image exec(Image inputImage, boolean dual) { return (Image) new CyclicTransform().process(inputImage, null, dual); } public static Image exec(Image inputImage, int size) { return (Image) new CyclicTransform().process(inputImage, size); } public static Image exec(Image inputImage) { return (Image) new CyclicTransform().process(inputImage); } /* * (non-Javadoc) * * @see fr.unistra.pelican.Algorithm#launch() */ public void launch() { outputImage = inputImage.copyImage(true); Image tmp; double v1, v2, min, max; // Check the size parameter if (size == -1) size = inputImage.size(); while (Math.pow(2, size) > inputImage.size()) size--; // Check if the image size is equal to 2^n double log2 = Math.log(inputImage.size()) / Math.log(2); // System.out.println(log2); if (log2 != (int) log2) return; // System.out.println("size="+size); int comp = inputImage.size() / 2; int shift = inputImage.size(); for (int i = 1; i < size + 1; i++) { tmp = outputImage.copyImage(true); shift /= 2; int j = 0; for (int k = 0; k < comp; k++) { // System.out.println(k+" "+j+" "+(j+shift)); v1 = tmp.getPixelDouble(j); v2 = tmp.getPixelDouble(j + shift); if ((!dual && v1 < v2) || (dual && v1 > v2)) { min = v1; max = v2; } else { min = v2; max = v1; } outputImage.setPixelDouble(j, max); outputImage.setPixelDouble(j + shift, min); j++; if (j % shift == 0) j += shift; } } } public static void main(String args[]) { Image img = null; // // Translation invariance // img=ImageLoader.exec("samples/stample.png"); // Viewer2D.exec(img); // Viewer2D.exec(CyclicTransform.exec(img)); img = ImageLoader.exec("samples/stample2.png"); Viewer2D.exec(img); Viewer2D.exec(CyclicTransform.exec(img)); // // Idempotence // Viewer2D.exec(CyclicTransform.exec(img)); // Viewer2D.exec(CyclicTransform.exec(CyclicTransform.exec(img))); // // Duality // Viewer2D.exec(Inversion.exec(CyclicTransform.exec(Inversion.exec(img)))); // Viewer2D.exec(CyclicTransform.exec(img,true)); } }