Weka Segmentation 3D - Beanshell scripting issue

Hi,

I am currently trying to apply a classifier which I trained using the
"Trainable Weka Segmentation 3D" plugin on the GUI of Fiji.

If I apply the classifier (“3D classifier”) on any kind of image stack by
using the GUI, it works nicely. However, if I use a Beanshell script to do
the same task, it shows me some errors:

Could not apply classifier!
Java.lang.ArrayIndexOutOfBoundsException: 18
...

In contrast, if I train a classifier (“2D classifier”) using the 2D version
of the Trainable Weka Segmentation, it works on exactly the same stack in
both, using the GUI as well as using exactly the same Beanshell script.

The script I am using is the following:

import trainableSegmentation.*;
import ij.io.FileSaver;
import ij.IJ;
import ij.ImagePlus;

testImage = IJ.openImage( "try.tif" ); 
segmentator = new WekaSegmentation( ); 
segmentator.loadClassifier( "classifier.model" ); 
result = segmentator.applyClassifier( testImage, 0, false );
new FileSaver( result ).saveAsTiff( "try_classified.tif" );

In summary, I can apply a 2D classifier on an image stack using the GUI as
well as the above Beanshell script, whereas for the 3D classifier it works
only using the GUI and not for the script.

Does any of you know about this problem?

Thank you and kind regards,

Michael

1 Like

Hello @Michael1987 and welcome to the ImageJ forum!

Here is the problem:

To use the WekaSegmentation in 3D, I created a new constructor with a boolean parameter that specifies exactly that.

So you only need to change that line to

segmentator = new WekaSegmentation( true );

I realized this is not explained anywhere right now, so I apologize about that and I will try to update the scripting wiki page as soon as possible with that information.

2 Likes

Thank you @iarganda for your fast and helpful answer!

I made the suggested small change in my script, but unfortunately it still doesn’t work. There seems to be a problem when I load the 3D classifier via the script as I get the following error message:

Field of view: max sigma = 4.0, min sigma = 1.0
Error while adjusting data!
java.lang.NullPointerException
	trainableSegmentation.WekaSegmentation.adjustSegmentationStateToData(WekaSegmentation.java:4122)
	trainableSegmentation.WekaSegmentation.loadClassifier(WekaSegmentation.java:717)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.lang.reflect.Method.invoke(Method.java:498)
	bsh.Reflect.invokeMethod(Unknown Source)
	bsh.Reflect.invokeObjectMethod(Unknown Source)
	bsh.Name.invokeMethod(Unknown Source)
	bsh.BSHMethodInvocation.eval(Unknown Source)
	bsh.BSHPrimaryExpression.eval(Unknown Source)
	bsh.BSHPrimaryExpression.eval(Unknown Source)
	bsh.Interpreter.eval(Unknown Source)
	bsh.Interpreter.source(Unknown Source)
	bsh.Interpreter.main(Unknown Source)

	at trainableSegmentation.WekaSegmentation.adjustSegmentationStateToData(WekaSegmentation.java:4122)
	at trainableSegmentation.WekaSegmentation.loadClassifier(WekaSegmentation.java:717)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at bsh.Reflect.invokeMethod(Unknown Source)
	at bsh.Reflect.invokeObjectMethod(Unknown Source)
	at bsh.Name.invokeMethod(Unknown Source)
	at bsh.BSHMethodInvocation.eval(Unknown Source)
	at bsh.BSHPrimaryExpression.eval(Unknown Source)
	at bsh.BSHPrimaryExpression.eval(Unknown Source)
	at bsh.Interpreter.eval(Unknown Source)
	at bsh.Interpreter.source(Unknown Source)
	at bsh.Interpreter.main(Unknown Source)

I am wondering what causes the problem, as loading the classifier via the Fiji GUI work as well as the subsequent application on image stacks.

I used the following script (exactly the same as above, but with your suggested change as well as excluding some lines in order to find the source of the error).

