package fr.unistra.pelican.algorithms.segmentation.regionMerging;
import fr.unistra.pelican.Algorithm;
import fr.unistra.pelican.AlgorithmException;
import fr.unistra.pelican.BooleanImage;
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.histogram.ContrastStretch;
import fr.unistra.pelican.algorithms.morphology.gray.GrayGradient;
import fr.unistra.pelican.algorithms.segmentation.Watershed;
import fr.unistra.pelican.algorithms.segmentation.labels.DeleteFrontiers;
import fr.unistra.pelican.algorithms.segmentation.labels.LabelsToColorByMeanValue;
import fr.unistra.pelican.util.morphology.FlatStructuringElement2D;
/**
* Maybe cf S. Beucher. Watershed, hierarchical segmentation and waterfall
* algorithm. In Mathematical Morphology and its Applications to Image
* Processing, Proc. ISMM 94, pages 69-76, Fontainebleau, France, 1994. Kluwer
* Ac. Publ.
*
* @author Sébastien Derivaux
*/
public class MergeUsingWatershed extends Algorithm {
// Inputs parameters
public Image labelImage;
public Image spaceImage;
public double threshold;
// Outputs parameters
public Image outputImage;
/**
* Constructor
*
*/
public MergeUsingWatershed() {
super();
super.inputs = "labelImage,spaceImage,threshold";
super.outputs = "outputImage";
}
/*
* (non-Javadoc)
*
* @see fr.unistra.pelican.Algorithm#launch()
*/
public void launch() throws AlgorithmException {
outputImage = labelImage.copyImage(false);
try {
Image values = (Image) new LabelsToColorByMeanValue().process(labelImage,
spaceImage);
BooleanImage se3 = FlatStructuringElement2D
.createSquareFlatStructuringElement(3);
// Compute the gradient on each band
values = (Image) new GrayGradient().process(values, se3);
// Compute the euclidian distance of the gradient
values = (Image) new EuclideanNorm().process(values);
values = (Image) new ContrastStretch().process(values);
// Reduce the gradient image with hmin to remove useless local
// minima
values = (Image) new DeleteSmallValues().process(values, threshold);
Image process = (Image) new Watershed().process(values);
// Process a watershed transformation
values = process;
values = (Image) new DeleteFrontiers().process(values);
outputImage = values;
} 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();
}
}
public static Image exec(Image labelImage, Image spaceImage, double threshold) {
return (Image)new MergeUsingWatershed().process(labelImage, spaceImage, threshold);
}
// public static void main(String[] args) {
// String file = "./samples/remotesensing1";
// if (args.length > 0)
// file = args[0];
//
// try {
// // Load the image
// Image source = (Image) new ImageLoader().process(file + ".png");
// Image regions = (Image) new RegionsLoader().process(file);
//
// System.out.println("RegionBuilderWatershedClassical of " + file);
//
// // Create regions
// Image result = (Image) new RegionBuilderWatershedClassical()
// .process(source, 0.15);
//
// // View it
// new Viewer2D().process(new DrawFrontiersOnImage().process(source,
// new FrontiersFromSegmentation().process(result)), "" + file
// + " after watershed");
// // Viewer2D.exec(LabelsToColorByMeanValue.process(result,
// // source), "RegionBuilderWatershedClassical of " + file);
// System.out.println(new EvalSegmentation().process(result, regions));
//
// result = (Image) new MergeUsingWatershed().process(result, source, 0.05);
//
// new Viewer2D().process(new DrawFrontiersOnImage().process(source,
// new FrontiersFromSegmentation().process(result)), "" + file
// + " after region merging 1");
// System.out.println(new EvalSegmentation().process(result, regions));
//
// result = (Image) new MergeUsingWatershed().process(result, source, 0.05);
//
// new Viewer2D().process(new DrawFrontiersOnImage().process(source,
// new FrontiersFromSegmentation().process(result)), "" + file
// + " after region merging 2");
// System.out.println(new EvalSegmentation().process(result, regions));
//
// result = (Image) new MergeUsingWatershed().process(result, source, 0.05);
//
// new Viewer2D().process(new DrawFrontiersOnImage().process(source,
// new FrontiersFromSegmentation().process(result)), "" + file
// + " after region merging 3");
// System.out.println(new EvalSegmentation().process(result, regions));
//
// result = (Image) new MergeUsingWatershed().process(result, source, 0.05);
//
// new Viewer2D().process(new DrawFrontiersOnImage().process(source,
// new FrontiersFromSegmentation().process(result)), "" + file
// + " after region merging 4");
// System.out.println(new EvalSegmentation().process(result, regions));
//
// } 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();
// }
// }
}