From 2d159b08e60a396d05dc16861cc6ab4d40f34e40 Mon Sep 17 00:00:00 2001
From: Charles Peyrega <charles.peyrega@c-s.fr>
Date: Tue, 2 Jul 2013 09:13:46 +0200
Subject: [PATCH] DOC: Add a generic image classification example in the SG

---
 Examples/Classification/CMakeLists.txt        |  4 +-
 ... SupervisedImageClassificationExample.cxx} | 76 +++++++++++++------
 ...nMachineLearningModelFromImagesExample.cxx | 58 +++++++-------
 ...MachineLearningModelFromSamplesExample.cxx | 24 +++---
 4 files changed, 98 insertions(+), 64 deletions(-)
 rename Examples/Classification/{SVMImageClassifierExample.cxx => SupervisedImageClassificationExample.cxx} (53%)

diff --git a/Examples/Classification/CMakeLists.txt b/Examples/Classification/CMakeLists.txt
index 4b94324402..6fdc0a12ee 100644
--- a/Examples/Classification/CMakeLists.txt
+++ b/Examples/Classification/CMakeLists.txt
@@ -25,8 +25,8 @@ TARGET_LINK_LIBRARIES(ScalarImageMarkovRandomField1 OTBIO OTBCommon )
 ADD_EXECUTABLE(SOMImageClassificationExample SOMImageClassificationExample.cxx )
 TARGET_LINK_LIBRARIES(SOMImageClassificationExample OTBIO OTBLearning)
 
-ADD_EXECUTABLE(SVMImageClassificationExample2 SVMImageClassifierExample.cxx )
-TARGET_LINK_LIBRARIES(SVMImageClassificationExample2 OTBIO OTBLearning)
+ADD_EXECUTABLE(SupervisedImageClassificationExample SupervisedImageClassificationExample.cxx )
+TARGET_LINK_LIBRARIES(SupervisedImageClassificationExample OTBIO OTBLearning)
 
 ADD_EXECUTABLE(ClassificationMapRegularizationExample ClassificationMapRegularizationExample.cxx )
 TARGET_LINK_LIBRARIES(ClassificationMapRegularizationExample OTBIO OTBCommon)
diff --git a/Examples/Classification/SVMImageClassifierExample.cxx b/Examples/Classification/SupervisedImageClassificationExample.cxx
similarity index 53%
rename from Examples/Classification/SVMImageClassifierExample.cxx
rename to Examples/Classification/SupervisedImageClassificationExample.cxx
index 9bbe66976d..ff5f57fb9c 100644
--- a/Examples/Classification/SVMImageClassifierExample.cxx
+++ b/Examples/Classification/SupervisedImageClassificationExample.cxx
@@ -18,20 +18,25 @@
 
 // Software Guide : BeginLatex
 //
-// In previous examples, we have used the
-// \doxygen{otb}{SVMClassifier}, which uses the ITK classification
-// framework. This good for compatibility with the ITK framework, but
-// introduces the limitations of not being able to use streaming and
-// being able to know at compilation time the number of bands of the
-// image to be classified. In OTB we have avoided this limitation by
-// developing the \doxygen{otb}{SVMImageClassificationFilter}. In
-// this example we will illustrate its use. We start by including the
-// appropriate header file.
+// In OTB, a generic streamed filter called \doxygen{otb}{ImageClassificationFilter}
+// is available to classify any input multi-channel image according to an input
+// classification model file. This filter is generic because it works with any
+// classification model type (SVM, KNN, Artificial Neural Network,...) generated
+// within the OTB generic Machine Learning framework based on OpenCV (\cite{opencv_library}).
+// The input model file is smartly parsed according to its content in order to
+// identify which learning method was used to generate it. Once the classification
+// method and model are known, the input image can be classified. More details are
+// given in subsections \ref{ssec:LearningFromSamples} and \ref{ssec:LearningFromImages}
+// to generate a classification model either from samples or from images.
+// In this example we will illustrate its use. We start by including the
+// appropriate header files.
 //
 // Software Guide : EndLatex
 
 // Software Guide : BeginCodeSnippet
-#include "otbSVMImageClassificationFilter.h"
+#include "otbMacro.h"
+#include "otbMachineLearningModelFactory.h"
+#include "otbImageClassificationFilter.h"
 // Software Guide : EndCodeSnippet
 
 #include "otbVectorImage.h"
@@ -53,34 +58,46 @@ int main(int argc, char * argv[])
 // Software Guide : EndLatex
 
 // Software Guide : BeginCodeSnippet
-  const unsigned int Dimension = 2;
+  const unsigned int     Dimension = 2;
   typedef double         PixelType;
   typedef unsigned short LabeledPixelType;
 // Software Guide : EndCodeSnippet
 // Software Guide : BeginLatex
 //