import trainableSegmentation.*;
import ij.io.FileSaver;
import ij.IJ;
import ij.ImagePlus;

//testImage = IJ.openImage( "try.tif" ); 
segmentator = new WekaSegmentation( true ); 
segmentator.loadClassifier( "classifier.model" ); 
//result = segmentator.applyClassifier( testImage, 0, false );
//new FileSaver( result ).saveAsTiff( "try_classified.tif" );
1 Like

What I forgot to mention: The classifier I want to load via the script was trained using a Windows machine whereas the script is supposed to run on a linux cluster. Does this may cause the problem?

However, loading and applying the classifier on the GUI using the Linux cluster works as well as it does on the Windows machine.

Hello again, @Michael1987,

Your script works for me using the latest release (Trainable Weka Segmentation v3.2.16). Which version are you using?

Thank you again @iarganda. I am using version v.3.2.13. which is the newest version I get via the updater on the linux machine.

I also just created a new testing 3D classifier using the GUI of the same version and then directly tried it again with the above script and get the same error message.

That’s strange, the updater should get the latest version independent of the platform. Can you make sure that you:

  • are running ImageJ on Java 8
  • have the Java-8 update site enabled
  • if both of the above is true, check the version of Trainable_Segmentation.jar that your updater reports using the Advanced mode in the updater?

2 Likes

As @imagejan suggested, please make sure you get the latest release so your plugin can work.

I checked it via the advanced mode in the updater and I found two versions of the trainable segmentation, one without anything written in the “Update Site” tab (v.3.2.13) and the new one (v.3.1.16) with “Java 8” in the tab. I uninstalled the old one, restarted ImageJ and now the advanced mode only shows me the new version, which I verified by opening the plugin using the GUI.

However, when I try running the script, I get the following error message:


Evaluation Error: Sourced file: WekaSegmentation.bsh : Unknown class: WekaSegmentation : at Line: 7 : in file: WekaSegmentation.bsh : new WekaSegmentation ( true )


I contacted the administrator of the cluster and asked him to completely make a new setup of ImageJ, maybe this might help?

It seems now you lost both versions of the plugin? Can you find the plugin in the GUI menu?

That’s an option, of course.

The administrator of the cluster fixed the issue by adjusting the CLASSPATH so that it uses version v.3.2.16 now and the older version is deinstalled. I can find as well as open the plugin in the GUI and it shows me v.3.2.16.

However, if I try to run the script now, it again shows the error messege of the beginning of my post: “Error while adjusting data!”.

I realized that I was missing the first line of the error when I posted it above:


WARNING: core mtj jar files are not available as resources to this classloader (sun.misc.Launcher$AppClassLoader@5c647e05)
Field of view: max sigma = 4.0, min sigma = 1.0
Error while adjusting data!


That’s very strange, you shouldn’t need to adjust any CLASSPATH. Why don’t you try to install a fresh version of Fiji locally and check if it works?

Yes, that’s a good idea. I installed a fresh version on the local Windows machine and tried to run the script.

The error message I got now is the following:


Evaluation Error: Sourced file: WekaSegmentation.bsh : Unknown class: WekaSegmentation : at Line: 7 : in file: WekaSegmentation.bsh : new WekaSegmentation ( true )


Again, using the GUI of Fiji, everything works nicely.

But this is not an issue of the Weka Segmenation itself, since I get a similar type of error if I just want to open the file:


Attempt to resolve method: openImage() on undefined variable or class name: IJ


With respect to the classpath, I meant that ij.*jar etc. had to be added to the java classpath, right?

Sorry if my questions are really basic. So far I just used Fiji by simply using the GUI and never did anything with Fiji from the command line.

These two error messages are very different from what you initially reported, and they suggest that either:

  • the required classes are not found on the classpath (as @iarganda suggested), or
  • the required classes were not imported in the current script instance.

