MultivariateAlterationDetector.cxx 8.41 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$


  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.


     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "otbVectorImage.h"
#include "otbImageFileReader.h"
21
#include "otbImageFileWriter.h"
22 23 24 25
#include "otbPrintableImageFilter.h"


//  Software Guide : BeginCommandLineArgs
Julien Michel's avatar
Julien Michel committed
26
//    INPUTS: {Spot5-Gloucester-before.tif}, {Spot5-Gloucester-after.tif}
27
//    OUTPUTS: {MADOutput.tif}, {mad-input1.png}, {mad-input2.png}, {mad-output.png}
Julien Michel's avatar
Julien Michel committed
28
//
29 30
//  Software Guide : EndCommandLineArgs

OTB Bot's avatar
OTB Bot committed
31
//  Software Guide : BeginLatex
Julien Michel's avatar
Julien Michel committed
32
// This example illustrates the class
33 34
// \doxygen{otb}{MultivariateAlterationChangeDetectorImageFilter},
// which implements the Multivariate Alteration Change Detector
35 36
// algorithm \cite{nielsen2007regularized}. This algorihtm allows
// performing change detection from a pair multi-band images, including
37 38 39
// images with different number of bands or modalities. Its output is
// a a multi-band image of change maps, each one being unccorrelated
// with the remaining. The number of bands of the output image is the
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
// minimum number of bands between the two input images.
//
// The algorithm works as follows. It tries to find two linear
// combinations of bands (one for each input images) which maximize
// correlation, and subtract these two linear combinitation, leading
// to the first change map. Then, it looks for a second set of linear
// combinations which are orthogonal to the first ones, a which
// maximize correlation, and use it as the second change map. This
// process is iterated until no more orthogonal linear combinations
// can be found.
//
// This algorithms has numerous advantages, such as radiometry scaling
// and shifting invariance and absence of parameters, but it can not
// be used on a pair of single band images (in this case the output is
// simply the difference between the two images).
//
// We start by including the corresponding header file.
//
//  Software Guide : EndLatex

//  Software Guide : BeginCodeSnippet
#include "otbMultivariateAlterationDetectorImageFilter.h"
//  Software Guide : EndCodeSnippet

int main(int argc, char* argv[])
{

Julien Michel's avatar
Julien Michel committed
67
  if (argc < 6)
68 69 70 71 72 73 74 75 76 77 78
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " inputImageFile1 inputImageFile2 outIn1Pretty outIn2Pretty outPretty"
              << "outputImageFile" << std::endl;
    return -1;
    }

  // Define the dimension of the images
  const unsigned int Dimension = 2;

  //  Software Guide : BeginLatex
79 80
  // We then define the types for the input images and for the
  // change image.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
  //
  //  Software Guide : EndLatex

  //  Software Guide : BeginCodeSnippet
  typedef unsigned short                               InputPixelType;
  typedef float                                        OutputPixelType;
  typedef otb::VectorImage<InputPixelType, Dimension>  InputImageType;
  typedef otb::VectorImage<OutputPixelType, Dimension> OutputImageType;
  //  Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We can now declare the types for the reader. Since the images
  //  can be vey large, we will force the pipeline to use
  //  streaming. For this purpose, the file writer will be
  //  streamed. This is achieved by using the
97
  //  \doxygen{otb}{ImageFileWriter} class.
98 99 100 101 102
  //
  //  Software Guide : EndLatex

  //  Software Guide : BeginCodeSnippet
  typedef otb::ImageFileReader<InputImageType>           ReaderType;
103
  typedef otb::ImageFileWriter<OutputImageType> WriterType;
104 105
  //  Software Guide : EndCodeSnippet

106

107 108 109 110
  // This is for rendering in software guide
  typedef otb::PrintableImageFilter<InputImageType,InputImageType>   InputPrintFilterType;
  typedef otb::PrintableImageFilter<OutputImageType,OutputImageType> OutputPrintFilterType;
  typedef InputPrintFilterType::OutputImageType                      VisuImageType;
111
  typedef otb::ImageFileWriter<VisuImageType>               VisuWriterType;
