Advanced Trainable Weka Segmentation- Classification Differences

segmentation
imagej
Tags: #<Tag:0x00007fb883d75800> #<Tag:0x00007fb883d755d0>

#1

Hello Forum Members,

I have currently been experimenting with Advanced Trainable Weka Segmentation, its a great tool.

Although, I have ran into a bit of a problem. Indeed, I trained a model to detect certain pixels in an image. When applied to an unknown image it will work, although only sometimes. In addition, I noticed something very strange. I can classify an image with my (MODEL file) and it not have any traces of the positive class. Furthermore, I can train my positives/negatives and have it all in memory. Indeed, I can classify the same image with the classifier (Not using MODEL file) that just got trained and it will return the expected results. Unlike the model file. Yes, I could run the classifier in memory but in the big picture your looking at it holding 200gb of memory. Possibly there may be a way to clear the memory of the image data?

Example of model file and not with model file use the same image. Different results…

Update-
When I use the model file in the Advanced Weka Segmentation Plugin via Fiji on the same image it classifies correctly, but
still does not work correctly with my Java Code.

Open to all ideas.
Thanks,
Jake


#2

Hello @jakebremiller and welcome to the ImageJ forum!

That can be totally normal if the pixels in the “unknown” image are not similar to the pixels in the training image. In this case, your trained classifier will not know how to treat those pixels and probably fail.

That is expected. If you load an already trained classifier, you don’t need traces of both classes to apply it, only to re-train it.

Yes, have a look at this script that applies an already trained classifier to a whole folder of images.

Do you mean you obtained different results in the same image using the same model, once from the GUI and once from file? What was the order of events? If you trained your classifier using the GUI and obtained some results on one image, you should have exactly the same result in the same image if you just apply the trained model from file.

Can you post here your java code, please?


#3

Hello @iarganda,

Do you mean you obtained different results in the same image using the same model, once from the GUI and once from file? What was the order of events? If you trained your classifier using the GUI and obtained some results on one image, you should have exactly the same result in the same image if you just apply the trained model from file

Exactly, I am obtaining different results for the same image using the same model once from the GUI and once from the Java Code.

Order of events.
1.) Trained Model with Training Images and Predefined ROI’s

public void trainImage(String modelName) throws IOException{
    FastRandomForest randomForest = new FastRandomForest();
    randomForest.setNumThreads(0);
    randomForest.setNumFeatures(25);
    randomForest.setNumTrees(300);
    randomForest.setSeed(new java.util.Random().nextInt());
    randomForest.setBatchSize("100");
    randomForest.setNumDecimalPlaces(2);
    randomForest.setMaxDepth(0);
    
    trainer.setClassifier(randomForest);
    
    trainer.setClassLabel(0, "Negative");
    trainer.setClassLabel(1, "Positive");
    
    trainer.setMembranePatchSize(19);
    trainer.setMaximumSigma(16.0f);
    trainer.setMinimumSigma(1.0f);
    trainer.setMembraneThickness(1);
    
    boolean[] enableFeatures = new boolean[]{
        true,   /* Gaussian_blur */
        true,   /* Sobel_filter */
        true,   /* Hessian */
        true,   /* Difference_of_gaussians */
        true,   /* Membrane_projections */
        false,  /* Variance */
        false,  /* Mean */
        false,  /* Minimum */
        false,  /* Maximum */
        false,  /* Median */
        false,  /* Anisotropic_diffusion */
        true,  /* Bilateral */
        false,  /* Lipschitz */
        false,  /* Kuwahara */
        false,  /* Gabor */
        false,  /* Derivatives */
        false,  /* Laplacian */
        false,  /* Structure */
        false,  /* Entropy */
        true  /* Neighbors */
    };
    // Enable features
    trainer.setEnabledFeatures(enableFeatures);
  
    trainer.trainClassifier();
    
   //This is where I test the model before it gets saved to insure results are correct. Results are true when I use this method. When I use the model file they are different
    ImageIO.write(trainer.applyClassifier(new ImagePlus("test.jpg")).getBufferedImage(), "png", new File("prc.png"));
    trainer.saveClassifier(modelName + ".model");
   
}

2.) Saved Model

3.) Used Classifying Function
My mistake may be here in the classifyImage Function.
> public BufferedImage classifyImage(BufferedImage input_Image, String modelName){

    WekaSegmentation weka_Segmentation = new WekaSegmentation(new ImagePlus("",input_Image));
    weka_Segmentation.loadClassifier(modelName);
    weka_Segmentation.applyClassifier(false);
    ImagePlus classifiedImage =  weka_Segmentation.getClassifiedImage();
    
    return classifiedImage.getBufferedImage();
}

Thank you for the reply,
Jake


#4

Your code seems OK. I am just wondering if the getBufferedImage method makes some scaling in the image values. Can you post here the result image from the training and the result image from your classifyImage method?


#5

Using the model file with classifyImage method

Using the same “model file” except I apply the classifier directly from the trained instance - results

As well GUI Image, using the same model file that my classifyImage method uses

Thanks again,
Jake


#6

Very strange indeed. Would it be possible for you to send me the test.jpg image and the saved model file so I can reproduce this behavior on my machine?

Otherwise, can you try saving directly the images from their ImagePlus objects instead of using the BufferedImage method?


#7

Hello @iarganda,

I prepared everything and was just about to send you a message with some details. In addition, I wanted to test the classifying method with a PathOrUrl to the image instead of the BufferedImage; as you had stated above. Weirdly enough it worked. Below I have attached the revised code for anyone else having this issue. Finally, I would like to thank you @iarganda

ImagePlus unclassifiedImage = new ImagePlus(“C:/testImage.jpg”);
classifyImage(unclassfiedImage. “C:/modelName.model”);

public BufferedImage classifyImage(ImagePlus input_Image, String modelName){
WekaSegmentation weka_Segmentation = new WekaSegmentation(input_Image);
weka_Segmentation.loadClassifier(modelName);
weka_Segmentation.applyClassifier(false);
ImagePlus classifiedImage = weka_Segmentation.getClassifiedImage();
return classifiedImage.getBufferedImage();
}

Thanks,
Jake


#8

Thanks for letting us know @jakebremiller. It seems the BufferedImage object was doing something we did not expect.