Running 'Trainable Weka Segmentation' from Matlab (using ImageJ-MATLAB)

Note: find below an improved workflow (my answer to this post).

Liebes Tagebuch,

I’m trying to help a lab that uses a ton of Matlab scripts. Seeing the Trainable Weka Sementation they asked if the plugin can be called from within one of their Matlab routines.

I found a solution that works and I will share it below. Still, I have never used ImageJ-MATLAB or Miji before and my solution might be crap. If you see ways to improve what I did, please let me know, ok? Thanks a lot!

  • First I have followed the instructions here: https://imagej.net/MATLAB_Scripting

    • The most tedious step was to run Matlab with the same JVM as the one Fiji is using. Links to documents that describe how to do that can be found on the page I linked above.
  • The following lines then allowed me to launch fiji from within Matlab:

    addpath('e:/Fiji.app/scripts') % Point to your ImageJ installation
    ImageJ
    
    • In order to avoid that ImageJ is called multiple times (if people run the Matlab script multiple times), I did the following:
% Check if IJM is started already and start if it is not
try
      %this is just some function that can only be called if IJM is set up
      IJM.getIdentifier() 
catch
      addpath('e:/Fiji.app/scripts') % Update for your ImageJ installation
      ImageJ                         % Initialize IJM and MIJ
end
call('trainableSegmentation.Weka_Segmentation.loadClassifier','E:\\Tr2dProjectFolder\\Classifier\\Hernan_Simple_Substack_1-252-10.model');
call('trainableSegmentation.Weka_Segmentation.getProbability');
  • In order to make this Macro available I installed it from within Matlab using:
% Install Macro 'WekaThis.ijm'
MIJ.run('Install...', 'install=C:\\Users\\jug\\matlab\\WekaThis.ijm');
  • The next problem I encountered was that I needed to wait for the Macro to terminate before continuing to execute the Matlab script. I did not find a way to use e.g. the IJ1 macroRunning() method, so I helped myself with the following hack in Matlab:
numImages = length(MIJ.getListImages());
MIJ.run('WekaThis');
while (length(MIJ.getListImages()) == numImages)
end
  • And last but not least I could receive the results and close all open windows:
% Receive computed results
IJM.getDatasetAs('probmaps');
probmapObject = probmaps(:,:,1)';
imshow(probmapObject)

% close all image windows
MIJ.run('Close All');
%MIJ.exit(); % do this only if you do not want to use fiji any more

This is it! If you saw something that you know how to improve – please let me know!

Below I will post the entire Matlab script for giving you a better overview.


The IJ Macro I called WekaThis.ijm:

call('trainableSegmentation.Weka_Segmentation.loadClassifier', 'E:\\Tr2dProjectFolder\\Classifier\\Hernan_Simple_Substack_1-252-10.model');
call('trainableSegmentation.Weka_Segmentation.getProbability');

The entire Matlab script:

% Check if IJM is started already and start if it is not
try
    %this is just some function that can only be called if IJM is set up
    IJM.getIdentifier() 
catch
    addpath('e:/Fiji.app/scripts') % Update for your ImageJ installation
    ImageJ                         % Initialize IJM and MIJ
end

% Load an image and show it in IJ
load('single_frame.mat')
IJM.show('data')

% Install Macro 'WekaThis.ijm'
MIJ.run('Install...', 'install=C:\\Users\\jug\\matlab\\WekaThis.ijm');

% Start Weka, do the magic
MIJ.run('Trainable Weka Segmentation');
pause(1);
numImages = length(MIJ.getListImages());
MIJ.run('WekaThis');
while (length(MIJ.getListImages()) == numImages)
end

% Receive computed results
IJM.getDatasetAs('probmaps');
probmapObject = probmaps(:,:,1)';
imshow(probmapObject)

% close all image windows
MIJ.run('Close All');
%MIJ.exit(); % do this only if you do not want to use fiji any more
4 Likes

Note: I received help by @ctrueden and incorporated it below. I call functions of Trainable Weka Segmentation directly from Matlab now. This avoids the need for the macro and its installation. Additionally it also avoids this hacky trick to wait for Macro termination. In total it simplified the whole pipeline quite a bit - thank you Curtis!

As said above, the WekaThis.ijm macro is obsolete now.

The entire (updated) Matlab script is now:

% Check if IJM is started already and start if it is not
try
    %this is just some function that can only be called if IJM is set up
    IJM.getIdentifier() 
catch
    addpath('e:/Fiji.app/scripts') % Update for your ImageJ installation
    ImageJ                         % Initialize IJM and MIJ
end

% Load an image and show it in IJ
load('single_frame.mat')
IJM.show('data')

