package fr.unistra.pelican.algorithms.segmentation.labels; import java.util.Vector; 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; import fr.unistra.pelican.InvalidNumberOfParametersException; import fr.unistra.pelican.InvalidTypeOfParameterException; import fr.unistra.pelican.algorithms.arithmetic.DeleteSmallValues; import fr.unistra.pelican.algorithms.arithmetic.EuclideanNorm; import fr.unistra.pelican.algorithms.io.ImageLoader; import fr.unistra.pelican.algorithms.morphology.gray.GrayGradient; import fr.unistra.pelican.algorithms.segmentation.Watershed; import fr.unistra.pelican.algorithms.visualisation.Viewer2D; import fr.unistra.pelican.util.morphology.FlatStructuringElement2D; /** * This classe convert an label image to an image. For each label it associate * some attributes. * @author Sébastien Derivaux */ public class LabelsToAttributes extends Algorithm { // Inputs parameters public Image labelImage; public Image baseImage; // Outputs parameters public Image outputImage; /** * Constructor * */ public LabelsToAttributes() { super(); super.inputs = "labelImage,baseImage"; super.outputs = "outputImage"; ; } /* * (non-Javadoc) * * @see fr.unistra.pelican.Algorithm#launch() */ public void launch() throws AlgorithmException { outputImage = new DoubleImage(baseImage.getXDim(), baseImage.getYDim(), 1, 1, baseImage.getBDim() * 2); Vector<double[]> labels = new Vector<double[]>(); // Grab all pixels values int xDim = outputImage.getXDim(); int yDim = outputImage.getYDim(); int bDim = outputImage.getBDim(); for (int x = 0; x < xDim; x++) for (int y = 0; y < yDim; y++) { int label = labelImage.getPixelXYBInt(x, y, 0); if (labels.size() <= label) labels.setSize(label + 1); // value[0] = number of pixels // value[b+1] = sum of pixels with this label for band b double value[] = labels.get(label); if (value == null) { value = new double[bDim * 2 + 1]; } value[0] = value[0] + 1.0; for (int b = 0; b < bDim; ++b) value[b + 1] += baseImage.getPixelXYBDouble(x, y, b); labels.set(label, value); } // Calculate the mean. for (int i = 0; i < labels.size(); i++) for (int b = 0; b < bDim; ++b) { double value[] = labels.get(i); if (value == null) continue; value[b + 1] = value[b + 1] / value[0]; } // Set each pixel value for (int x = 0; x < xDim; x++) for (int y = 0; y < yDim; y++) { int label = labelImage.getPixelXYBInt(x, y, 0); double value[] = labels.get(label); if (value == null) throw new AlgorithmException( "Label with no pixel but in use????"); for (int b = 0; b < bDim; ++b) outputImage.setPixelXYBDouble(x, y, b, value[b + 1]); } // Compuet stddev for (int x = 0; x < xDim; x++) for (int y = 0; y < yDim; y++) { int label = labelImage.getPixelXYBInt(x, y, 0); double value[] = labels.get(label); if (value == null) throw new AlgorithmException( "Label with no pixel but in use????"); for (int b = 0; b < bDim; ++b) value[2 * bDim + 1] += value[b + 1] - baseImage.getPixelXYBDouble(x, y, b); labels.set(label, value); } } public static void main(String[] args) { String file = "samples/remotesensing1.png"; if (args.length > 0) file = args[0]; BooleanImage se3 = FlatStructuringElement2D .createSquareFlatStructuringElement(3); try { // Load the image Image source = (Image) new ImageLoader().process(file); new Viewer2D().process(source, "Image " + file); // Compute the gradient on each band Image work = (Image) new GrayGradient().process(source, se3); // Compute the euclidian distance of the gradient work = (Image) new EuclideanNorm().process(work); work = (Image) new DeleteSmallValues().process(work, 0.2); // Process a watershed transformation work = (Image) new Watershed().process(work); work = (Image) new DeleteFrontiers().process(work); // View it new Viewer2D().process(new LabelsToAttributes().process(work, source), "Segmentation of " + file); } catch (InvalidTypeOfParameterException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (AlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidNumberOfParametersException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }