From 6d6b25fec297f18dc45043f780a320d4e55607d0 Mon Sep 17 00:00:00 2001
From: Jordi Inglada <jordi.inglada@orfeo-toolbox.org>
Date: Wed, 14 Jun 2006 15:09:28 +0000
Subject: [PATCH] Nouveaux exemples segmentation

---
 .../otbComplexMomentImageFunction.txx         |   4 +-
 Code/FeatureExtraction/otbHuImageFunction.txx |   9 +-
 Examples/Segmentation/CMakeLists.txt          |  12 +-
 .../NeighborhoodConnectedImageFilter.cxx      | 342 ++++++++++++++++++
 .../OtsuMultipleThresholdImageFilter.cxx      | 195 ++++++++++
 .../Segmentation/OtsuThresholdImageFilter.cxx | 231 ++++++++++++
 6 files changed, 788 insertions(+), 5 deletions(-)
 create mode 100644 Examples/Segmentation/NeighborhoodConnectedImageFilter.cxx
 create mode 100755 Examples/Segmentation/OtsuMultipleThresholdImageFilter.cxx
 create mode 100755 Examples/Segmentation/OtsuThresholdImageFilter.cxx

diff --git a/Code/FeatureExtraction/otbComplexMomentImageFunction.txx b/Code/FeatureExtraction/otbComplexMomentImageFunction.txx
index 1f67679df3..a9ef0f2bc7 100644
--- a/Code/FeatureExtraction/otbComplexMomentImageFunction.txx
+++ b/Code/FeatureExtraction/otbComplexMomentImageFunction.txx
@@ -111,7 +111,9 @@ ComplexMomentImageFunction<TInput,TOutput,TCoordRep>
       --q; 
      }
           
-    Sum += ( ValP * ValQ * std::complex<float>(static_cast<float>(it.GetPixel(i)),0.0) ); 
+    Sum += ( ValP * ValQ * std::complex<float>(static_cast<float>(it.GetPixel(i)),0.0) );
+
+    //std::cout << Sum << std::endl;
   }
 
   return (static_cast<ComplexType>(Sum) );
diff --git a/Code/FeatureExtraction/otbHuImageFunction.txx b/Code/FeatureExtraction/otbHuImageFunction.txx
index 62b24cc4ab..d6e2feed25 100644
--- a/Code/FeatureExtraction/otbHuImageFunction.txx
+++ b/Code/FeatureExtraction/otbHuImageFunction.txx
@@ -62,18 +62,23 @@ HuImageFunction<TInput,TOutput,TCoordRep>
     {
     return ( itk::NumericTraits<RealType>::max() );
     }
+
+
+/*  std::cout << "Start" << this->GetStartIndex() << std::endl;
+  std::cout << "End" << this->GetEndIndex() << std::endl; */
   
   if ( !this->IsInsideBuffer( index ) )
     {
+    std::cout << index << std::endl;
     return ( itk::NumericTraits<RealType>::max() );
     }
 
   assert(m_MomentNumber > 0);
   assert(m_MomentNumber < 8);
-	
+
    function->SetInputImage( this->GetInputImage() );
 //OTB-FA-00025-CS
-   std::cout << "Neighbor " <<this->GetNeighborhoodRadius()<<std::endl;
+//   std::cout << "Neighbor " <<this->GetNeighborhoodRadius()<<std::endl;
    function->SetNeighborhoodRadius(this->GetNeighborhoodRadius() );
 
   //OTB-FA-00024-CS
diff --git a/Examples/Segmentation/CMakeLists.txt b/Examples/Segmentation/CMakeLists.txt
index 087e2e1ec4..535beedcbc 100644
--- a/Examples/Segmentation/CMakeLists.txt
+++ b/Examples/Segmentation/CMakeLists.txt
@@ -8,11 +8,19 @@ INCLUDE_REGULAR_EXPRESSION("^.*$")
 ADD_EXECUTABLE(ConnectedThresholdImageFilter ConnectedThresholdImageFilter.cxx )
 TARGET_LINK_LIBRARIES(ConnectedThresholdImageFilter OTBCommon OTBIO ITKNumerics ITKIO)
 
