Login  Register

classifying multi-spectral images using Advanced Weka Segmaentation

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options Options
Embed post
Permalink
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

classifying multi-spectral images using Advanced Weka Segmaentation

Dionysios Lefkaditis
8 posts
Hello everyone,

I am trying to classify/segment multi-spectral images. The original images are in multi-layer tiff format. I am computing a set of features for every slice/band and then adding it to a custom featureStack, so that the final feature vector is a collection of varying features coming from each of the spectral bands. I can successfully build the featurestack and train the classifier. However, when the classifier is applied to a test image, it seems that it classifies each band/slice separately. It is intended to treat each multi-sepctral image as one entity and thus produce a single slice classified image. As I am a newbe on Fiji's API and the javadoc site is currently down, I would greatly appreciate your input on this. I am also wandering how it would be possible to just apply such a classifier to other unseen images. How do I recompute the feature vector and feed it straight to the classifier?

thanks a bunch,
Dionysios

I am sorry to clutter my post with a long script:

import ij.*;
import ij.process.*;
import trainableSegmentation.*;
import hr.irb.fastRandomForest.*;
 
// training input image (it could be a stack or a single 2D image)
opener = new Opener();
image = opener.openImage("/home/dionysis/fermi/media/data/CNH/cnh_multispectral/Denmark_field_1/original images/15/multi-spectral.tif");
//IJ.run(image, "8-bit", "");
IJ.run(image, "32-bit", "");



//*** Custom features***

-----------------------------------



// the FeatureStackArray contains a FeatureStack for every slice in our original image
featuresArray = new FeatureStackArray(1, 1, 16, false, 1, 19, null);

customstack = new ImageStack(image.getWidth(), image.getHeight());
for (slice = 1; slice <= image.getStackSize(); slice++) {
        image.setSlice(slice);
       
        features = new FeatureStack(image.getProcessor().duplicate());
        features.addGaussianBlur(20);
        features.addLaplacian(5);
        features.addHessian(2);
        //features.show();

       
        customstack.addSlice("original "+slice, features.getProcessor(1));
        customstack.addSlice("gaussianstd "+slice, features.getProcessor(2));
        customstack.addSlice("Laplacianstd "+slice, features.getProcessor(3));
       
}

//customFeaturesImage = new ImagePlus("features_std&cust", customstack);
//customFeaturesImage.show();



// create new feature stack with the custom features
stack2featstack = new FeatureStack( image );
stack2featstack.setStack( customstack );
stack2featstack.show();
//print(stack2featstack.getSize());



// create Weka segmentator
seg = new WekaSegmentation(image);
 
// number of samples to use per slice
nSamplesToUse = 1000;
 
 
// Classifier
// In this case we use a Fast Random Forest
rf = new FastRandomForest();
// Number of trees in the forest
rf.setNumTrees(100);      
// Number of features per tree
rf.setNumFeatures(0);
// Seed
rf.setSeed( (new java.util.Random()).nextInt() );
 
// set classifier
seg.setClassifier(rf);

//Set feature stack array to the weka segmentation object
featuresArray.set(stack2featstack, 0);
seg.setFeatureStackArray(featuresArray);


// corresponding binary labels
labels = IJ.openImage("/home/dionysis/fermi/media/data/CNH/cnh_multispectral/Denmark_field_1/original images/15/MOG.bmp");
labelstack = new ImageStack(labels.getWidth(), labels.getHeight());
for (slice = 1; slice <= image.getStackSize(); slice++) {
        labelstack.addSlice("MOG "+slice, labels.getProcessor().duplicate());
}
labelstackimage = new ImagePlus("Labels_std&cust", labelstack);
labelstackimage.show();



// Add (balanced) labels
seg.addRandomBalancedBinaryData(image, labelstackimage, "class 2", "class 1", nSamplesToUse);
//seg.addBinaryData(image, labels, "class 2", "class 1");


// Train classifier
seg.trainClassifier();

//save Classifier
seg.saveClassifier("/home/dionysis/Desktop/testclassifier.model");
 

