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

  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.

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

//  Software Guide : BeginCommandLineArgs
Manuel Grizonnet's avatar
Manuel Grizonnet committed
20 21 22
//    INPUTS: {/home/grizonnetm/OTB/Dev/OTB-Data/Examples/qb_RoadExtract2.tif}
//    OUTPUTS: {OBIARadiometricAttribute1.tif}
//    STATS::Ndvi::Mean 0 0.3 16 16 200 1.0
23 24 25 26
//  Software Guide : EndCommandLineArgs

//  Software Guide : BeginLatex
//
Manuel Grizonnet's avatar
Manuel Grizonnet committed
27
//  This example shows the basic approach to perform object based analysis on a image.
Manuel Grizonnet's avatar
Manuel Grizonnet committed
28 29
//  The input image is firstly segmented using the \doxygen{otb}{MeanShiftImageFilter}
//  Then each segmented region is converted to a Map of labeled objects.
Manuel Grizonnet's avatar
Manuel Grizonnet committed
30
//  After the \doxygen{otb}{RadiometricAttributesLabelMapFilter}  computes 
Manuel Grizonnet's avatar
Manuel Grizonnet committed
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
//  radiometric attributes for each object.
//  Images are supposed to be standard 4-bands image (B,G,R,NIR). The
//  index of each channel can be set via the Set***ChannelIndex()
//  accessors.
//  
//  This filter internally applies the
//  StatisticsAttributesLabelMapFilter to the following features: 
  //  \begin{itemize}
  //  \item GEMI
  //  \item NDVI
  //  \item IR
  //  \item IC
  //  \item IB
  //  \item NDWI2
  //  \item Intensity
  //  \item and original B, G, R and NIR channels
  //  \end{itemize},
Manuel Grizonnet's avatar
Manuel Grizonnet committed
48
//  Here we use the  \doxygen{otb}{AttributesMapOpeningLabelMapFilter} to extract vegetated areas.
Manuel Grizonnet's avatar
Manuel Grizonnet committed
49
//   
50 51 52
//
//  Software Guide : EndLatex

Manuel Grizonnet's avatar
Manuel Grizonnet committed
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"

#include "otbMeanShiftImageFilter.h"
#include "itkLabelImageToLabelMapFilter.h"
#include "otbAttributesMapLabelObject.h"
#include "itkLabelMap.h"
#include "otbShapeAttributesLabelMapFilter.h"
#include "otbStatisticsAttributesLabelMapFilter.h"
#include "otbRadiometricAttributesLabelMapFilter.h"
#include "otbAttributesMapOpeningLabelMapFilter.h"
#include "itkLabelMapToLabelImageFilter.h"

