package fr.unistra.pelican.demos;
import java.util.ArrayList;
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.AdditionChecked;
import fr.unistra.pelican.algorithms.conversion.ColorImageFromMultiBandImage;
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.logical.OR;
import fr.unistra.pelican.algorithms.morphology.binary.BinaryDilation;
import fr.unistra.pelican.algorithms.segmentation.IncompleteMarkerBasedMultiProbashed;
import fr.unistra.pelican.algorithms.segmentation.MarkerBasedMultiProbashed;
import fr.unistra.pelican.algorithms.segmentation.labels.DrawFrontiersOnImage;
import fr.unistra.pelican.algorithms.segmentation.labels.FrontiersFromSegmentation;
import fr.unistra.pelican.algorithms.segmentation.labels.LabelsToBinaryMasks;
import fr.unistra.pelican.algorithms.segmentation.labels.LabelsToColorByMeanValue;
import fr.unistra.pelican.algorithms.segmentation.labels.LabelsToRandomColors;
import fr.unistra.pelican.algorithms.segmentation.labels.MergeLabelsFromClasses;
import fr.unistra.pelican.algorithms.segmentation.weka.WekaClassificationKNN;
import fr.unistra.pelican.algorithms.visualisation.Viewer2D;
import fr.unistra.pelican.gui.OldDraw2DThread;
import fr.unistra.pelican.util.morphology.FlatStructuringElement2D;
public class SupervisedWatershedDemo {
public static void main(String[] args) {
if (args.length == 0) {
System.out
.println("Usage: MarkerBasedMultiProbashedDemo file [output][-stretch][-compare][-colorview]\n"
+ "- file is the image to be segmented\n"
+ "- output is the resulting image\n"
+ "- -stretch to perform a contrast stretch step\n"
+ "- -thick to display thick region edges\n"
+ "- -merge to merge connected regions belong to the same class\n"
+ "- -semi to apply a semi-supervised strategy\n"
+ "- -compare to compare with classical watershed and supervised classification\n"
+ "- -colorview to have a color display of the image to be segmented");
return;
}
new SupervisedWatershedDemo(args);
}
public SupervisedWatershedDemo(String[] args) {
boolean compare = false;
boolean color = false;
boolean merge = false;
boolean semi = false;
boolean thick = false;
boolean subsampling=false;
String path = args[0];
Image input = ImageLoader.exec(path);
String outfile = null;
for (int i = 1; i < args.length; i++) {
if (args[i].equalsIgnoreCase("-stretch"))
input = ContrastStretch.exec(input);
else if (args[i].equalsIgnoreCase("-subsampling"))
subsampling = true;
else if (args[i].equalsIgnoreCase("-semi"))
semi = true;
else if (args[i].equalsIgnoreCase("-merge"))
merge = true;
else if (args[i].equalsIgnoreCase("-thick"))
thick = true;
else if (args[i].equalsIgnoreCase("-compare"))
compare = true;
else if (args[i].equalsIgnoreCase("-colorview"))
color = true;
else
outfile = args[i];
}
Image disp = input;
if (input.getBDim() > 3 && color)
disp = ColorImageFromMultiBandImage.exec(input, 2, 1, 0);
if (input.getBDim() == 3)
input.setColor(true);
if (disp.getBDim() == 3)
disp.setColor(true);
OldDraw2DThread d2d;
d2d = new OldDraw2DThread(disp, "SupervisedWatersedDemo: " + args[0], this);
new Thread(d2d).start();
while (d2d.isActive) {
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
}
}
if (!d2d.isActive) {
// TODO: do a cleaner exit
System.exit(0);
} else {
BooleanImage se = FlatStructuringElement2D
.createSquareFlatStructuringElement(thick ? 3 : 1);
Image markers = (Image) d2d.output;
Image samples = LabelsToBinaryMasks.exec(markers);
long t1 = System.currentTimeMillis();
Image result = null;
Image newMarkers = null;
boolean isColor = (input.getBDim() == 3);
//isColor=false;
if (semi) {
ArrayList results = new IncompleteMarkerBasedMultiProbashed()
.processAll(input, samples, null, isColor, subsampling);
result = (Image) results.get(0);
newMarkers = (Image) results.get(1);
// Viewer2D.exec(LabelsToRandomColors.exec(newMarkers,true));
// Viewer2D.exec(LabelsToRandomColors.exec(((ByteImage)markers).copyToIntegerImage(),true));
} else {
result = MarkerBasedMultiProbashed.exec(input,
samples, isColor, subsampling);
newMarkers = ((ByteImage) markers).copyToIntegerImage();
}
if (merge)
result = MergeLabelsFromClasses.exec(result, newMarkers);
long t2 = System.currentTimeMillis();
System.out.println("Supervised segmentation : " + (t2 - t1) / 1000.0
+ " s");
Image view1 = LabelsToColorByMeanValue.exec((IntegerImage)result, input);
Viewer2D.exec(view1, "SupervisedWatersedDemo: regions of " + args[0]);
BooleanImage frontiers = (BooleanImage) BinaryDilation.exec(
FrontiersFromSegmentation.exec(result), se);
BooleanImage frontiers2 = (BooleanImage) FrontiersFromSegmentation
.exec(convertToIntegerImage(markers));
frontiers2 = (BooleanImage) OR.exec(frontiers, frontiers2);
Image view3 = DrawFrontiersOnImage.exec(input, frontiers2);
Viewer2D.exec(view3,
"SupervisedWatersedDemo: frontiers with markers of " + args[0]);
if (outfile != null) {
result = convertToByteImage(result);
ImageSave.exec(result, outfile);
}
if (compare) {
result = MarkerBasedMultiProbashed.exec(input,
samples, 0);
if (!semi)
if (merge)
result = MergeLabelsFromClasses.exec(result, newMarkers);
view1 = LabelsToColorByMeanValue.exec((IntegerImage)result, input);
Viewer2D.exec(view1, "SupervisedWatersedDemo (standard): regions of " + args[0]);
frontiers = (BooleanImage) BinaryDilation.exec(
FrontiersFromSegmentation.exec(result), se);
frontiers2 = (BooleanImage) FrontiersFromSegmentation
.exec(convertToIntegerImage(markers));
frontiers2 = (BooleanImage) OR.exec(frontiers, frontiers2);
view3 = DrawFrontiersOnImage.exec(input, frontiers2);
Viewer2D.exec(view3,
"SupervisedWatersedDemo (standard): frontiers with markers of " + args[0]);
result = WekaClassificationKNN.exec(input, samples,
5);
view1 = LabelsToColorByMeanValue.exec((IntegerImage)result, input);
Viewer2D.exec(view1, "SupervisedWatersedDemo (classification): regions of " + args[0]);
frontiers = (BooleanImage) BinaryDilation.exec(
FrontiersFromSegmentation.exec(result), se);
frontiers2 = (BooleanImage) FrontiersFromSegmentation
.exec(convertToIntegerImage(markers));
frontiers2 = (BooleanImage) OR.exec(frontiers, frontiers2);
view3 = DrawFrontiersOnImage.exec(input, frontiers2);
Viewer2D.exec(view3,
"SupervisedWatersedDemo (classification): frontiers with markers of " + args[0]);
Viewer2D.exec(LabelsToRandomColors.exec(result));
}
}
}
}
private static IntegerImage convertToIntegerImage(Image img) {
IntegerImage res = new IntegerImage(img.getXDim(), img.getYDim(), img
.getZDim(), img.getTDim(), img.getBDim());
for (int p = 0; p < img.size(); p++)
res.setPixelInt(p, img.getPixelByte(p));
return res;
}
private static ByteImage convertToByteImage(Image img) {
ByteImage res = new ByteImage(img.getXDim(), img.getYDim(), img.getZDim(),
img.getTDim(), img.getBDim());
for (int p = 0; p < img.size(); p++)
res.setPixelByte(p, img.getPixelInt(p));
return res;
}
}