MorphoLibJ
MorphoLibJ copied to clipboard
Using Distance Transform Watershed without a GUI / UI
Hello David,
I would like to use MorphoLibJ without any UI. For the moment I am focused on DistanceTransformWatershed().
Currently it seems to me the code assumes a UI is present.
Could you add a constructor to DistanceTransformWatershed() so I can pass all mandatory arguments? Or using some sort of builder pattern for DistanceTransformWatershed() would also be nice.
What I tried, but it did not work because of java.awt.HeadlessException: null:
webcam.addValueChangeListener(e -> {
value = e.getValue();
String[] split = value.split(",");
data = Base64.getDecoder().decode(split[1]);
BufferedImage img = null;
try {
img = ImageIO.read(new ByteArrayInputStream(data));
} catch (IOException ex) {
}
ImagePlus imp = new ImagePlus("test", img);
var watershed = new DistanceTransformWatershed();
watershed.setup("", imp);
ImageProcessor processor = imp.getProcessor();
processor.autoThreshold();
//this is false
BinaryImages.isBinaryImage(imp);
GenericDialog gd = new GenericDialog("Distance Transform Watershed");
gd.setInsets(0, 0, 0);
gd.addMessage("Distance map options:", new Font("SansSerif", 1, 12));
gd.addChoice("Distances", ChamferWeights.getAllLabels(), "Chessboard (1,1)");
String[] outputTypes = new String[]{"32 bits", "16 bits"};
boolean floatProcessing = true;
gd.addChoice("Output Type", outputTypes, outputTypes[floatProcessing ? 0 : 1]);
gd.setInsets(0, 0, 0);
gd.addCheckbox("Normalize weights", false);
gd.setInsets(20, 0, 0);
gd.addMessage("Watershed options:", new Font("SansSerif", 1, 12));
gd.addNumericField("Dynamic", (double)2, 2);
String[] connectivity = {"4", "8"};
gd.addChoice("Connectivity", connectivity, "4");
gd.setInsets(20, 0, 0);
watershed.dialogItemChanged(gd, null);
watershed.run(processor);
FileSaver fileSaver = new FileSaver(imp);
fileSaver.saveAsBmp("...");
});
Thanks, @satorstefan for bringing this to our attention! While we create a public method for that and publish a new release, you may want to write in your code the few lines equivalent to the process in that plugin:
https://github.com/ijpb/MorphoLibJ/blob/master/src/main/java/inra/ijpb/plugins/DistanceTransformWatershed.java#L263-L268
Hello Ignarcio,
For now it seems it also works to set: System.setProperty("java.awt.headless", "false");
But I struggle to get a binary image out of my greyscale image.
So far I tried:
ImagePlus imp = new ImagePlus("test", img);
ImageProcessor processor = imp.getProcessor();
processor.autoThreshold();
ImagePlus binaryPlus = new ImagePlus("binary", processor);
if(!BinaryImages.isBinaryImage(binaryPlus)){
System.out.println("Huston we got a problem!");
}
and I also see that
ByteProcessor.threshold(int level1, int level2)
gets called.
To binarize an image, you can use our own method from the Threshold class:
https://github.com/ijpb/MorphoLibJ/blob/master/src/main/java/inra/ijpb/segment/Threshold.java#L57
Hello Ignarcio,
I will try your approach.
What I did try so for seems to "work", but the image result.png is just the unchanged binary that I put in.
watershed.dialogItemChanged(gd, null);
watershed.run(processor);
BufferedImage bufferedImage = processor.getBufferedImage();
print("result.png", bufferedImage)
```;
@iarganda Hello Ignarcio,
with your hint I could implement the algorithm.
I have one last question. Is there a easy way to give each object its own color like shown in the picture on the right here: https://imagej.net/plugins/distance-transform-watershed?
Best regards Stefan
Hi Stefan, maybe late for reply, but you can assign colors to regions in a label map when performing the connected component analysis. Either via the plugin, or by using the computation classes.
best, David