ShapeAttributeComputation.cxx 5.12 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
//    INPUTS: {qb_RoadExtract2.tif}
21 22 23 24 25
//    OUTPUTS: {OBIAShapeAttribute.txt}
//  Software Guide : EndCommandLineArgs

//  Software Guide : BeginLatex
//
Manuel Grizonnet's avatar
Manuel Grizonnet committed
26
//  This basic example shows how compute shape attributes at the object level.
Jordi Inglada's avatar
Jordi Inglada committed
27 28 29
//  The input image is firstly converted into a set of regions (
// \doxygen{itk}{ShapeLabelObject}), some attribute values of each
//  object are computed and then saved to an ASCII file. 
30 31 32 33 34 35 36 37 38 39 40
//
//  Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkShapeLabelObject.h"
#include "itkLabelMap.h"
#include "itkLabelImageToLabelMapFilter.h"
#include "itkShapeLabelMapFilter.h"

// Software Guide : EndCodeSnippet
#include "otbImageFileReader.h"
41
#include <fstream>
42 43 44

int main(int argc, char * argv[])
{
Manuel Grizonnet's avatar
Manuel Grizonnet committed
45
  
46 47 48
  
  if( argc != 3)
    {
49 50
    std::cerr << "usage: " << argv[0] << " input outputcentroidlist" << std::endl;
    return EXIT_FAILURE;
51 52
    }

Manuel Grizonnet's avatar
Manuel Grizonnet committed
53 54 55
  //  Software Guide : BeginLatex
  //
  // The image types are defined using pixel types and
Jordi Inglada's avatar
Jordi Inglada committed
56
  // dimensions. The input image is defined as an \doxygen{otb}{Image}.
Manuel Grizonnet's avatar
Manuel Grizonnet committed
57 58 59 60
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
61 62 63
  const int dim = 2;
  typedef unsigned long                           PixelType;
  typedef itk::Image< PixelType, dim >            ImageType;
Manuel Grizonnet's avatar
Manuel Grizonnet committed
64 65 66
  typedef unsigned long                           LabelType;
  typedef itk::ShapeLabelObject< LabelType, dim > LabelObjectType;
  typedef itk::LabelMap< LabelObjectType >        LabelMapType;
67 68
  typedef itk::LabelImageToLabelMapFilter
                      < ImageType, LabelMapType > ConverterType;
Manuel Grizonnet's avatar
Manuel Grizonnet committed
69 70 71 72 73 74 75 76 77 78
  
  // Software Guide : EndCodeSnippet
  
  //  Software Guide : BeginLatex
  //
  // Firstly, the image reader is instantiated.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
79 80 81
  typedef itk::ImageFileReader< ImageType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );
Manuel Grizonnet's avatar
Manuel Grizonnet committed
82 83
  // Software Guide : EndCodeSnippet

84
  
Manuel Grizonnet's avatar
Manuel Grizonnet committed
85 86
  //  Software Guide : BeginLatex
  //
Manuel Grizonnet's avatar
Manuel Grizonnet committed
87
  // Here the \doxygen{itk}{ShapeLabelObject} type
Jordi Inglada's avatar
Jordi Inglada committed
88 89
  // is chosen in order to read some attributes related to the shape
  // of the objects, by opposition to the content of the object, with
90
  // the \doxygen{itk}{StatisticsLabelObject}.
Manuel Grizonnet's avatar
Manuel Grizonnet committed
91 92
  //
  // Software Guide : EndLatex
93

Manuel Grizonnet's avatar
Manuel Grizonnet committed
94 95 96 97 98 99 100 101 102 103 104 105
  // Software Guide : BeginCodeSnippet
  typedef itk::ShapeLabelMapFilter< LabelMapType > ShapeFilterType;
  // Software Guide : EndCodeSnippet
  
  
  //  Software Guide : BeginLatex
  //
  // The input image is converted in a collection of objects
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
106 107
  ConverterType::Pointer converter = ConverterType::New();
  converter->SetInput( reader->GetOutput() );
Manuel Grizonnet's avatar
Manuel Grizonnet committed
108
  converter->SetBackgroundValue( itk::NumericTraits<LabelType>::min() );
109 110 111 112

  ShapeFilterType::Pointer shape = ShapeFilterType::New();

  shape->SetInput( converter->GetOutput() );
Manuel Grizonnet's avatar
Manuel Grizonnet committed
113 114 115 116 117 118 119 120 121 122
  // Software Guide : EndCodeSnippet

  
  //  Software Guide : BeginLatex
  //
  // Update the shape filter, so its output will be up to date.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
123
  shape->Update();
Manuel Grizonnet's avatar
Manuel Grizonnet committed
124
  // Software Guide : EndCodeSnippet
125 126 127

  std::cout << "Nb. objects conv. " << converter->GetOutput()->GetNumberOfLabelObjects() << std::endl;

Manuel Grizonnet's avatar
Manuel Grizonnet committed
128 129 130 131
  std::cout << "Nb. objects shape " << shape->GetOutput()->GetNumberOfLabelObjects() << std::endl;

  //  Software Guide : BeginLatex
  //
132
  // Then, we can read the attribute values we're interested in. The \doxygen{itk}{BinaryImageToShapeLabelMapFilter}
Jordi Inglada's avatar
Jordi Inglada committed
133 134 135
  // produces consecutive labels, so we can use a for loop and \code{GetLabelObject()} method to retrieve
  // the label objects. If the labels are not consecutive, the \code{GetNthLabelObject()} method must be
  // use instead of \code{GetLabelObject()}, or an iterator on the label
136
  // object container of the label map.
Jordi Inglada's avatar
Jordi Inglada committed
137
  // In this example, we write 2 shape attributes of each object to a text file (the size and the centroid coordinates).
Manuel Grizonnet's avatar
Manuel Grizonnet committed
138 139 140 141 142
  //
  // Software Guide : EndLatex
  
  // Software Guide : BeginCodeSnippet
  std::ofstream outfile( argv[2] );
143

144 145 146 147 148 149
  LabelMapType::Pointer labelMap = shape->GetOutput();
  for( unsigned long label=1; label<=labelMap->GetNumberOfLabelObjects(); label++ )
    {
    // we don't need a SmartPointer of the label object here, because the reference is kept in
    // in the label map.
    const LabelObjectType * labelObject = labelMap->GetLabelObject( label );
150
    outfile << label << "\t" << labelObject->GetPhysicalSize() << "\t" << labelObject->GetCentroid() << std::endl;
151
    }
152 153

  outfile.close();
Manuel Grizonnet's avatar
Manuel Grizonnet committed
154 155
  // Software Guide : EndCodeSnippet

156
  return EXIT_SUCCESS;
157
}