% Start Weka, do the magic
MIJ.run('Trainable Weka Segmentation');
pause(1);
trainableSegmentation.Weka_Segmentation.loadClassifier('E:\\Tr2dProjectFolder\\Classifier\\Hernan_Simple_Substack_1-252-10.model');
trainableSegmentation.Weka_Segmentation.getProbability();

% Receive computed results
IJM.getDatasetAs('probmaps');
probmapObject = probmaps(:,:,1)';
imshow(probmapObject)

% close all image windows
MIJ.run('Close All');
%MIJ.exit(); % do this only if you do not want to use fiji any more
5 Likes

Hi @fjug,

I’ve used what you wrote down here to run the Trainable Weka Segmentation script within Matlab but I’m obtaining the error below. I can open the Weka GUI, but cannot load data and train it. Do you have any idea on what could happen? I copy my Matlab code.

Best regards,

Tomas.

Code:

javaaddpath('C:\Program Files\MATLAB\R2017b\java\ij-1.52a.jar');
javaaddpath('C:\Program Files\MATLAB\R2017b\java\mij.jar');
addpath('C:\Users\tmost\Documents\Instaladores de programas\Fiji.app\scripts');
Miji(false);

%Open an image in Fiji within Matlab
[testfile, testpath]=uigetfile({'*.*','All Files'},'Choose image','C:\Users\tmost\Documents\Universidad\Final Project\Microscopies\Jessica\*.jpg');
MIJ.run('Open...', ['path=[' testpath testfile ']']);
MIJ.run('8-bit');
MIJ.run('Enhance Contrast...', 'saturated=0.2 normalize');

% Start Weka
MIJ.run('Trainable Weka Segmentation');
trainableSegmentation.Weka_Segmentation.loadData('C:\Users\tmost\Desktop\TWS\TWS240786.arff');
trainableSegmentation.Weka_Segmentation.trainClassifier;
trainableSegmentation.Weka_Segmentation.getResult;
MIJ.run('8-bit');
MIJ.run('Make Binary')

Segmented_micro=MIJ.getCurrentImage;
Segmented_micro=uint8(Segmented_micro);

[file, path] = uiputfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';'*.*','All Files' },'Save Image', testfile);
imwrite(Segmented_micro, strcat(path, file));

Error:

Error using TWS_MATLAB (line 15)
Java exception occurred:
java.lang.NullPointerException

	at trainableSegmentation.Weka_Segmentation$CustomWindow.setButtonsEnabled(Weka_Segmentation.java:1118)

	at trainableSegmentation.Weka_Segmentation.trainClassifier(Weka_Segmentation.java:2552)

In order to get you help quickly:

  • What are your reasons for deviating from the script posted by @fjug? I see almost no correspondence between the working script posted above and your code…
  • Did you test if that sequence works when run from a script inside ImageJ? I’d expect that you also have to load (or define) a classifier, otherwise Weka_Segmentation has little chance to know how many classes and what features it should train. Testing this within ImageJ would leave one factor (Matlab) out of the game and help finding the actual issue of your script.
1 Like

Hi @imagejan, sorry for my lack of clarity and experience at the moment to write that question. After reading a bit more deeper and getting in contact with the plugin (also thanks to @iarganda) I could make it work, so the scrip posted by @fjug is totally correct.

At the moment I’m having a problem with the java heap space, it runs out of memory when I want to load the classifier (is a classifier made with a stack of 10 images and several traces each image, for a smaller one I can make it work without problem). I changed the space used by Matlab to the top but is still failing. Is there a way to avoid it, uploading the classifier by parts or something else?

Thank you,

Tomás.

1 Like

Thanks to @iarganda I solved the problem of the memory for my purpose. The images must be loaded in stacks of 5, and after drawing all the traces, save the data with “Save data”. Then, a new stack of 5 images must be loaded, and after drawing the new traces, load the data that was saved before with “Load data”. Once the new data of traces was drawn and the old data was loaded, all this data must be saved. Now the data file contains information from the 10 images and this process can be reproduce as many times as desired and when the data saved is enough, it must be loaded and trained with “Train classifier”. After all, you will have a classifier model with the data of all the images.

Hope I was clear and it can be useful,

Tomás.

1 Like

Hello @fjug!

Thank you for this very helpful script. I was so pleased to find it available on the internet.
I have encountered an error that I am unsure how to resolve.
The error is: Undefined variable “MIJ” or class “mij.run”.
Are there any other steps that must be taken before using the updated Matlab script as is?

Thank you kindly,
Sara

2 Likes

@skmusc_histo I am also facing the same issue. Have you managed to get it resolved? Please do let me know.