-// Our classifier will be generic enough to be able to process images
-// with any number of bands. We read the images as
-// \doxygen{otb}{VectorImage}s. The labeled image will be a scalar image.
+// Our classifier is generic enough to be able to process images
+// with any number of bands. We read the input image as a
+// \doxygen{otb}{VectorImage}. The labeled image will be a scalar image.
 //
 // Software Guide : EndLatex
-
 // Software Guide : BeginCodeSnippet
   typedef otb::VectorImage<PixelType, Dimension>  ImageType;
   typedef otb::Image<LabeledPixelType, Dimension> LabeledImageType;
 // Software Guide : EndCodeSnippet
+
 // Software Guide : BeginLatex
 //
 // We can now define the type for the classifier filter, which is
 // templated over its input and output image types.
 //
 // Software Guide : EndLatex
-
 // Software Guide : BeginCodeSnippet
-  typedef otb::SVMImageClassificationFilter
-  <ImageType, LabeledImageType>  ClassificationFilterType;
+  typedef otb::ImageClassificationFilter<ImageType, LabeledImageType>
+                                                          ClassificationFilterType;
   typedef ClassificationFilterType::ModelType ModelType;
 // Software Guide : EndCodeSnippet
+
+// Software Guide : BeginLatex
+//
+// Moreover, it is necessary to define a \doxygen{otb}{MachineLearningModelFactory}
+// which is templated over its input and output pixel types. This factory is used
+// to parse the input model file and to define which classification method to use.
+//
+// Software Guide : EndLatex
+// Software Guide : BeginCodeSnippet
+  typedef otb::MachineLearningModelFactory<PixelType, LabeledPixelType>
+                                                   MachineLearningModelFactoryType;
+// Software Guide : EndCodeSnippet
+
 // Software Guide : BeginLatex
 //
 // And finally, we define the reader and the writer. Since the images
@@ -88,29 +105,40 @@ int main(int argc, char * argv[])
 // will trigger the streaming ability of the classifier.
 //
 // Software Guide : EndLatex
-
 // Software Guide : BeginCodeSnippet
-  typedef otb::ImageFileReader<ImageType>                 ReaderType;
+  typedef otb::ImageFileReader<ImageType>        ReaderType;
   typedef otb::ImageFileWriter<LabeledImageType> WriterType;
 // Software Guide : EndCodeSnippet
+
 // Software Guide : BeginLatex
 //
 // We instantiate the classifier and the reader objects and we set
-// the existing SVM model obtained in a previous training step.
+// the existing model obtained in a previous training step.
 //
 // Software Guide : EndLatex
-
 // Software Guide : BeginCodeSnippet
   ClassificationFilterType::Pointer filter = ClassificationFilterType::New();
 
   ReaderType::Pointer reader = ReaderType::New();
   reader->SetFileName(infname);
+// Software Guide : EndCodeSnippet
 
-  ModelType::Pointer model = ModelType::New();
-  model->LoadModel(modelfname);
+// Software Guide : BeginLatex
+//
+// The input model file is parsed according to its content and the generated model
+// is then loaded within the \doxygen{otb}{ImageClassificationFilter}.
+//
+// Software Guide : EndLatex
+// Software Guide : BeginCodeSnippet
+  ModelType::Pointer model;
+  model = MachineLearningModelFactoryType::CreateMachineLearningModel(
+                                        modelfname,
+                                        MachineLearningModelFactoryType::ReadMode);
+  model->Load(modelfname);
 
   filter->SetModel(model);
 // Software Guide : EndCodeSnippet
+
 // Software Guide : BeginLatex
 //
 // We plug the pipeline and
diff --git a/Examples/Learning/TrainMachineLearningModelFromImagesExample.cxx b/Examples/Learning/TrainMachineLearningModelFromImagesExample.cxx
index f248756206..045f0c717d 100644
--- a/Examples/Learning/TrainMachineLearningModelFromImagesExample.cxx
+++ b/Examples/Learning/TrainMachineLearningModelFromImagesExample.cxx
@@ -16,25 +16,6 @@
 
 =========================================================================*/
 
-//Image
-#include "otbVectorImage.h"
-#include "otbVectorData.h"
-#include "otbListSampleGenerator.h"
-
-//Reader
-#include "otbImageFileReader.h"
-#include "otbVectorDataFileReader.h"
-
-//Estimator
-# include "otbSVMMachineLearningModel.h"
-#include "otbMachineLearningModelFactory.h"
-
-// Normalize the samples
-#include "otbShiftScaleSampleListFilter.h"
-
-// Extract a ROI of the vectordata
-#include "otbVectorDataIntoImageProjectionFilter.h"
-
 //  Software Guide : BeginCommandLineArgs
 //    INPUTS: {QB_1_ortho.tif}, {VectorData_QB1.shp}
 //    OUTPUTS: {clLIBSVMModelQB1.libsvm}