// Open test image
image = IJ.openImage("/home/dionysis/fermi/media/data/CNH/cnh_multispectral/Denmark_field_1/original images/15/multi-spectral.tif");
IJ.run(image, "32-bit", "");
IJ.log("Test image loaded");
// Apply trained classifier to test image and get probabilities
prob = seg.applyClassifier(image, 0, true );
IJ.log("Classifier applied");
 
// Display results
prob.setTitle( "Probability maps of test image" );
IJ.log("Showing results");
prob.show();

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: classifying multi-spectral images using Advanced Weka Segmaentation

Ignacio Arganda-Carreras
138 posts
Hello Dionysios,

If you create a special feature stack for training, you need to do exactly
the same for testing. There is an "applyClassifier" method in
WekaSegmentation that accepts a festure stack as input:

// Apply trained classifier to test image and get probabilities
prob = seg.applyClassifier( testFeatureStackArray 0, true );

where "testFeatureStackArray" needs to be previously created in the exact
same way you did for the training set.

Does it make sense?

ignacio


On Tue, Mar 26, 2013 at 1:49 PM, Dionysios Lefkaditis
<[hidden email]>wrote:

> Hello everyone,
>
> I am trying to classify/segment multi-spectral images. The original images
> are in multi-layer tiff format. I am computing a set of features for every
> slice/band and then adding it to a custom featureStack, so that the final
> feature vector is a collection of varying features coming from each of the
> spectral bands. I can successfully build the featurestack and train the
> classifier. However, when the classifier is applied to a test image, it
> seems that it classifies each band/slice separately. It is intended to
> treat each multi-sepctral image as one entity and thus produce a single
> slice classified image. As I am a newbe on Fiji's API and the javadoc site
> is currently down, I would greatly appreciate your input on this. I am also
> wandering how it would be possible to just apply such a classifier to other
> unseen images. How do I recompute the feature vector and feed it straight
> to the classifier?
>
> thanks a bunch,
> Dionysios
>
> I am sorry to clutter my post with a long script:
>
> import ij.*;
> import ij.process.*;
> import trainableSegmentation.*;
> import hr.irb.fastRandomForest.*;
>
> // training input image (it could be a stack or a single 2D image)
> opener = new Opener();
> image =
> opener.openImage("/home/dionysis/fermi/media/data/CNH/cnh_multispectral/Denmark_field_1/original
> images/15/multi-spectral.tif");
> //IJ.run(image, "8-bit", "");
> IJ.run(image, "32-bit", "");
>
>
>
> //*** Custom features***
>
> -----------------------------------
>
>
>
> // the FeatureStackArray contains a FeatureStack for every slice in our
> original image
> featuresArray = new FeatureStackArray(1, 1, 16, false, 1, 19, null);
>
> customstack = new ImageStack(image.getWidth(), image.getHeight());
> for (slice = 1; slice <= image.getStackSize(); slice++) {
>         image.setSlice(slice);
>
>         features = new FeatureStack(image.getProcessor().duplicate());
>         features.addGaussianBlur(20);
>         features.addLaplacian(5);
>         features.addHessian(2);
>         //features.show();
>
>
>         customstack.addSlice("original "+slice, features.getProcessor(1));
>         customstack.addSlice("gaussianstd "+slice,
> features.getProcessor(2));
>         customstack.addSlice("Laplacianstd "+slice,
> features.getProcessor(3));
>
> }
>
> //customFeaturesImage = new ImagePlus("features_std&cust", customstack);
> //customFeaturesImage.show();
>
>
>
> // create new feature stack with the custom features
> stack2featstack = new FeatureStack( image );
> stack2featstack.setStack( customstack );
> stack2featstack.show();
> //print(stack2featstack.getSize());
>
>
>
> // create Weka segmentator
> seg = new WekaSegmentation(image);
>
> // number of samples to use per slice
> nSamplesToUse = 1000;
>
>
> // Classifier
> // In this case we use a Fast Random Forest
> rf = new FastRandomForest();
> // Number of trees in the forest
> rf.setNumTrees(100);
> // Number of features per tree
> rf.setNumFeatures(0);
> // Seed
> rf.setSeed( (new java.util.Random()).nextInt() );
>
> // set classifier
> seg.setClassifier(rf);
>
> //Set feature stack array to the weka segmentation object
> featuresArray.set(stack2featstack, 0);
> seg.setFeatureStackArray(featuresArray);
>
>
> // corresponding binary labels
> labels =
> IJ.openImage("/home/dionysis/fermi/media/data/CNH/cnh_multispectral/Denmark_field_1/original
> images/15/MOG.bmp");
> labelstack = new ImageStack(labels.getWidth(), labels.getHeight());
> for (slice = 1; slice <= image.getStackSize(); slice++) {
>         labelstack.addSlice("MOG "+slice,
> labels.getProcessor().duplicate());
> }
> labelstackimage = new ImagePlus("Labels_std&cust", labelstack);
> labelstackimage.show();
>
>
>
> // Add (balanced) labels
> seg.addRandomBalancedBinaryData(image, labelstackimage, "class 2", "class
> 1", nSamplesToUse);
> //seg.addBinaryData(image, labels, "class 2", "class 1");
>
>
> // Train classifier
> seg.trainClassifier();
>
> //save Classifier
> seg.saveClassifier("/home/dionysis/Desktop/testclassifier.model");
>
>
> // Open test image
> image =
> IJ.openImage("/home/dionysis/fermi/media/data/CNH/cnh_multispectral/Denmark_field_1/original
> images/15/multi-spectral.tif");
> IJ.run(image, "32-bit", "");
> IJ.log("Test image loaded");
> // Apply trained classifier to test image and get probabilities
> prob = seg.applyClassifier(image, 0, true );
> IJ.log("Classifier applied");
>
> // Display results
> prob.setTitle( "Probability maps of test image" );
> IJ.log("Showing results");
> prob.show();
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>



--
Ignacio Arganda-Carreras, Ph.D.
Seung's lab, 46-5065
Department of Brain and Cognitive Sciences
Massachusetts Institute of Technology
43 Vassar St.
Cambridge, MA 02139
USA

Phone: (001) 617-324-3747
Website: http://bioweb.cnb.csic.es/~iarganda/index_EN.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
| More
Print post
Permalink

Re: classifying multi-spectral images using Advanced Weka Segmaentation

Dionysios Lefkaditis
8 posts
Hello Ignacio,

It makes prefect sense to me. However, it does not work. It pops up a
message "Could not apply classifier". If I do "seg.applyClassifier( true
);" instead the classification runs smoothly. Do you think this the
correct way to do this or am I getting bogus results? I am a bit
confused because when I comment out some of the precomputed features it
will still run, but give different results. I would expect it not to run
at all.

the script I am using is attached to this email.

Thank you again,

Dionysios



-----Original Message-----
From: Ignacio Arganda-Carreras <[hidden email]>
Reply-to: <[hidden email]>
To: [hidden email]
Subject: Re: classifying multi-spectral images using Advanced Weka
Segmaentation
Date: Tue, 26 Mar 2013 15:22:55 -0400

Hello Dionysios,

If you create a special feature stack for training, you need to do exactly
the same for testing. There is an "applyClassifier" method in
WekaSegmentation that accepts a festure stack as input:

// Apply trained classifier to test image and get probabilities
prob = seg.applyClassifier( testFeatureStackArray 0, true );

where "testFeatureStackArray" needs to be previously created in the exact
same way you did for the training set.

Does it make sense?

ignacio


On Tue, Mar 26, 2013 at 1:49 PM, Dionysios Lefkaditis
<[hidden email]>wrote:

> Hello everyone,
>
> I am trying to classify/segment multi-spectral images. The original images
> are in multi-layer tiff format. I am computing a set of features for every
> slice/band and then adding it to a custom featureStack, so that the final
> feature vector is a collection of varying features coming from each of the
> spectral bands. I can successfully build the featurestack and train the
> classifier. However, when the classifier is applied to a test image, it
> seems that it classifies each band/slice separately. It is intended to
> treat each multi-sepctral image as one entity and thus produce a single
> slice classified image. As I am a newbe on Fiji's API and the javadoc site
> is currently down, I would greatly appreciate your input on this. I am also
> wandering how it would be possible to just apply such a classifier to other
> unseen images. How do I recompute the feature vector and feed it straight
> to the classifier?
>
> thanks a bunch,
> Dionysios
>
> I am sorry to clutter my post with a long script:
>
> import ij.*;
> import ij.process.*;
> import trainableSegmentation.*;
> import hr.irb.fastRandomForest.*;
>
> // training input image (it could be a stack or a single 2D image)
> opener = new Opener();
> image =
> opener.openImage("/home/dionysis/fermi/media/data/CNH/cnh_multispectral/Denmark_field_1/original
> images/15/multi-spectral.tif");
> //IJ.run(image, "8-bit", "");
> IJ.run(image, "32-bit", "");
>
>
>
> //*** Custom features***
>
> -----------------------------------
>
>
>
> // the FeatureStackArray contains a FeatureStack for every slice in our
> original image
> featuresArray = new FeatureStackArray(1, 1, 16, false, 1, 19, null);
>
> customstack = new ImageStack(image.getWidth(), image.getHeight());
> for (slice = 1; slice <= image.getStackSize(); slice++) {
>         image.setSlice(slice);
>
>         features = new FeatureStack(image.getProcessor().duplicate());
>         features.addGaussianBlur(20);
>         features.addLaplacian(5);
>         features.addHessian(2);
>         //features.show();
>
>
>         customstack.addSlice("original "+slice, features.getProcessor(1));
>         customstack.addSlice("gaussianstd "+slice,
> features.getProcessor(2));
>         customstack.addSlice("Laplacianstd "+slice,
> features.getProcessor(3));
>
> }
>
> //customFeaturesImage = new ImagePlus("features_std&cust", customstack);
> //customFeaturesImage.show();
>
>
>
> // create new feature stack with the custom features
> stack2featstack = new FeatureStack( image );
> stack2featstack.setStack( customstack );
> stack2featstack.show();
> //print(stack2featstack.getSize());
>
>
>
> // create Weka segmentator
> seg = new WekaSegmentation(image);
>
> // number of samples to use per slice
> nSamplesToUse = 1000;
>
>
> // Classifier
> // In this case we use a Fast Random Forest
> rf = new FastRandomForest();
> // Number of trees in the forest
> rf.setNumTrees(100);
> // Number of features per tree
> rf.setNumFeatures(0);
> // Seed
> rf.setSeed( (new java.util.Random()).nextInt() );
>
> // set classifier
> seg.setClassifier(rf);
>
> //Set feature stack array to the weka segmentation object
> featuresArray.set(stack2featstack, 0);
> seg.setFeatureStackArray(featuresArray);
>
>
> // corresponding binary labels
> labels =
> IJ.openImage("/home/dionysis/fermi/media/data/CNH/cnh_multispectral/Denmark_field_1/original
> images/15/MOG.bmp");
> labelstack = new ImageStack(labels.getWidth(), labels.getHeight());
> for (slice = 1; slice <= image.getStackSize(); slice++) {
>         labelstack.addSlice("MOG "+slice,
> labels.getProcessor().duplicate());
> }
> labelstackimage = new ImagePlus("Labels_std&cust", labelstack);
> labelstackimage.show();
>
>
>
> // Add (balanced) labels
> seg.addRandomBalancedBinaryData(image, labelstackimage, "class 2", "class
> 1", nSamplesToUse);
> //seg.addBinaryData(image, labels, "class 2", "class 1");
>
>
> // Train classifier
> seg.trainClassifier();
>
> //save Classifier
> seg.saveClassifier("/home/dionysis/Desktop/testclassifier.model");
>
>
> // Open test image
> image =
> IJ.openImage("/home/dionysis/fermi/media/data/CNH/cnh_multispectral/Denmark_field_1/original
> images/15/multi-spectral.tif");
> IJ.run(image, "32-bit", "");
> IJ.log("Test image loaded");
> // Apply trained classifier to test image and get probabilities
> prob = seg.applyClassifier(image, 0, true );
> IJ.log("Classifier applied");
>
> // Display results
> prob.setTitle( "Probability maps of test image" );
> IJ.log("Showing results");
> prob.show();
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>



--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html

cnh_apply_custom_classifier.bsh (2K) Download Attachment