Are you sure you’re running the required imports at the start of your script, and not, by any chance, executed only part of the code?

import trainableSegmentation.WekaSegmentation;
import ij.IJ;

Also, I noticed that in Beanshell, wrong import statements do not seem to throw an error message: you can write import foo.Crap; and it will not complain, only when you try to instantiate the (non-existing) class with new Crap(); it will throw an exception…

Yes, the first lines of my script have been:


import trainableSegmentation.*;
import ij.io.FileSaver;
import ij.IJ;
import ij.ImagePlus;

testImage = IJ.openImage( “try.tif” );


@Michael1987 just to rule out that it’s an issue specific to Beanshell: can you try if the same small script runs fine if you switch the script language to Groovy? And if not, are the error message any different? This might help finding out if it really is a classpath issue…

Right now I don’t have the rights (not Administrator) to install groovy. But I will check everything which has been suggested so far later on my private Computer at home.

With respect to the error messages, I can run the following part of the script on the cluster without any problems:

import trainableSegmentation.*;
import ij.io.FileSaver;
import ij.IJ;
import ij.ImagePlus;

testImage = IJ.openImage( "try.tif" ); 
segmentator = new WekaSegmentation( true );

This is because there it was set up for me that everything which is imported above is added to the java classpath. However, when I add the following line at the bottom…

segmentator.loadClassifier( "classifier.model" );

… I get the follwing error message:

WARNING: core mtj jar files are not available as resources to this classloader (sun.misc.Launcher$AppClassLoader@5c647e05)
Field of view: max sigma = 4.0, min sigma = 1.0
Error while adjusting data!
java.lang.NullPointerException
    trainableSegmentation.WekaSegmentation.adjustSegmentationStateToData(WekaSegmentation.java:4254)
    trainableSegmentation.WekaSegmentation.loadClassifier(WekaSegmentation.java:772)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:498)
    bsh.Reflect.invokeMethod(Unknown Source)
    bsh.Reflect.invokeObjectMethod(Unknown Source)
    bsh.Name.invokeMethod(Unknown Source)
    bsh.BSHMethodInvocation.eval(Unknown Source)
    bsh.BSHPrimaryExpression.eval(Unknown Source)
    bsh.BSHPrimaryExpression.eval(Unknown Source)
    bsh.Interpreter.eval(Unknown Source)
    bsh.Interpreter.source(Unknown Source)
    bsh.Interpreter.main(Unknown Source)

    at trainableSegmentation.WekaSegmentation.adjustSegmentationStateToData(WekaSegmentation.java:4254)
    at trainableSegmentation.WekaSegmentation.loadClassifier(WekaSegmentation.java:772)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at bsh.Reflect.invokeMethod(Unknown Source)
    at bsh.Reflect.invokeObjectMethod(Unknown Source)
    at bsh.Name.invokeMethod(Unknown Source)
    at bsh.BSHMethodInvocation.eval(Unknown Source)
    at bsh.BSHPrimaryExpression.eval(Unknown Source)
    at bsh.BSHPrimaryExpression.eval(Unknown Source)
    at bsh.Interpreter.eval(Unknown Source)
    at bsh.Interpreter.source(Unknown Source)
    at bsh.Interpreter.main(Unknown Source)

If I switch the classifier to a 2D one and use:

segmentator = new WekaSegmentation( false );
segmentator.loadClassifier( “classifier2D.model” );

…it works and gives me the following message:

WARNING: core mtj jar files are not available as resources to this classloader (sun.misc.Launcher$AppClassLoader@5c647e05)
Field of view: max sigma = 1.0, min sigma = 1.0
Membrane thickness: 1, patch size: 19
Read class name: class 1
Read class name: class

Also the application of the 2D classifier and subsequent saving by:

result = segmentator.applyClassifier( testImage, 0, false ); 
new FileSaver( result ).saveAsTiff( "try_classified.tif" );

works. Just for the 3D classifier it gives me the mentioned problems.