Java script and Trainable Weka Segmentation

I have a very big stack from which I have trained a classifier. When I tried to load the full stack with Weka trainable segmentation it runs out of memory! To fix this I have an image macro to open the stack one slice at a time, apply the classifier then save the mask. However this is very slow and I’ve noticed it used very little of the CPU ~9% of 12 cores. So to speed it up I thought about running 12 slices on 12 cores then repeat. This requires using Java-scripting. I have found code online that I can adapt for my purpose, it can be found here

http://fiji.sc/Multithreaded_Image_Processing_in_JavaScript.

How to use Wekasegmentation class in JavaScript is hard to find online, and I know little about Java.

I need to know how to load a classifier and apply it to a stack. Can anyone point me in the right direction?

Thanks in advance,

Dan

1 Like

The Trainable Segmentation Scripting page has extensive documentation about how to use the plugin via scripting. The examples are in Beanshell, but it’s sufficiently similar to Javascript to learn from them.

Something along these lines should get you started:

// @ImagePlus imp

importClass(Packages.trainableSegmentation.WekaSegmentation);

var weka = WekaSegmentation( imp );

var classifierFile = "/path/to/your/classifier-file";
weka.loadClassifier(classifierFile);

weka.applyClassifier(True);
var result = weka.getClassifiedImage();
result.show();

Also have a look at the WekaSegmentation javadoc.


If you have a functional macro already to apply the classifier, you can also modify it to load “chunk” stacks containing 12 slices each, and run your segmentation on those stack instead of the single slices.

3 Likes

Thanks very much, I tried opening 12 slices at a time as a single tiff then classifying that but it automatically processes this slice by slice. I will have a go with with the pointers you gave me.

All the best, Dan.

Hello @danmckay91

Let me try to bring some light into the subject.

If you run @imagejan 's script (with some small modifications I made so it runs in the Script Editor):

// @ImagePlus imp

importClass(Packages.trainableSegmentation.WekaSegmentation);

var weka = new WekaSegmentation( imp );

var classifierFile = "/path/to/your/classifier-file.model";
weka.loadClassifier( classifierFile );

weka.applyClassifier( false ); // set to true to get probabilities
var result = weka.getClassifiedImage();

result.show();

Fiji will use all available processors to first calculate all the features of your input slices and then classify them. You can use this approach if you divide your data into chunks of slices whose features fit into your RAM. In this case you will have to make a loop over all the chunks or call the script as many times.

Another option is to use this almost equivalent script:

// @ImagePlus imp

importClass(Packages.trainableSegmentation.WekaSegmentation);

var weka = new WekaSegmentation( imp );

var classifierFile = "/path/to/your/classifier-file.model";
weka.loadClassifier( classifierFile );

// apply classifier to input image
var result = weka.applyClassifier( imp ); // <- this is the difference

result.show();

The advantage of this script is that the method used to apply the classifier divides the classification of the slices between the number of available processors, i.e., each thread calculates the features of one and only one slice at the time and then classifies it (so it’s supposed to save memory). I think that’s exactly what you wanted.

I admit this should be more clear on the API, so I will work on it as soon as possible.

Please, let me know if you have more problems or questions!

2 Likes