TextureExample.cxx 8.48 KB
Newer Older
1
/*=========================================================================
Jordi Inglada's avatar
Jordi Inglada committed
2

3 4 5 6
  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
Jordi Inglada's avatar
Jordi Inglada committed
7 8


9 10
  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.
Jordi Inglada's avatar
Jordi Inglada committed
11 12


13 14 15
     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.
Jordi Inglada's avatar
Jordi Inglada committed
16

17 18 19 20
=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
Jordi Inglada's avatar
Jordi Inglada committed
21

22 23 24 25 26
#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginCommandLineArgs
27 28
//    INPUTS: {ADS40RoiSmall.png}
//    OUTPUTS: {TextureOutput.tif}, {pretty_TextureOutput.png}
29 30 31 32 33 34 35 36 37 38 39
//    2 1 1
//  Software Guide : EndCommandLineArgs

#include "itkExceptionObject.h"
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"



40 41 42 43
// Software Guide : BeginLatex
//
// This example illustrates the use of the
// \doxygen{otb}{ContrastTextureFunctor}, and more generally it
Emmanuel Christophe's avatar
Emmanuel Christophe committed
44
// demonstrates how to compute Haralick's textural features.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
// \relatedClasses
//  \begin{itemize}
//  \item \doxygen{otb}{EnergyTextureFunctor}
//  \item \doxygen{otb}{EntropyTextureFunctor}
//  \item \doxygen{otb}{InverseDifferenceMomentTextureFunctor}
//  \item \doxygen{otb}{AngularSecondMomentumTextureFunctor}
//  \item \doxygen{otb}{VarianceTextureFunctor}
//  \item \doxygen{otb}{CorrelationTextureFunctor}
//  \item \doxygen{otb}{SumAverageTextureFunctor}
//  \item \doxygen{otb}{DifferenceEntropyTextureFunctor}
//  \item \doxygen{otb}{SumEntropyTextureFunctor}
//  \item \doxygen{otb}{SumVarianceTextureFunctor}
//  \item \doxygen{otb}{DifferenceVarianceTextureFunctor}
//  \item \doxygen{otb}{InformationMeasureOfCorrelation1TextureFunctor}
//  \item \doxygen{otb}{InformationMeasureOfCorrelation2TextureFunctor}
//  \item \doxygen{otb}{ClusterShadeTextureFunctor}
//  \item \doxygen{otb}{ClusterProminenceTextureFunctor}
//  \item \doxygen{otb}{MeanTextureFunctor}
//  \end{itemize}
//
// The first step required to use this filter is to include its header file.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbContrastTextureFunctor.h"
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Although including the individual header file for a texture functor
// is O.K., OTB provides a single header file which will include all
// other texture functors. Since often we might want to compute
// several texture parameters, it is more efficient to use this single
// header file.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
83
#include "otbTextureFunctors.h"
84 85 86 87 88 89 90 91 92 93 94 95 96
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The texture functors compute a texture feature for a given
// neighborhood. Since we want here to compute the texture features
// for all pixels ofthe image, we will use a filter which will apply
// the functor to every pixel in the image. This filter will take care
// of building the neighborhoods with the needed offsets for texture
// computation.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
97
#include "otbUnaryFunctorNeighborhoodWithOffsetImageFilter.h"
98 99 100 101 102 103 104 105 106 107 108
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Please note that if you want to compute a single scalar texture
// feature for the whole image or for a whole image region, the most
// efficient way to do that is using the
// \doxygen{otb}{TextureImageFunction} class which provides the
// \code{Evaluate} and \code{EvaluateAtIndex} methods for this purpose.
//
// Software Guide : EndLatex

109

Jordi Inglada's avatar
Jordi Inglada committed
110 111 112 113

int main(int argc, char * argv[])
{
  // Parse command line parameters
114
  if ( argc != 7 )
115 116
  {
    std::cerr << "Usage: " << argv[0] << " <inputImage> ";
117
    std::cerr << " <outputImage> <outputRescaled> ";
118 119 120 121 122
    std::cerr << " <radius> <xOffset> <yOffset> ";
    std::cerr << std::endl;
    return EXIT_FAILURE;
  }

Jordi Inglada's avatar
Jordi Inglada committed
123 124
  const char* infname   = argv[1];
  const char* outfname  = argv[2];
125
  const char* outprettyfname  = argv[3];
Jordi Inglada's avatar
Jordi Inglada committed
126

127 128 129
  const unsigned int radius  =  static_cast<unsigned int>(atoi(argv[4]));
  const unsigned int xOffset =  static_cast<unsigned int>(atoi(argv[5]));
  const unsigned int yOffset =  static_cast<unsigned int>(atoi(argv[6]));
Jordi Inglada's avatar
Jordi Inglada committed
130

131

132
  typedef double PixelType;
Jordi Inglada's avatar
Jordi Inglada committed
133
  const int Dimension = 2;
134
  typedef otb::Image<PixelType,Dimension> ImageType;
Jordi Inglada's avatar
Jordi Inglada committed
135

136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
  // Software Guide : BeginLatex
//
// After defining the types for the pixels and the images used in the
// example, we define the type for the texture functor. It is
// templated by the input and output pixel types.
//
// Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::Functor::ContrastTextureFunctor<PixelType, PixelType>
                                                                FunctorType;
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
//
// The filter for computing the texture features for a complete image
// is templated by the input and output image types and, of course,
// the functor type.
//
// Software Guide : EndLatex
155

156
  // Software Guide : BeginCodeSnippet
157 158
  typedef otb::UnaryFunctorNeighborhoodWithOffsetImageFilter<ImageType,
                                          ImageType, FunctorType> FilterType;
159 160

  // Software Guide : EndCodeSnippet
Jordi Inglada's avatar
Jordi Inglada committed
161
  typedef otb::ImageFileReader<ImageType>  ReaderType;
162
  typedef otb::ImageFileWriter<ImageType> WriterType;
163

Jordi Inglada's avatar
Jordi Inglada committed
164 165
  ReaderType::Pointer reader  = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();
166

Jordi Inglada's avatar
Jordi Inglada committed
167 168 169
  reader->SetFileName(infname);
  writer->SetFileName(outfname);

170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
    // Software Guide : BeginLatex
//
// We can now instatiate the filter.
//
// Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  FilterType::Pointer textureFilter = FilterType::New();
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
//
// The texture filter takes 2 parameters: the radius of the
// neighborhood on which the texture will be computed and the offset
// used. Texture features are bivariate statistics, that is, they are
// computed using pair of pixels. Each texture feature is defined for
// an offset defining the pixel pair.
//
// The radius parameter can be passed to the filter as a scalar
// parameter if the neighborhood is square, or as \code{SizeType} in
// any case.
//
// The offset is always an array of N values, where N is the number of
Emmanuel Christophe's avatar
Emmanuel Christophe committed
192
// dimensions of the image.
193 194
//
// Software Guide : EndLatex
Emmanuel Christophe's avatar
Emmanuel Christophe committed
195
  // Software Guide : BeginCodeSnippet
196
  textureFilter->SetRadius(radius);
197 198

  typedef ImageType::OffsetType OffsetType;
Jordi Inglada's avatar
Jordi Inglada committed
199 200 201 202
  OffsetType offset;
  offset[0] =  xOffset;
  offset[1] =  yOffset;

203
  textureFilter->SetOffset(offset);
204 205 206 207 208 209 210 211

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
//
// We can now plug the pipeline and trigger the execution by calling
// the \code{Update} method of the writer.
//
// Software Guide : EndLatex
Emmanuel Christophe's avatar
Emmanuel Christophe committed
212
  // Software Guide : BeginCodeSnippet
213
  textureFilter->SetInput(reader->GetOutput());
214
  writer->SetInput(textureFilter->GetOutput());
Jordi Inglada's avatar
Jordi Inglada committed
215 216

  writer->Update();
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  // Figure~\ref{fig:TEXTUREFUNCTOR} shows the result of applying
  // the contrast texture computation.
  // \begin{figure}
  // \center
  // \includegraphics[width=0.40\textwidth]{ADS40RoiSmall.eps}
  // \includegraphics[width=0.40\textwidth]{pretty_TextureOutput.eps}
  // \itkcaption[Texture Functor]{Result of applying the
  // \doxygen{otb}{ContrastTextureFunctor} to an image. From left to right :
  // original image, contrast.}
  // \label{fig:TEXTUREFUNCTOR}
  // \end{figure}
  //
  //  Software Guide : EndLatex
Jordi Inglada's avatar
Jordi Inglada committed
233

234 235 236 237 238 239 240 241 242 243 244
 // Pretty image creation for printing

  typedef otb::Image<unsigned char, Dimension>                                           OutputPrettyImageType;
  typedef otb::ImageFileWriter<OutputPrettyImageType>                                    WriterPrettyOutputType;
  typedef itk::RescaleIntensityImageFilter< ImageType, OutputPrettyImageType>      RescalerOutputType;

  RescalerOutputType::Pointer     outputRescaler     = RescalerOutputType::New();
  WriterPrettyOutputType::Pointer prettyOutputWriter = WriterPrettyOutputType::New();
  outputRescaler->SetInput( textureFilter->GetOutput() );
  outputRescaler->SetOutputMinimum(0);
  outputRescaler->SetOutputMaximum(255);
Jordi Inglada's avatar
Jordi Inglada committed
245
  prettyOutputWriter->SetFileName( outprettyfname );
246 247 248
  prettyOutputWriter->SetInput( outputRescaler->GetOutput() );

  prettyOutputWriter->Update();
Jordi Inglada's avatar
Jordi Inglada committed
249 250
  return EXIT_SUCCESS;
}