package fr.unistra.pelican.demos;
import fr.unistra.pelican.BooleanImage;
import fr.unistra.pelican.ByteImage;
import fr.unistra.pelican.Image;
import fr.unistra.pelican.IntegerImage;
import fr.unistra.pelican.algorithms.arithmetic.AdditionConstantChecked;
import fr.unistra.pelican.algorithms.arithmetic.EuclideanNorm;
import fr.unistra.pelican.algorithms.arithmetic.Inversion;
import fr.unistra.pelican.algorithms.arithmetic.Maximum;
import fr.unistra.pelican.algorithms.arithmetic.Minimum;
import fr.unistra.pelican.algorithms.conversion.BinaryArrayToLabels;
import fr.unistra.pelican.algorithms.conversion.BinaryMasksToLabels;
import fr.unistra.pelican.algorithms.histogram.ContrastStretch;
import fr.unistra.pelican.algorithms.io.ImageLoader;
import fr.unistra.pelican.algorithms.io.ImageSave;
import fr.unistra.pelican.algorithms.io.SamplesLoader;
import fr.unistra.pelican.algorithms.morphology.binary.BinaryDilation;
import fr.unistra.pelican.algorithms.morphology.gray.GrayGradient;
import fr.unistra.pelican.algorithms.segmentation.MarkerBasedMultiProbashed;
import fr.unistra.pelican.algorithms.segmentation.MarkerBasedWatershed;
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.labels.MergeLabelsFromClasses;
import fr.unistra.pelican.algorithms.segmentation.weka.WekaSoftClassification5NN;
import fr.unistra.pelican.algorithms.visualisation.Viewer2D;
import fr.unistra.pelican.util.morphology.FlatStructuringElement2D;
public class MBWDemo {
public static void main(String[] args) throws Exception {
String path = "./samples/";
String file = "bear1"; // oui
// String file = "autruche"; // oui
//String file = "horse2"; // oui
// String file = "zebre"; // oui
// String file = "monkey1"; // oui assez bon
// String file = "horse1"; // assez bon
// String file = "plane1"; // oui mais bon spatial pur
// String file = "tiger2"; // oui mais assez bon pour tout
// String file = "desert"; // oui mais bonne classif
// String file = "tiger1"; // mauvais
// String file = "pyramides"; // mauvais
// String file = "guepard"; // ok
// String file = "etoile"; // ok
// String file = "aigle2"; //ok
String ext = "png";
file = path + file;
if (args.length > 0)
file = args[0];
if (args.length > 1)
ext = args[1];
BooleanImage se1 = FlatStructuringElement2D
.createSquareFlatStructuringElement(5);
// Load the image and the samples
Image source = ImageLoader.exec(file + "." + ext);
BooleanImage samples = SamplesLoader.exec(file);
// source = GrayMedian.process(source, se1);
// Viewer2D.exec(source, "Source");
// Comparison with classical MBW
BooleanImage se2 = FlatStructuringElement2D
.createSquareFlatStructuringElement(3);
Image relief = GrayGradient.exec(source, se2);
// relief=AverageChannels.process(relief);
relief = EuclideanNorm.exec(relief);
relief = AdditionConstantChecked.exec(relief, 1.0/255);
Image marker=samples.getImage4D(0,Image.B);
for(int i=1;i<samples.getBDim();i++)
marker=Maximum.exec(marker,samples.getImage4D(i,Image.B));
marker = Inversion.exec(marker);
relief = Minimum.exec(relief, new ByteImage(marker));
Image mbww = MarkerBasedWatershed.exec(relief);
Viewer2D.exec(DrawFrontiersOnImage.exec(source, FrontiersFromSegmentation
.exec(mbww)), "MBW " + file);
// Apply Probashed
boolean frontiers = true;
int thickness = 3;
boolean single = false;
boolean compare = true;
boolean merge = true;
Image im;
if (!single) {
// Compare with classifier
Image proba = (Image) new WekaSoftClassification5NN().process(source,
samples);
proba = ContrastStretch.exec(proba);
Image classif = segmentFromProbabilities(proba);
Viewer2D.exec(classif, "Classification");
ImageSave.exec(classif, file + "-res-classif.png");
if (frontiers)
im = DrawFrontiersOnImage.exec(source, (BooleanImage) BinaryDilation
.exec(FrontiersFromSegmentation.exec(MarkerBasedMultiProbashed.exec(
source, samples, 0.25)), FlatStructuringElement2D
.createSquareFlatStructuringElement(thickness)));
else
im = LabelsToColorByMeanValue.exec(MarkerBasedMultiProbashed.exec(
source, samples, 0.25), source);
Viewer2D.exec(im, "marker-based probashed more spatial");
ImageSave.exec(im, file + "-res-more-spatial.png");
if (frontiers)
im = DrawFrontiersOnImage.exec(source, (BooleanImage) BinaryDilation
.exec(FrontiersFromSegmentation.exec(MarkerBasedMultiProbashed.exec(
source, samples, 0.5)), FlatStructuringElement2D
.createSquareFlatStructuringElement(thickness)));
else
im = LabelsToColorByMeanValue.exec(MarkerBasedMultiProbashed.exec(
source, samples, 0.5), source);
Viewer2D.exec(im, "marker-based probashed");
ImageSave.exec(im, file + "-res-mixed.png");
if (frontiers)
im = DrawFrontiersOnImage.exec(source, (BooleanImage) BinaryDilation
.exec(FrontiersFromSegmentation.exec(MarkerBasedMultiProbashed.exec(
source, samples, 0.75)), FlatStructuringElement2D
.createSquareFlatStructuringElement(thickness)));
else
im = LabelsToColorByMeanValue.exec(MarkerBasedMultiProbashed.exec(
source, samples, 0.75), source);
Viewer2D.exec(im, "marker-based probashed more spectral");
ImageSave.exec(im, file + "-res-more-spectral.png");
if (frontiers)
im = DrawFrontiersOnImage.exec(source, (BooleanImage) BinaryDilation
.exec(FrontiersFromSegmentation.exec(MarkerBasedMultiProbashed.exec(
source, samples, 1.0)), FlatStructuringElement2D
.createSquareFlatStructuringElement(thickness)));
else
im = LabelsToColorByMeanValue.exec(MarkerBasedMultiProbashed.exec(
source, samples, 1.0), source);
Viewer2D.exec(im, "spectral only");
ImageSave.exec(im, file + "-res-only-spectral.png");
}
if (compare) {
if (frontiers)
im = DrawFrontiersOnImage.exec(source, (BooleanImage) BinaryDilation
.exec(FrontiersFromSegmentation.exec(MarkerBasedMultiProbashed.exec(
source, samples, 0.0)), FlatStructuringElement2D
.createSquareFlatStructuringElement(thickness)));
else
im = LabelsToColorByMeanValue.exec(MarkerBasedMultiProbashed.exec(
source, samples, 0.0), source);
Viewer2D.exec(im, "spatial only");
ImageSave.exec(im,file + "-res-only-spatial.png");
}
long t1 = System.currentTimeMillis();
IntegerImage mbw = MarkerBasedMultiProbashed.exec(source, samples);
if (merge)
mbw = MergeLabelsFromClasses.exec(mbw, BinaryMasksToLabels.exec(samples));
if (frontiers)
im = DrawFrontiersOnImage.exec(source, (BooleanImage) BinaryDilation
.exec(FrontiersFromSegmentation.exec(mbw), FlatStructuringElement2D
.createSquareFlatStructuringElement(thickness)));
else
im = LabelsToColorByMeanValue.exec(mbw, source);
long t2 = System.currentTimeMillis();
System.out
.println("Supervised segmentation : " + (t2 - t1) / 1000.0 + " s");
Viewer2D.exec(im, "experimental multiplied");
ImageSave.exec(im,file + "-res-multiplied.png");
}
public static Image segmentFromProbabilities(Image i1) {
int bdim = i1.getBDim();
boolean color = false;
if (bdim < 3) {
bdim = 3;
color = true;
}
Image i2 = new ByteImage(i1.getXDim(), i1.getYDim(), i1.getZDim(), i1
.getTDim(), bdim);
i2.setColor(color);
boolean ok;
for (int x = 0; x < i1.getXDim(); x++)
for (int y = 0; y < i1.getYDim(); y++)
for (int z = 0; z < i1.getZDim(); z++)
for (int t = 0; t < i1.getTDim(); t++)
for (int b = 0; b < i1.getBDim(); b++) {
ok = true;
for (int b2 = 0; b2 < i1.getBDim(); b2++)
if (b2 != b
&& i1.getPixelDouble(x, y, z, t, b2) > i1.getPixelDouble(x,
y, z, t, b))
ok = false;
i2.setPixelBoolean(x, y, z, t, b, ok);
}
return i2;
}
}