112

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
  //  The \doxygen{otb}{MultivariateAlterationDetectorImageFilter} is templated over
  //  the type of the input images and the type of the generated change
  //  image.
  //
  //  Software Guide : EndLatex

  //  Software Guide : BeginCodeSnippet
  typedef otb::MultivariateAlterationDetectorImageFilter<
      InputImageType,OutputImageType>                   MADFilterType;
  //  Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The different elements of the pipeline can now be instantiated.
  //
  //  Software Guide : EndLatex

  //  Software Guide : BeginCodeSnippet
  ReaderType::Pointer    reader1 = ReaderType::New();
  ReaderType::Pointer    reader2 = ReaderType::New();
  WriterType::Pointer    writer = WriterType::New();
  MADFilterType::Pointer madFilter = MADFilterType::New();

  //  Software Guide : EndCodeSnippet
  const char * inputFilename1  = argv[1];
  const char * inputFilename2  = argv[2];
  const char * outputFilename  = argv[3];
  const char * in1pretty       = argv[4];
  const char * in2pretty       = argv[5];
  const char * outpretty       = argv[6];
  //  Software Guide : BeginLatex
  //
  //  We set the parameters of the different elements of the pipeline.
  //
  //  Software Guide : EndLatex

  //  Software Guide : BeginCodeSnippet
  reader1->SetFileName(inputFilename1);
  reader2->SetFileName(inputFilename2);
  writer->SetFileName(outputFilename);
  //  Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  We build the pipeline by plugging all the elements together.
  //
  //  Software Guide : EndLatex

  //  Software Guide : BeginCodeSnippet
  madFilter->SetInput1(reader1->GetOutput());
  madFilter->SetInput2(reader2->GetOutput());
  writer->SetInput(madFilter->GetOutput());
  //  Software Guide : EndCodeSnippet

  try
    {
    //  Software Guide : BeginLatex
    //
    //  And then we can trigger the pipeline update, as usual.
    //
    //  Software Guide : EndLatex
174

175 176 177
    //  Software Guide : BeginCodeSnippet
    writer->Update();
    //  Software Guide : EndCodeSnippet
178

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
    }
  catch (itk::ExceptionObject& err)
    {
    std::cout << "ExceptionObject caught !" << std::endl;
    std::cout << err << std::endl;
    return -1;
    }

  // Here we generate the figures
  InputPrintFilterType::Pointer input1PrintFilter = InputPrintFilterType::New();
  InputPrintFilterType::Pointer input2PrintFilter = InputPrintFilterType::New();
  OutputPrintFilterType::Pointer outputPrintFilter = OutputPrintFilterType::New();
  VisuWriterType::Pointer input1VisuWriter = VisuWriterType::New();
  VisuWriterType::Pointer input2VisuWriter = VisuWriterType::New();
  VisuWriterType::Pointer outputVisuWriter = VisuWriterType::New();

  input1PrintFilter->SetInput(reader1->GetOutput());
  input1PrintFilter->SetChannel(3);
  input1PrintFilter->SetChannel(2);
  input1PrintFilter->SetChannel(1);
  input2PrintFilter->SetInput(reader2->GetOutput());
  input2PrintFilter->SetChannel(3);
  input2PrintFilter->SetChannel(2);
  input2PrintFilter->SetChannel(1);
  outputPrintFilter->SetInput(madFilter->GetOutput());
  outputPrintFilter->SetChannel(3);
  outputPrintFilter->SetChannel(2);
  outputPrintFilter->SetChannel(1);

  input1VisuWriter->SetInput(input1PrintFilter->GetOutput());
  input2VisuWriter->SetInput(input2PrintFilter->GetOutput());
  outputVisuWriter->SetInput(outputPrintFilter->GetOutput());

  input1VisuWriter->SetFileName(in1pretty);
  input2VisuWriter->SetFileName(in2pretty);
  outputVisuWriter->SetFileName(outpretty);

  input1VisuWriter->Update();
  input2VisuWriter->Update();
  outputVisuWriter->Update();

OTB Bot's avatar
OTB Bot committed
220
//  Software Guide : BeginLatex
221 222
// Figure \ref{fig:MADCHDET} shows the
// results of Multivariate Alteration Detector applied to a pair of
OTB Bot's avatar
OTB Bot committed
223
// SPOT5 images before and after a flooding event.
224
// \begin{figure}
225 226 227
// \center \includegraphics[width=0.32\textwidth]{mad-input1.eps}
// \includegraphics[width=0.32\textwidth]{mad-input2.eps}
// \includegraphics[width=0.32\textwidth]{mad-output.eps}
228
// \itkcaption[Multivariate Alteration Detection
229 230
// Results]{Result of the Multivariate Alteration Detector results on
// SPOT5 data before and after flooding.}  \label{fig:MADCHDET}
OTB Bot's avatar
OTB Bot committed
231
// \end{figure}
232
// Software Guide : EndLatex
233 234 235 236

  return EXIT_SUCCESS;

}