+ADD_EXECUTABLE(OtsuThresholdImageFilter OtsuThresholdImageFilter.cxx )
+TARGET_LINK_LIBRARIES(OtsuThresholdImageFilter OTBCommon OTBIO ITKCommon ITKIO)
+
+ADD_EXECUTABLE(OtsuMultipleThresholdImageFilter OtsuMultipleThresholdImageFilter.cxx )
+TARGET_LINK_LIBRARIES(OtsuMultipleThresholdImageFilter
+                      OTBCommon OTBIO ITKCommon ITKIO ITKStatistics)
+
 #ADD_EXECUTABLE(ConfidenceConnected ConfidenceConnected.cxx )
 #TARGET_LINK_LIBRARIES(ConfidenceConnected ITKNumerics ITKIO)
 
-#ADD_EXECUTABLE(NeighborhoodConnectedImageFilter NeighborhoodConnectedImageFilter.cxx )
-#TARGET_LINK_LIBRARIES(NeighborhoodConnectedImageFilter ITKNumerics ITKIO)
+ADD_EXECUTABLE(NeighborhoodConnectedImageFilter NeighborhoodConnectedImageFilter.cxx )
+TARGET_LINK_LIBRARIES(NeighborhoodConnectedImageFilter OTBCommon OTBIO
+ITKNumerics ITKIO)
 
 #ADD_EXECUTABLE(IsolatedConnectedImageFilter IsolatedConnectedImageFilter.cxx )
 #TARGET_LINK_LIBRARIES(IsolatedConnectedImageFilter ITKNumerics ITKIO)