int main(int argc, char * argv[])
{
  if(argc != 10)
    {
      std::cerr<<"Usage: "<<argv[0]<<" reffname outfname attribute_name lowerThan tresh spatialRadius rangeRadius minregionsize scale"<<std::endl;
      return EXIT_FAILURE;
    }

  const char * reffname = argv[1];
  const char * outfname = argv[2];
  const char * attr     = argv[3];
  bool  lowerThan       = atoi(argv[4]);
  double thresh         = atof(argv[5]);
  
  const unsigned int spatialRadius          = atoi(argv[6]);
  const double       rangeRadius            = atof(argv[7]);
  const unsigned int minRegionSize          = atoi(argv[8]);
  const double       scale                  = atoi(argv[9]);

  const unsigned int Dimension = 2;

  // Labeled image type
  typedef unsigned short                                                 LabelType;
  typedef double                                                         PixelType;
  typedef otb::Image<LabelType,Dimension>                                LabeledImageType;
  typedef otb::Image<PixelType,Dimension>                                ImageType;
  typedef otb::VectorImage<PixelType,Dimension>                          VectorImageType;
  typedef otb::ImageFileReader<LabeledImageType>                         LabeledReaderType;
  typedef otb::ImageFileReader<ImageType>                                ReaderType;
  typedef otb::ImageFileReader<VectorImageType>                          VectorReaderType;
  typedef otb::ImageFileWriter<LabeledImageType>                         WriterType;
  // Label map typedef 
  typedef otb::AttributesMapLabelObject<LabelType,Dimension,double>      LabelObjectType;
  typedef itk::LabelMap<LabelObjectType>                                 LabelMapType;
  typedef itk::LabelImageToLabelMapFilter<LabeledImageType,LabelMapType> LabelMapFilterType;
  typedef otb::ShapeAttributesLabelMapFilter<LabelMapType>               ShapeLabelMapFilterType;
  typedef otb::StatisticsAttributesLabelMapFilter<LabelMapType,ImageType> StatisticsLabelMapFilterType;
  typedef otb::RadiometricAttributesLabelMapFilter<LabelMapType,VectorImageType> RadiometricLabelMapFilterType;
  typedef otb::AttributesMapOpeningLabelMapFilter<LabelMapType>          OpeningLabelMapFilterType;
  typedef itk::LabelMapToLabelImageFilter<LabelMapType,LabeledImageType> LabelMapToLabeledImageFilterType;


  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(reffname);
Manuel Grizonnet's avatar
Manuel Grizonnet committed
113

114 115
  VectorReaderType::Pointer vreader = VectorReaderType::New();
  vreader->SetFileName(reffname);
Manuel Grizonnet's avatar
Manuel Grizonnet committed
116 117
    //  Software Guide : BeginLatex
  //
Manuel Grizonnet's avatar
Manuel Grizonnet committed
118
  // Firstly, segment input image using the Mean Shift algorithm.
Manuel Grizonnet's avatar
Manuel Grizonnet committed
119 120
  //
  //  Software Guide : EndLatex
121
  
Manuel Grizonnet's avatar
Manuel Grizonnet committed
122
  // Software Guide : BeginCodeSnippet
123 124 125 126 127 128
  typedef otb::MeanShiftImageFilter<ImageType,ImageType, LabeledImageType> FilterType;
  FilterType::Pointer filter = FilterType::New();
  filter->SetSpatialRadius(spatialRadius);
  filter->SetRangeRadius(rangeRadius);
  filter->SetMinimumRegionSize(minRegionSize);
  filter->SetScale(scale);
Manuel Grizonnet's avatar
Manuel Grizonnet committed
129 130
  // Software Guide : EndCodeSnippet
  
Manuel Grizonnet's avatar
Manuel Grizonnet committed
131 132 133
  //  Software Guide : BeginLatex
  //
  // The \doxygen{otb}{MeanShiftImageFilter} type is instantiated using the images
Manuel Grizonnet's avatar
Manuel Grizonnet committed
134
  // types.
Manuel Grizonnet's avatar
Manuel Grizonnet committed
135 136
  //
  //  Software Guide : EndLatex
Manuel Grizonnet's avatar
Manuel Grizonnet committed
137
// Software Guide : BeginCodeSnippet
138
  filter->SetInput(reader->GetOutput());	
Manuel Grizonnet's avatar
Manuel Grizonnet committed
139
// Software Guide : EndCodeSnippet
Manuel Grizonnet's avatar
Manuel Grizonnet committed
140 141 142 143 144 145 146 147 148 149

//  Software Guide : BeginLatex
  //
  // The \doxygen{itk}{LabelImageToLabelMapFilter} type is instantiated using the output
  // of the \doxygen{otb}{MeanShiftImageFilter}. This filter produces a labeled image 
  // where each segmented region have a unique label.
  //
  //  Software Guide : EndLatex
  
  // Software Guide : BeginCodeSnippet
150 151
  LabelMapFilterType::Pointer labelMapFilter = LabelMapFilterType::New();
  labelMapFilter->SetInput(filter->GetLabeledClusteredOutput());
Manuel Grizonnet's avatar
Manuel Grizonnet committed
152
  labelMapFilter->SetBackgroundValue(itk::NumericTraits<LabelType>::min());
Manuel Grizonnet's avatar
Manuel Grizonnet committed
153
  // Software Guide : EndCodeSnippet
154 155 156 157 158 159 160 161 162
  
  ShapeLabelMapFilterType::Pointer shapeLabelMapFilter = ShapeLabelMapFilterType::New();
  shapeLabelMapFilter->SetInput(labelMapFilter->GetOutput());
  
  StatisticsLabelMapFilterType::Pointer statisticsLabelMapFilter = StatisticsLabelMapFilterType::New();
  statisticsLabelMapFilter->SetInput1(shapeLabelMapFilter->GetOutput());
  statisticsLabelMapFilter->SetInput2(reader->GetOutput());
  
  statisticsLabelMapFilter->Update();
Manuel Grizonnet's avatar
Manuel Grizonnet committed
163 164 165 166 167 168
  //  Software Guide : BeginLatex
  //
  // Instantiate the  \doxygen{otb}{RadiometricAttributesLabelMapFilter} to
  // compute radiometric value on each label object.
  //
  //  Software Guide : EndLatex
Manuel Grizonnet's avatar
Manuel Grizonnet committed
169 170
  
  // Software Guide : BeginCodeSnippet
171 172 173
  RadiometricLabelMapFilterType::Pointer radiometricLabelMapFilter = RadiometricLabelMapFilterType::New();
  radiometricLabelMapFilter->SetInput1(statisticsLabelMapFilter->GetOutput());
  radiometricLabelMapFilter->SetInput2(vreader->GetOutput());
Manuel Grizonnet's avatar
Manuel Grizonnet committed
174 175
  // Software Guide : EndCodeSnippet

Manuel Grizonnet's avatar
Manuel Grizonnet committed
176 177
  //  Software Guide : BeginLatex
  // 
Manuel Grizonnet's avatar
Manuel Grizonnet committed
178 179 180 181
  // Then, we specify the red and the near infrared channels 
  // By default, images are supposed to be standard 4-bands 
  // image (B,G,R,NIR). The index of each channel can 
  // be set via the Set***ChannelIndex() accessors.
Manuel Grizonnet's avatar
Manuel Grizonnet committed
182 183
  //
  //  Software Guide : EndLatex
Manuel Grizonnet's avatar
Manuel Grizonnet committed
184 185

  // Software Guide : BeginCodeSnippet
Manuel Grizonnet's avatar
Manuel Grizonnet committed
186 187
  radiometricLabelMapFilter->SetRedChannelIndex(2);
  radiometricLabelMapFilter->SetNIRChannelIndex(3);
188
  radiometricLabelMapFilter->Update();
Manuel Grizonnet's avatar
Manuel Grizonnet committed
189
  // Software Guide : EndCodeSnippet
190

Manuel Grizonnet's avatar
Manuel Grizonnet committed
191 192
  //  Software Guide : BeginLatex
  // 
Manuel Grizonnet's avatar
Manuel Grizonnet committed
193
  // The \doxygen{otb}{AttributesMapOpeningLabelMapFilter} will proceed the selection. 
Manuel Grizonnet's avatar
Manuel Grizonnet committed
194 195 196 197 198
  // There are three parameters. \code{AttributeName} specifies the radiometric attribute, \code{Lambda} 
  // controls the thresholding of the input and \code{ReverseOrdering} make this filter to remove the 
  // object with an attribute value greater than \code{Lambda} instead.   
  // 
  //  Software Guide : EndLatex
Manuel Grizonnet's avatar
Manuel Grizonnet committed
199 200

  // Software Guide : BeginCodeSnippet
201 202 203 204
  OpeningLabelMapFilterType::Pointer opening = OpeningLabelMapFilterType::New();
  opening->SetInput(radiometricLabelMapFilter->GetOutput());
  opening->SetAttributeName(attr);
  opening->SetLambda(thresh);
Manuel Grizonnet's avatar
Manuel Grizonnet committed
205
  opening->SetReverseOrdering(lowerThan);
Manuel Grizonnet's avatar
Manuel Grizonnet committed
206 207 208
  // Software Guide : EndCodeSnippet


Manuel Grizonnet's avatar
Manuel Grizonnet committed
209 210 211 212 213
  //  Software Guide : BeginLatex
  // 
  //  Then, Label object selected are transform in a Label Image using the \doxygen{itk}{LabelMapToLabelImageFilter}  
  // 
  //  Software Guide : EndLatex
Manuel Grizonnet's avatar
Manuel Grizonnet committed
214 215

  // Software Guide : BeginCodeSnippet
216 217
  LabelMapToLabeledImageFilterType::Pointer labelMap2LabeledImage = LabelMapToLabeledImageFilterType::New();
  labelMap2LabeledImage->SetInput(opening->GetOutput());
Manuel Grizonnet's avatar
Manuel Grizonnet committed
218 219
  // Software Guide : EndCodeSnippet

220

Manuel Grizonnet's avatar
Manuel Grizonnet committed
221 222 223 224 225 226 227 228
  // Software Guide : BeginLatex
  //
  // And finally, we declare the writer and call its \code{Update()} method to
  // trigger the full pipeline execution.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
229 230 231 232
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName(outfname);
  writer->SetInput(labelMap2LabeledImage->GetOutput());
  writer->Update();
Manuel Grizonnet's avatar
Manuel Grizonnet committed
233
  // Software Guide : EndCodeSnippet
Manuel Grizonnet's avatar
Manuel Grizonnet committed
234

235 236
  return EXIT_SUCCESS;
}