package fr.unistra.pelican.algorithms.edge; import fr.unistra.pelican.Algorithm; import fr.unistra.pelican.AlgorithmException; import fr.unistra.pelican.BooleanImage; import fr.unistra.pelican.DoubleImage; import fr.unistra.pelican.Image; /** * This class represents the Prewitt edge detector scheme, applied as norm, * horizontal,vertical and orientation gradient. * * @author Abdullah */ public class Prewitt extends Algorithm { /** * Input image */ public Image input; /** * Type of operation (NORM,GRADX,GRADY,ORIEN) */ public int operation; /** * Gradient norm */ public static final int NORM = 0; /** * X gradient */ public static final int GRADX = 1; /** * Y gradient */ public static final int GRADY = 2; /** * Orientation gradient */ public static final int ORIEN = 3; /** * Output image */ public Image output; /** * Constructor * */ public Prewitt() { super(); super.inputs = "input,operation"; super.outputs = "output"; } /* * (non-Javadoc) * * @see fr.unistra.pelican.Algorithm#launch() */ public void launch() throws AlgorithmException { int bdim = input.getBDim(); int tdim = input.getTDim(); int zdim = input.getZDim(); int ydim = input.getYDim(); int xdim = input.getXDim(); output = new DoubleImage(xdim, ydim, zdim, tdim, bdim); output.copyAttributes(input); if (input instanceof BooleanImage) throw new AlgorithmException("BooleanImages are not supported"); switch (operation) { case GRADY: for (int b = 0; b < bdim; b++) { for (int t = 0; t < tdim; t++) { for (int z = 0; z < zdim; z++) { for (int y = 1; y < ydim - 1; y++) { for (int x = 1; x < xdim - 1; x++) { double tmp = input.getPixelXYZTBDouble(x - 1, y - 1, z, t, b) + input.getPixelXYZTBDouble(x, y - 1, z, t, b) + input.getPixelXYZTBDouble(x + 1, y - 1, z, t, b); tmp = input.getPixelXYZTBDouble(x - 1, y + 1, z, t, b) + input.getPixelXYZTBDouble(x, y + 1, z, t, b) + input.getPixelXYZTBDouble(x + 1, y + 1, z, t, b) - tmp; output.setPixelXYZTBDouble(x, y, z, t, b, tmp); } } } } } break; case GRADX: for (int b = 0; b < bdim; b++) { for (int t = 0; t < tdim; t++) { for (int z = 0; z < zdim; z++) { for (int y = 1; y < ydim - 1; y++) { for (int x = 1; x < xdim - 1; x++) { double tmp = input.getPixelXYZTBDouble(x - 1, y - 1, z, t, b) + input.getPixelXYZTBDouble(x - 1, y, z, t, b) + input.getPixelXYZTBDouble(x - 1, y + 1, z, t, b); tmp = input.getPixelXYZTBDouble(x + 1, y - 1, z, t, b) + input.getPixelXYZTBDouble(x + 1, y, z, t, b) + input.getPixelXYZTBDouble(x + 1, y + 1, z, t, b) - tmp; output.setPixelXYZTBDouble(x, y, z, t, b, tmp); } } } } } break; case NORM: for (int b = 0; b < bdim; b++) { for (int t = 0; t < tdim; t++) { for (int z = 0; z < zdim; z++) { for (int y = 1; y < ydim - 1; y++) { for (int x = 1; x < xdim - 1; x++) { double tmpy = input.getPixelXYZTBDouble(x - 1, y - 1, z, t, b) + input.getPixelXYZTBDouble(x, y - 1, z, t, b) + input.getPixelXYZTBDouble(x + 1, y - 1, z, t, b); tmpy = input.getPixelXYZTBDouble(x - 1, y + 1, z, t, b) + input.getPixelXYZTBDouble(x, y + 1, z, t, b) + input.getPixelXYZTBDouble(x + 1, y + 1, z, t, b) - tmpy; double tmpx = input.getPixelXYZTBDouble(x - 1, y - 1, z, t, b) + input.getPixelXYZTBDouble(x - 1, y, z, t, b) + input.getPixelXYZTBDouble(x - 1, y + 1, z, t, b); tmpx = input.getPixelXYZTBDouble(x + 1, y - 1, z, t, b) + input.getPixelXYZTBDouble(x + 1, y, z, t, b) + input.getPixelXYZTBDouble(x + 1, y + 1, z, t, b) - tmpx; double norm = Math.sqrt(tmpx * tmpx + tmpy * tmpy); output.setPixelXYZTBDouble(x, y, z, t, b, norm); } } } } } break; default: for (int b = 0; b < bdim; b++) { for (int t = 0; t < tdim; t++) { for (int z = 0; z < zdim; z++) { for (int y = 1; y < ydim - 1; y++) { for (int x = 1; x < xdim - 1; x++) { double tmpy = input.getPixelXYZTBDouble(x - 1, y - 1, z, t, b) + input.getPixelXYZTBDouble(x, y - 1, z, t, b) + input.getPixelXYZTBDouble(x + 1, y - 1, z, t, b); tmpy = input.getPixelXYZTBDouble(x - 1, y + 1, z, t, b) + 2 * input.getPixelXYZTBDouble(x, y + 1, z, t, b) + input.getPixelXYZTBDouble(x + 1, y + 1, z, t, b) - tmpy; double tmpx = input.getPixelXYZTBDouble(x - 1, y - 1, z, t, b) + input.getPixelXYZTBDouble(x - 1, y, z, t, b) + input.getPixelXYZTBDouble(x - 1, y + 1, z, t, b); tmpx = input.getPixelXYZTBDouble(x + 1, y - 1, z, t, b) + 2 * input.getPixelXYZTBDouble(x + 1, y, z, t, b) + input.getPixelXYZTBDouble(x + 1, y + 1, z, t, b) - tmpx; double norm = Math.atan(tmpy / tmpx) - 3 * Math.PI / 4; output.setPixelXYZTBDouble(x, y, z, t, b, norm); } } } } } } } /** * Apply the Prewitt edge detector scheme * @param image the input image * @param operation type of operation (NORM,GRADX,GRADY,ORIEN) * @return the output image */ public static DoubleImage exec(Image image, int operation) { return (DoubleImage)new Prewitt().process(image,operation); } }