diff --git a/Examples/Segmentation/NeighborhoodConnectedImageFilter.cxx b/Examples/Segmentation/NeighborhoodConnectedImageFilter.cxx
new file mode 100644
index 0000000000..781a2b6c8e
--- /dev/null
+++ b/Examples/Segmentation/NeighborhoodConnectedImageFilter.cxx
@@ -0,0 +1,342 @@
+
+#if defined(_MSC_VER)
+#pragma warning ( disable : 4786 )
+#endif
+
+#ifdef __BORLANDC__
+#define ITK_LEAN_AND_MEAN
+#endif
+
+//  Software Guide : BeginCommandLineArgs
+//  INPUTS: {QB_Suburb.png}
+//  OUTPUTS: {NeighborhoodConnectedThresholdOutput1.png}
+//  110 38 50 100
+//  Software Guide : EndCommandLineArgs
+//  Software Guide : BeginCommandLineArgs
+//  INPUTS: {QB_Suburb.png}
+//  OUTPUTS: {NeighborhoodConnectedThresholdOutput2.png}
+//  118 100 0 10
+//  Software Guide : EndCommandLineArgs
+//  Software Guide : BeginCommandLineArgs
+//  INPUTS: {QB_Suburb.png}
+//  OUTPUTS: {NeighborhoodConnectedThresholdOutput3.png}
+//  169 146 220 255
+//  Software Guide : EndCommandLineArgs
+
+// Software Guide : BeginLatex
+//
+// The following example illustrates the use of the
+// \doxygen{itk::NeighborhoodConnectedImageFilter}.  This filter is a close variant
+// of the \doxygen{itk::ConnectedThresholdImageFilter}. On one hand, the
+// ConnectedThresholdImageFilter accepts a pixel in the region if its intensity
+// is in the interval defined by two user-provided threshold values.  The
+// NeighborhoodConnectedImageFilter, on the other hand, will only accept a
+// pixel if \textbf{all} its neighbors have intensities that fit in the
+// interval. The size of the neighborhood to be considered around each pixel is
+// defined by a user-provided integer radius. 
+//
+// The reason for considering the neighborhood intensities instead of only the
+// current pixel intensity is that small structures are less likely to be
+// accepted in the region. The operation of this filter is equivalent to
+// applying the ConnectedThresholdImageFilter followed by mathematical
+// morphology erosion using a structuring element of the same shape as
+// the neighborhood provided to the NeighborhoodConnectedImageFilter.
+//
+// Software Guide : EndLatex 
+
+
+// Software Guide : BeginCodeSnippet
+#include "itkNeighborhoodConnectedImageFilter.h"
+// Software Guide : EndCodeSnippet
+
+
+#include "otbImage.h"
+#include "itkCastImageFilter.h"
+
+
+//  Software Guide : BeginLatex
+//
+//  The \doxygen{itk::CurvatureFlowImageFilter} is used here to smooth the image
+//  while preserving edges.
+//
+//  Software Guide : EndLatex 
+
+// Software Guide : BeginCodeSnippet
+#include "itkCurvatureFlowImageFilter.h"
+// Software Guide : EndCodeSnippet
+
+
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+
+
+int main( int argc, char *argv[] )
+{
+  if( argc < 7 )
+    {
+    std::cerr << "Missing Parameters " << std::endl;
+    std::cerr << "Usage: " << argv[0];
+    std::cerr << " inputImage  outputImage seedX seedY lowerThreshold upperThreshold" << std::endl;
+    return 1;
+    }
+
+
+  //  Software Guide : BeginLatex
+  //  
+  //  We now define the image type using a particular pixel type and image
+  //  dimension. In this case the \code{float} type is used for the pixels due
+  //  to the requirements of the smoothing filter. 
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  typedef   float           InternalPixelType;
+  const     unsigned int    Dimension = 2;
+  typedef itk::Image< InternalPixelType, Dimension >  InternalImageType;
+  // Software Guide : EndCodeSnippet
+
+  //FIXME : OTBIMAGE
+  typedef unsigned char OutputPixelType;
+  typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
+
+  typedef itk::CastImageFilter< InternalImageType, OutputImageType >
+    CastingFilterType;
+  CastingFilterType::Pointer caster = CastingFilterType::New();
+                        
+
+  // We instantiate reader and writer types
+  //
+  typedef  otb::ImageFileReader< InternalImageType > ReaderType;
+  typedef  otb::ImageFileWriter<  OutputImageType  > WriterType;
+
+  ReaderType::Pointer reader = ReaderType::New();
+  WriterType::Pointer writer = WriterType::New();
+
+  reader->SetFileName( argv[1] );
+  writer->SetFileName( argv[2] );
+
+
+  //  Software Guide : BeginLatex
+  //  
+  //  The smoothing filter type is instantiated using the image type as
+  //  a template parameter.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  typedef   itk::CurvatureFlowImageFilter<InternalImageType, InternalImageType>
+    CurvatureFlowImageFilterType;
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //  
+  //  Then, the filter is created by invoking the \code{New()} method and
+  //  assigning the result to a \doxygen{itk::SmartPointer}.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  CurvatureFlowImageFilterType::Pointer smoothing = 
+                         CurvatureFlowImageFilterType::New();
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //  
+  //  We now declare the type of the region growing filter. In this case it is
+  //  the NeighborhoodConnectedImageFilter. 
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  typedef itk::NeighborhoodConnectedImageFilter<InternalImageType,
+                                    InternalImageType > ConnectedFilterType;
+  // Software Guide : EndCodeSnippet
+
+  //  Software Guide : BeginLatex
+  //  
+  //  One filter of this class is constructed using the \code{New()} method. 
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  ConnectedFilterType::Pointer neighborhoodConnected = ConnectedFilterType::New();
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //  
+  //  Now it is time to create a simple, linear data processing pipeline. A
+  //  file reader is added at the beginning of the pipeline and a cast
+  //  filter and writer are added at the end. The cast filter is required
+  //  to convert \code{float} pixel types to integer types since only a
+  //  few image file formats support \code{float} types.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  smoothing->SetInput( reader->GetOutput() );
+  neighborhoodConnected->SetInput( smoothing->GetOutput() );
+  caster->SetInput( neighborhoodConnected->GetOutput() );
+  writer->SetInput( caster->GetOutput() );
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //
+  //  The CurvatureFlowImageFilter requires a couple of parameters to
+  //  be defined. The following are typical values for $2D$ images. However
+  //  they may have to be adjusted depending on the amount of noise present in
+  //  the input image.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  smoothing->SetNumberOfIterations( 5 );
+  smoothing->SetTimeStep( 0.125 );
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //
+  //  The NeighborhoodConnectedImageFilter requires that two main parameters
+  //  are specified. They are the lower and upper thresholds of the interval
+  //  in which intensity values must fall to be included in the
+  //  region. Setting these two values too close will not allow enough
+  //  flexibility for the region to grow. Setting them too far apart will
+  //  result in a region that engulfs the image.
+  //
+  //  \index{itk::NeighborhoodConnectedImageFilter!SetLower()}
+  //  \index{itk::NeighborhoodConnectedImageFilter!SetUppder()}
+  //
+  //  Software Guide : EndLatex 
+
+  const InternalPixelType lowerThreshold = atof( argv[5] );
+  const InternalPixelType upperThreshold = atof( argv[6] );
+
+  // Software Guide : BeginCodeSnippet
+  neighborhoodConnected->SetLower(  lowerThreshold  );
+  neighborhoodConnected->SetUpper(  upperThreshold  );
+  // Software Guide : EndCodeSnippet
+
+  //  Software Guide : BeginLatex
+  //  
+  //  Here, we add the crucial parameter that defines the neighborhood size
+  //  used to determine whether a pixel lies in the region. The larger the
+  //  neighborhood, the more stable this filter will be against noise in the
+  //  input image, but also the longer the computing time will be.  Here we
+  //  select a filter of radius $2$ along each dimension. This results in a
+  //  neighborhood of $5 \times 5$ pixels.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  InternalImageType::SizeType   radius;
+
+  radius[0] = 2;   // two pixels along X 
+  radius[1] = 2;   // two pixels along Y 
+
+  neighborhoodConnected->SetRadius( radius );
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //
+  //  As in the ConnectedThresholdImageFilter we must now provide the
+  //  intensity value to be used for the output pixels accepted in the region
+  //  and at least one seed point to define the initial region.
+  //
+  //  \index{itk::NeighborhoodConnectedImageFilter!SetSeed()}
+  //  \index{itk::NeighborhoodConnectedImageFilter!SetReplaceValue()}
+  //
+  //  Software Guide : EndLatex 
+
+  InternalImageType::IndexType  index;
+  
+  index[0] = atoi( argv[3] );
+  index[1] = atoi( argv[4] );
+
+
+  // Software Guide : BeginCodeSnippet
+  neighborhoodConnected->SetSeed( index );
+  neighborhoodConnected->SetReplaceValue( 255 );
+  // Software Guide : EndCodeSnippet
+
+  
+  //  Software Guide : BeginLatex
+  //  
+  //  The invocation of the \code{Update()} method on the writer triggers the
+  //  execution of the pipeline.  It is usually wise to put update calls in a
+  //  \code{try/catch} block in case errors occur and exceptions are thrown.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  try
+    {
+    writer->Update();
+    }
+  catch( itk::ExceptionObject & excep )
+    {
+    std::cerr << "Exception caught !" << std::endl;
+    std::cerr << excep << std::endl;
+    }
+  // Software Guide : EndCodeSnippet
+
+
+    //  Software Guide : BeginLatex
+  //
+  //  Let's run this example using as input the image
+  //  \code{QB\_Suburb.png} provided in the directory
+  //  \code{Examples/Data}. We can easily segment the major 
+  //  structures by providing seeds in the appropriate locations and defining
+  //  values for the lower and upper thresholds.
+  //  Figure~\ref{fig:NeighborhoodConnectedThresholdOutput} illustrates several examples of
+  //  segmentation. The parameters used are presented in
+  //  Table~\ref{tab:NeighborhoodConnectedThresholdOutput}.
+  //
+  //  \begin{table}
+  //  \begin{center}
+  //  \begin{tabular}{|l|c|c|c|c|}
+  //  \hline
+  //  Structure & Seed Index & Lower & Upper & Output Image \\ \hline 
+  //  Road & $(110,38)$ & 50 & 100 & Second from left in Figure \ref{fig:NeighborhoodConnectedThresholdOutput} \\ \hline
+  //  Shadow    & $(118,100)$ & 0 & 10 & Third  from left in Figure \ref{fig:NeighborhoodConnectedThresholdOutput} \\ \hline
+  //  Building  & $(169,146)$ & 220 & 255 & Fourth from left in Figure \ref{fig:NeighborhoodConnectedThresholdOutput} \\ \hline
+  //  \end{tabular}
+  //  \end{center}
+  //  \itkcaption[NeighborhoodConnectedThreshold example parameters]{Parameters used for
+  //  segmenting some structures shown in
+  //  Figure~\ref{fig:NeighborhoodConnectedThresholdOutput} with the filter
+  //  \doxygen{itk::NeighborhoodConnectedThresholdImageFilter}.\label{tab:NeighborhoodConnectedThresholdOutput}}
+  //  \end{table}
+  //
+  // \begin{figure} \center
+  // \includegraphics[width=0.24\textwidth]{QB_Suburb.eps}
+  // \includegraphics[width=0.24\textwidth]{NeighborhoodConnectedThresholdOutput1.eps}
+  // \includegraphics[width=0.24\textwidth]{NeighborhoodConnectedThresholdOutput2.eps}
+  // \includegraphics[width=0.24\textwidth]{NeighborhoodConnectedThresholdOutput3.eps}
+  // \itkcaption[NeighborhoodConnectedThreshold segmentation results]{Segmentation results 
+  // for the NeighborhoodConnectedThreshold filter for various seed points.}
+  // \label{fig:NeighborhoodConnectedThresholdOutput}
+  // \end{figure}
+  //
+  //  As with the ConnectedThresholdImageFilter, several seeds could
+  //  be provided to the filter by using the \code{AddSeed()} method.
+  //  Compare the output of Figure
+  //  \ref{fig:NeighborhoodConnectedImageFilterOutput} with those of Figure
+  //  \ref{fig:ConnectedThresholdOutput} produced by the
+  //  ConnectedThresholdImageFilter. You may want to play with the
+  //  value of the neighborhood radius and see how it affect the smoothness of
+  //  the segmented object borders, the size of the segmented region and how
+  //  much that costs in computing time. 
+  //
+  //  Software Guide : EndLatex 
+
+  return 0;
+}
+
+
+
+
diff --git a/Examples/Segmentation/OtsuMultipleThresholdImageFilter.cxx b/Examples/Segmentation/OtsuMultipleThresholdImageFilter.cxx
new file mode 100755
index 0000000000..c347ea383c
--- /dev/null
+++ b/Examples/Segmentation/OtsuMultipleThresholdImageFilter.cxx
@@ -0,0 +1,195 @@
+
+#if defined(_MSC_VER)
+#pragma warning ( disable : 4786 )
+#endif
+
+#ifdef __BORLANDC__
+#define ITK_LEAN_AND_MEAN
+#endif
+
+//  Software Guide : BeginCommandLineArgs
+//    INPUTS: {QB_Suburb.png}
+//    OUTPUTS: {OtsuMultipleThresholdsOutput000.png},{OtsuMultipleThresholdsOutput001.png},  {OtsuMultipleThresholdsOutput002.png}
+//  Software Guide : EndCommandLineArgs
+
+// Software Guide : BeginLatex
+// This example illustrates how to use the \doxygen{itk::OtsuMultipleThresholdsCalculator}.
+// Software Guide : EndLatex 
+
+// Software Guide : BeginCodeSnippet
+#include "itkOtsuMultipleThresholdsCalculator.h"
+// Software Guide : EndCodeSnippet
+
+#include "otbImage.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+#include "itkScalarImageToHistogramGenerator.h"
+#include "itkBinaryThresholdImageFilter.h"
+#include "itkNumericTraits.h"
+
+#include <stdio.h>
+int main( int argc, char * argv[] )
+{
+  if( argc < 2 )
+    {
+    std::cerr << "Usage: " << argv[0];
+    std::cerr << " inputImageFile outputImageFileName1 [OutputImageFilename2 ...] ";  
+    return EXIT_FAILURE;
+    }
+  
+  //Convenience typedefs
+  typedef  unsigned char  InputPixelType;
+  typedef  unsigned char  OutputPixelType;
+  
+  typedef otb::Image< InputPixelType,  2 >   InputImageType;
+  typedef otb::Image< OutputPixelType, 2 >   OutputImageType;
+  
+  // Software Guide : BeginLatex
+  // OtsuMultipleThresholdsCalculator calculates thresholds for a give histogram
+  // so as to maximize the between-class variance. We use 
+  // ScalarImageToHistogramGenerator to generate histograms 
+  // Software Guide : EndLatex
+
+  // Software Guide : BeginCodeSnippet
+  typedef itk::Statistics::ScalarImageToHistogramGenerator< InputImageType > 
+    ScalarImageToHistogramGeneratorType;
+  typedef itk::OtsuMultipleThresholdsCalculator< 
+    ScalarImageToHistogramGeneratorType::HistogramType >   CalculatorType;
+  // Software Guide : EndCodeSnippet
+
+  typedef otb::ImageFileReader< InputImageType >  ReaderType;
+  typedef otb::ImageFileWriter< InputImageType >  WriterType;
+
+  // Software Guide : BeginLatex
+  // Once thresholds are computed we will use BinaryThresholdImageFilter to 
+  // segment the input image into segments.
+  // Software Guide : EndLatex
+
+  // Software Guide : BeginCodeSnippet
+  typedef itk::BinaryThresholdImageFilter< InputImageType, OutputImageType >  
+    FilterType;
+  // Software Guide : EndCodeSnippet
+  
+  //Create using static New() method
+
+  // Software Guide : BeginCodeSnippet
+  ScalarImageToHistogramGeneratorType::Pointer scalarImageToHistogramGenerator = 
+    ScalarImageToHistogramGeneratorType::New();
+  CalculatorType::Pointer calculator = CalculatorType::New();
+  FilterType::Pointer filter = FilterType::New();
+  // Software Guide : EndCodeSnippet
+
+  ReaderType::Pointer reader = ReaderType::New();
+  WriterType::Pointer writer = WriterType::New();
+  
+  //Set Properties
+
+  // Software Guide : BeginCodeSnippet
+  scalarImageToHistogramGenerator->SetNumberOfBins(128);
+  int nbThresholds = argc-2;
+  calculator->SetNumberOfThresholds( nbThresholds );
+  // Software Guide : EndCodeSnippet
+
+  const OutputPixelType outsideValue = 0;
+  const OutputPixelType insideValue = 255;
+  filter->SetOutsideValue( outsideValue );
+  filter->SetInsideValue(  insideValue  );
+
+  //Connect Pipeline
+  reader->SetFileName( argv[1] );
+
+  // Software Guide : BeginLatex
+  // The pipeline will look as follows:
+  // Software Guide : EndLatex
+  // Software Guide : BeginCodeSnippet
+  scalarImageToHistogramGenerator->SetInput(reader->GetOutput());
+  calculator->SetInputHistogram(scalarImageToHistogramGenerator->GetOutput());
+  filter->SetInput( reader->GetOutput() );
+  writer->SetInput(filter->GetOutput());
+  // Software Guide : EndCodeSnippet
+  
+  
+  //Invoke pipeline
+  try
+    { reader->Update();  }
+  catch( itk::ExceptionObject & excp )
+    {
+    std::cerr << "Exception thrown while reading image" << excp << std::endl;
+    }
+  scalarImageToHistogramGenerator->Compute();
+  
+  try
+    { calculator->Update();  }
+  catch( itk::ExceptionObject & excp )
+    {
+    std::cerr << "Exception thrown " << excp << std::endl;
+    }
+
+  // Software Guide : BeginLatex
+  // Thresholds are obtained using the \code{GetOutput} method
+  // \index{itk::OtsuMultipleThresholdsCalculator!GetOutput()}
+  // Software Guide : EndLatex
+  //Get Thresholds
+  // Software Guide : BeginCodeSnippet
+  const CalculatorType::OutputType &thresholdVector = calculator->GetOutput(); 
+  CalculatorType::OutputType::const_iterator itNum = thresholdVector.begin();
+  // Software Guide : EndCodeSnippet
+
+  //Threshold into seperate segments and write out as binary images
+  double lowerThreshold = 0;
+  double upperThreshold;
+
+  unsigned int counter = 0;
+  // Software Guide : BeginCodeSnippet
+  for(; itNum < thresholdVector.end(); itNum++) 
+    {
+    std::cout << "OtsuThreshold["
+      << (int)(itNum - thresholdVector.begin())
+      << "] = " << 
+      static_cast<itk::NumericTraits<CalculatorType::MeasurementType>::PrintType>
+      (*itNum) << std::endl;  
+  // Software Guide : EndCodeSnippet
+    
+    upperThreshold = (*itNum);
+    filter->SetLowerThreshold( static_cast<OutputPixelType> (lowerThreshold) );
+    filter->SetUpperThreshold( static_cast<OutputPixelType> (upperThreshold) );
+    lowerThreshold = upperThreshold;
+    
+
+    writer->SetFileName( argv[2+counter] );
+    ++counter;
+    try
+      { writer->Update(); }
+    catch( itk::ExceptionObject & excp )
+      {
+      std::cerr << "Exception thrown " << excp << std::endl;
+      }
+  // Software Guide : BeginCodeSnippet
+    }
+  // Software Guide : EndCodeSnippet
+
+    //  Software Guide : BeginLatex
+  //  
+  // \begin{figure}
+  // \center
+  // \includegraphics[width=0.44\textwidth]{QB_Suburb.eps}
+  // \includegraphics[width=0.44\textwidth]{OtsuMultipleThresholdsOutput000.eps}
+  // \includegraphics[width=0.44\textwidth]{OtsuMultipleThresholdsOutput001.eps}
+  // \includegraphics[width=0.44\textwidth]{OtsuMultipleThresholdsOutput002.eps}
+  // \itkcaption[OtsuThresholdImageFilter output]{Effect of the OtsuMultipleThresholdImageFilter.}
+  // \label{fig:OtsuMultipleThresholdImageFilterInputOutput}
+  // \end{figure}
+  //
+  //  Figure \ref{fig:OtsuMultipleThresholdImageFilterInputOutput} illustrates the
+  //  effect of this filter. 
+  //
+  //  \relatedClasses
+  //  \begin{itemize}
+  //  \item \doxygen{itk::ThresholdImageFilter}
+  //  \end{itemize}
+  //
+  //  Software Guide : EndLatex 
+
+  return EXIT_SUCCESS;
+}
+
diff --git a/Examples/Segmentation/OtsuThresholdImageFilter.cxx b/Examples/Segmentation/OtsuThresholdImageFilter.cxx
new file mode 100755
index 0000000000..7081963931
--- /dev/null
+++ b/Examples/Segmentation/OtsuThresholdImageFilter.cxx
@@ -0,0 +1,231 @@
+#if defined(_MSC_VER)
+#pragma warning ( disable : 4786 )
+#endif
+
+#ifdef __BORLANDC__
+#define ITK_LEAN_AND_MEAN
+#endif
+
+//  Software Guide : BeginCommandLineArgs
+//    INPUTS: {QB_Suburb.png}
+//    OUTPUTS: {OtsuThresholdImageFilterOutput.png}
+//    255 0
+//  Software Guide : EndCommandLineArgs
+
+// Software Guide : BeginLatex
+//
+// This example illustrates how to use the \doxygen{itk::OtsuThresholdImageFilter}.
+//
+// Software Guide : EndLatex 
+
+// Software Guide : BeginCodeSnippet
+#include "itkOtsuThresholdImageFilter.h"
+// Software Guide : EndCodeSnippet
+
+#include "otbImage.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+
+int main( int argc, char * argv[] )
+{
+  if( argc < 5 )
+    {
+    std::cerr << "Usage: " << argv[0];
+    std::cerr << " inputImageFile outputImageFile ";  
+    std::cerr << " insideValue    outsideValue   "  << std::endl;  
+    return EXIT_FAILURE;
+    }
+  
+  //  Software Guide : BeginLatex
+  //
+  //  The next step is to decide which pixel types to use for the input and output
+  //  images.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  typedef  unsigned char  InputPixelType;
+  typedef  unsigned char  OutputPixelType;
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //
+  //  The input and output image types are now defined using their respective
+  //  pixel types and dimensions.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  typedef itk::Image< InputPixelType,  2 >   InputImageType;
+  typedef itk::Image< OutputPixelType, 2 >   OutputImageType;
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //
+  //  The filter type can be instantiated using the input and output image
+  //  types defined above.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  typedef itk::OtsuThresholdImageFilter<
+               InputImageType, OutputImageType >  FilterType;
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //
+  //  An \doxygen{otb::ImageFileReader} class is also instantiated in order to read
+  //  image data from a file. (See Section \ref{sec:IO} on page 
+  //  \pageref{sec:IO} for more information about reading
+  //  and writing data.) 
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  typedef otb::ImageFileReader< InputImageType >  ReaderType;
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //  
+  // An \doxygen{otb::ImageFileWriter} is instantiated in order to write the output
+  // image to a file.
+  //
+  //  Software Guide : EndLatex 
+
+
+  // Software Guide : BeginCodeSnippet
+  typedef otb::ImageFileWriter< InputImageType >  WriterType;
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //
+  //  Both the filter and the reader are created by invoking their \code{New()}
+  //  methods and assigning the result to \doxygen{SmartPointer}s.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  ReaderType::Pointer reader = ReaderType::New();
+  FilterType::Pointer filter = FilterType::New();
+  // Software Guide : EndCodeSnippet
+
+  WriterType::Pointer writer = WriterType::New();
+  writer->SetInput( filter->GetOutput() );
+  reader->SetFileName( argv[1] );
+
+
+  //  Software Guide : BeginLatex
+  //  
+  //  The image obtained with the reader is passed as input to the
+  //  OtsuThresholdImageFilter.
+  //
+  //  \index{itk::Otsu\-Threshold\-Image\-Filter!SetInput()}
+  //  \index{otb::FileImageReader!GetOutput()}
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  filter->SetInput( reader->GetOutput() );
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //  
+  //  The method \code{SetOutsideValue()} defines the intensity value to be
+  //  assigned to those pixels whose intensities are outside the range defined
+  //  by the lower and upper thresholds. The method \code{SetInsideValue()}
+  //  defines the intensity value to be assigned to pixels with intensities
+  //  falling inside the threshold range.
+  //  
+  //  \index{itk::Otsu\-Threshold\-Image\-Filter!SetOutsideValue()}
+  //  \index{itk::Otsu\-Threshold\-Image\-Filter!SetInsideValue()}
+  //  \index{SetOutsideValue()!itk::Otsu\-Threshold\-Image\-Filter}
+  //  \index{SetInsideValue()!itk::Otsu\-Threshold\-Image\-Filter}
+  //
+  //  Software Guide : EndLatex 
+
+  const OutputPixelType outsideValue = atoi( argv[3] );
+  const OutputPixelType insideValue  = atoi( argv[4] );
+
+  // Software Guide : BeginCodeSnippet
+  filter->SetOutsideValue( outsideValue );
+  filter->SetInsideValue(  insideValue  );
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //  
+  //  The method \code{SetNumberOfHistogramBins()} defines the number of bins
+  //  to be used for computing the histogram. This histogram will be used
+  //  internally in order to compute the Otsu threshold.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  filter->SetNumberOfHistogramBins( 128 );
+  // Software Guide : EndCodeSnippet
+
+
+  //  Software Guide : BeginLatex
+  //  
+  //  The execution of the filter is triggered by invoking the \code{Update()}
+  //  method.   If the filter's output has been passed as input to subsequent
+  //  filters, the \code{Update()} call on any posterior filters in the
+  //  pipeline will indirectly trigger the update of this filter.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  filter->Update();
+  // Software Guide : EndCodeSnippet
+
+
+
+  //  Software Guide : BeginLatex
+  //  
+  //  We print out here the Threshold value that was computed internally by the
+  //  filter. For this we invoke the \code{GetThreshold} method.
+  //
+  //  Software Guide : EndLatex 
+
+  // Software Guide : BeginCodeSnippet
+  int threshold = filter->GetThreshold();
+  std::cout << "Threshold = " << threshold << std::endl;
+  // Software Guide : EndCodeSnippet
+
+
+
+  //  Software Guide : BeginLatex
+  //  
+  // \begin{figure}
+  // \center
+  // \includegraphics[width=0.44\textwidth]{QB_Suburb.eps}
+  // \includegraphics[width=0.44\textwidth]{OtsuThresholdImageFilterOutput.eps}
+  // \itkcaption[OtsuThresholdImageFilter output]{Effect of the OtsuThresholdImageFilter.}
+  // \label{fig:OtsuThresholdImageFilterInputOutput}
+  // \end{figure}
+  //
+  //  Figure \ref{fig:OtsuThresholdImageFilterInputOutput} illustrates the
+  //  effect of this filter. This
+  //  figure shows the limitations of this filter for performing segmentation
+  //  by itself. These limitations are particularly noticeable in noisy images
+  //  and in images lacking spatial uniformity.
+  //
+  //  \relatedClasses
+  //  \begin{itemize}
+  //  \item \doxygen{itk::ThresholdImageFilter}
+  //  \end{itemize}
+  //
+  //  Software Guide : EndLatex 
+
+  writer->SetFileName( argv[2] );
+  writer->Update();
+
+  return EXIT_SUCCESS;
+}
+
-- 
GitLab