@@ -44,13 +25,35 @@
 // This example illustrates the use of the
 // \doxygen{otb}{MachineLearningModel} class. This class allows the
 // estimation of a classification model (supervised learning) from images. In this example, we will train an SVM
-// with 4 classes.
+// with 4 classes. We start by including the appropriate header files.
 //
 //  Software Guide : EndLatex
+// Software Guide : BeginCodeSnippet
+// List sample generator
+#include "otbListSampleGenerator.h"
+
+// Extract a ROI of the vectordata
+#include "otbVectorDataIntoImageProjectionFilter.h"
+
+// SVM model Estimator
+#include "otbSVMMachineLearningModel.h"
+// Software Guide : EndCodeSnippet
+
+
+// Image
+#include "otbVectorImage.h"
+#include "otbVectorData.h"
+
+// Reader
+#include "otbImageFileReader.h"
+#include "otbVectorDataFileReader.h"
+
+// Normalize the samples
+//#include "otbShiftScaleSampleListFilter.h"
+
 
 int main(int argc, char* argv[])
 {
-
   const char* inputImageFileName = argv[1];
   const char* trainingShpFileName = argv[2];
   const char* outputModelFileName = argv[3];
@@ -64,8 +67,8 @@ int main(int argc, char* argv[])
 
   typedef otb::VectorData<double, 2>                   VectorDataType;
   
-  typedef otb::ImageFileReader<InputImageType>    InputReaderType;
-  typedef otb::VectorDataFileReader<VectorDataType> VectorDataReaderType;
+  typedef otb::ImageFileReader<InputImageType>         InputReaderType;
+  typedef otb::VectorDataFileReader<VectorDataType>    VectorDataReaderType;
 
 // Software Guide : BeginLatex
 //
@@ -84,9 +87,9 @@ int main(int argc, char* argv[])
 // Software Guide : BeginCodeSnippet
   // VectorData projection filter
   typedef otb::VectorDataIntoImageProjectionFilter<VectorDataType, InputImageType>
-                                              VectorDataReprojectionType;
+                                                        VectorDataReprojectionType;
 
-  InputReaderType::Pointer    inputReader = InputReaderType::New();
+  InputReaderType::Pointer inputReader = InputReaderType::New();
   inputReader->SetFileName(inputImageFileName);
   
   InputImageType::Pointer image = inputReader->GetOutput();
@@ -149,8 +152,9 @@ int main(int argc, char* argv[])
 // Software Guide : EndLatex
 
 // Software Guide : BeginCodeSnippet
-  typedef otb::SVMMachineLearningModel<InputImageType::InternalPixelType,
-                                       ListSampleGeneratorType::ClassLabelType> SVMType;
+  typedef otb::SVMMachineLearningModel
+                                 <InputImageType::InternalPixelType,
+                                  ListSampleGeneratorType::ClassLabelType> SVMType;
 
   SVMType::Pointer SVMClassifier = SVMType::New();
 
diff --git a/Examples/Learning/TrainMachineLearningModelFromSamplesExample.cxx b/Examples/Learning/TrainMachineLearningModelFromSamplesExample.cxx
index 4fe46985f5..ecfc1bf041 100644
--- a/Examples/Learning/TrainMachineLearningModelFromSamplesExample.cxx
+++ b/Examples/Learning/TrainMachineLearningModelFromSamplesExample.cxx
@@ -16,29 +16,31 @@
 
 =========================================================================*/
 
-//Random
-#include "itkMersenneTwisterRandomVariateGenerator.h"
-
-//List sample generator
-#include "otbListSampleGenerator.h"
-
-//Estimator
-# include "otbSVMMachineLearningModel.h"
-#include "otbMachineLearningModelFactory.h"
-
-
 //  Software Guide : BeginCommandLineArgs
 //    INPUTS: {1000}, {4}, {5}, {121212}
 //    OUTPUTS: {clSVMModelFromSamples.svm}
 //  Software Guide : EndCommandLineArgs
 
 //  Software Guide : BeginLatex
+//
 // This example illustrates the use of the \doxygen{otb}{SVMMachineLearningModel} class, which inherits from the
 // \doxygen{otb}{MachineLearningModel} class. This class allows the
 // estimation of a classification model (supervised learning) from samples. In this example, we will train an SVM model
 // with 4 output classes, from 1000 randomly generated training samples, each of them having 7 components.
+// We start by including the appropriate header files.
 //
 //  Software Guide : EndLatex
+// Software Guide : BeginCodeSnippet
+// List sample generator
+#include "otbListSampleGenerator.h"
+
+// Random number generator
+#include "itkMersenneTwisterRandomVariateGenerator.h"
+
+// SVM model Estimator
+#include "otbSVMMachineLearningModel.h"
+// Software Guide : EndCodeSnippet
+
 
 int main(int argc, char* argv[])
 {
-- 
GitLab