package fr.unistra.pelican.algorithms.applied.remotesensing;
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.histogram.ContrastStretch;
import fr.unistra.pelican.algorithms.io.ImageLoader;
import fr.unistra.pelican.algorithms.io.SamplesLoader;
import fr.unistra.pelican.algorithms.morphology.gray.GrayMedian;
import fr.unistra.pelican.algorithms.segmentation.labels.DrawFrontiersOnImage;
import fr.unistra.pelican.algorithms.segmentation.labels.FrontiersFromSegmentation;
import fr.unistra.pelican.algorithms.segmentation.labels.LabelsToColorByMeanValue;
import fr.unistra.pelican.algorithms.segmentation.regionMerging.MergeUsingWatershed;
import fr.unistra.pelican.algorithms.segmentation.weka.WekaSoftClassification5NN;
import fr.unistra.pelican.algorithms.visualisation.Viewer2D;
import fr.unistra.pelican.util.morphology.FlatStructuringElement2D;
/**
* Create regions using a soft 5NN algorithm then watershed algorithm.
* Settings are :
* - samples : training set, boolean image, each band is for a class, white pixel are samples.
* - hmin : reduction value of the gradient image to limit oversegmentation
* - dynamics : reduction value of the gradient image to limit oversegmentation
* - merging : connected regions with a Euclidian difference in spectral values less than merging are merged
* @author Sebastien Derivaux
*/
public class RegionBuilderSoftClassificationWatershed extends Algorithm {
// Inputs parameters
public Image inputImage;
public Image samples;
public double hmin;
public double dynamics;
public double merging;
// Outputs parameters
public Image outputImage;
/**
* Constructor
*
*/
public RegionBuilderSoftClassificationWatershed() {
super();
super.inputs = "inputImage,samples,hmin,dynamics,merging";
super.outputs = "outputImage";
}
/* (non-Javadoc)
* @see fr.unistra.pelican.Algorithm#launch()
*/
public void launch() throws AlgorithmException {
Image work;
try {
Image proba = (Image) new WekaSoftClassification5NN().process(inputImage, samples);
proba = (Image) new ContrastStretch().process(proba);
BooleanImage se = FlatStructuringElement2D.createSquareFlatStructuringElement(5);
proba = (Image) new GrayMedian().process(proba, se);
//Viewer2D.exec(proba, "probas");
work = RegionBuilderWatershedClassical.exec(proba, hmin, dynamics);
// Another filtering step
work = MergeUsingWatershed.exec(work, proba, merging);
outputImage = work;
} 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();
}
}
/**
* Create regions using a soft 5NN algorithm then watershed algorithm.
* Settings are :
* @param samples : training set, boolean image, each band is for a class, white pixel are samples.
* @param hmin : reduction value of the gradient image to limit oversegmentation
* @param dynamics : reduction value of the gradient image to limit oversegmentation
* @param merging : connected regions with a Euclidian difference in spectral values less than merging are merged
*/
public static Image exec(Image image, Image samples, double hmin, double dynamics, double merging) throws InvalidTypeOfParameterException, AlgorithmException, InvalidNumberOfParametersException {
RegionBuilderSoftClassificationWatershed algo = new RegionBuilderSoftClassificationWatershed();
algo.inputImage = image;
algo.samples = samples;
algo.hmin = hmin;
algo.dynamics = dynamics;
algo.merging = dynamics;
algo.launch();
return algo.outputImage;
}
public static void main(String[] args) {
String file = "./samples/remotesensing1";
if(args.length > 0)
file = args[0];
BooleanImage se3 = FlatStructuringElement2D.createSquareFlatStructuringElement(3);
try {
// Load the image
Image source = (Image) new ImageLoader().process(file + ".png");
Image samples = (Image) new SamplesLoader().process(file);
source = (Image) new GrayMedian().process(source, se3);
// Create regions
Image result = (Image) new RegionBuilderSoftClassificationWatershed().process(source, samples, 0.2);
// View it
new Viewer2D().process(new DrawFrontiersOnImage().process(source, new FrontiersFromSegmentation().process(result)), "Segmentation of " + file);
new Viewer2D().process(new LabelsToColorByMeanValue().process(result, 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();
}
}
}