otbLSGRM.cxx 8.55 KB
Newer Older
remicres's avatar
remicres committed
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "itkFixedArray.h"
#include "itkObjectFactory.h"

// Elevation handler
#include "otbWrapperElevationParametersHandler.h"
#include "otbWrapperApplicationFactory.h"

// Application engine
#include "otbStandardFilterWatcher.h"
#include "itkFixedArray.h"
#include "itkImageSource.h"

// GRM
14
#include <iostream>
15
16
17
#include "lsgrmBaatzSegmenter.h"
#include "lsgrmSpringSegmenter.h"
#include "lsgrmFullLambdaScheduleSegmenter.h"
18
19
#include "lsgrmController.h"

20
21
22
// system tools
#include <itksys/SystemTools.hxx>

remicres's avatar
remicres committed
23
24
25
26
27
28
29
namespace otb
{

namespace Wrapper
{

class LSGRM : public Application
30
{
remicres's avatar
remicres committed
31
32
public:
  /** Standard class typedefs. */
33
  typedef LSGRM                         Self;
remicres's avatar
remicres committed
34
35
36
37
38
39
40
41
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);
  itkTypeMacro(LSGRM, Application);

42
43
44
45
46
47
48
49
50
  /** Useful typedefs */
  typedef otb::VectorImage<float, 2>                    ImageType;
  typedef lsgrm::BaatzSegmenter<ImageType>              BaatzSegmenterType;
  typedef lsgrm::SpringSegmenter<ImageType>             SpringSegmenterType;
  typedef lsgrm::FullLambdaScheduleSegmenter<ImageType> FLSSegmenterType;
  typedef lsgrm::Controller<BaatzSegmenterType>         BaatzControllerType;
  typedef lsgrm::Controller<SpringSegmenterType>        SpringControllerType;
  typedef lsgrm::Controller<FLSSegmenterType>           FLSControllerType;

remicres's avatar
remicres committed
51
52
private:

53
54
55
56
57
58
59
60
  /* Tiling mode choice */
  enum TilingMode
  {
    TILING_AUTO,
    TILING_USER,
    TILING_NONE
  };

61
62
63
64
65
66
67
68
  /* Criterion choice */
  enum Criterion
  {
    CRITERION_BAATZ,
    CRITERION_SPRING,
    CRITERION_FLS
  };

remicres's avatar
remicres committed
69
70
  void DoInit()
  {
71
72
73
74
75
    SetName("GenericRegionMerging");
    SetDescription("This application allows to use the Generic Region Merging library "
        "(GRM) and provides currently 3 homogeneity criteria: Euclidean Distance, "
        "Full Lambda Schedule and Baatz & Schape criterion.");

76
    // Input and Output images
77
78
79
80
    AddParameter(ParameterType_InputImage, "in", "Input Image");
    AddParameter(ParameterType_OutputImage, "out", "Ouput Label Image");
    SetDefaultOutputPixelType("out", ImagePixelType_uint32);

81
82
83
84
85
    // Criterion choice
    AddParameter(ParameterType_Choice, "criterion", "Homogeneity criterion to use");
    AddChoice("criterion.bs", "Baatz & Schape");
    AddChoice("criterion.ed", "Euclidean Distance");
    AddChoice("criterion.fls", "Full Lambda Schedule");
86

87
    // Generic parameters
88
89
90
91
92
    AddParameter(ParameterType_Float, "threshold", "Threshold for the criterion");
    AddParameter(ParameterType_Int, "niter", "Maximum number of iterations");
    SetDefaultParameterInt("niter", 75);
    MandatoryOff("niter");

93
94
95
96
97
98
99
    // Specific parameters for Baatz & Schape
    AddParameter(ParameterType_Float, "criterion.bs.cw", "Weight for the spectral homogeneity");
    SetDefaultParameterFloat("criterion.bs.cw", 0.5);
    MandatoryOff("criterion.bs.cw");
    AddParameter(ParameterType_Float, "criterion.bs.sw", "Weight for the spatial homogeneity");
    SetDefaultParameterFloat("criterion.bs.sw", 0.5);
    MandatoryOff("criterion.bs.sw");
100
101

    // For large scale
102
    AddParameter(ParameterType_Directory, "tmpdir", "Directory for temporary files");
103
104
105
106
107
108
109
110
    AddParameter(ParameterType_Choice, "tiling", "Tiling layout for the large scale segmentation");
    AddChoice("tiling.auto", "Automatic tiling layout");
    AddChoice("tiling.user", "User tiling layout");
    AddParameter(ParameterType_Int, "tiling.user.sizex", "Tiles width");
    AddParameter(ParameterType_Int, "tiling.user.sizey", "Tiles height");
    AddParameter(ParameterType_Int, "tiling.user.nfirstiter", "Number of first iterations");
    AddParameter(ParameterType_Int, "tiling.user.memory", "Available memory");
    AddChoice("tiling.none", "No tiling layout");
remicres's avatar
remicres committed
111
112
113
114
115
116
  }

  void DoUpdateParameters()
  {
  }

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
  /*
   * Return a prefix for temporary files
   */
  std::string GetTemporaryFilesPrefix()
  {

    // Get output filename (without extension)
    std::string outfname = GetParameterString("out");
    std::string outbfname = itksys::SystemTools::GetFilenameWithoutExtension(outfname.c_str());

    // Get specified temporary directory
    std::string tmpdir = GetParameterAsString("tmpdir");
    if (!tmpdir.empty())
      {
      // A temporary directory is specified: we check that it ends with a POSIX separator
      if (tmpdir[tmpdir.size()-1] != '/')
        {
        // If not, we add the separator
        tmpdir.append("/");
        }
      }
    std::string prefix = tmpdir + outbfname;
    return prefix;
  }

143
144
145
146
147
  /*
   * This function sets the generic parameters of a controller and runs the segmentation
   */
  template<class TController>
  UInt32ImageType::Pointer SetGenericParametersAndRunSegmentation(typename TController::Pointer& controller)
remicres's avatar
remicres committed
148
  {
149
150
    // Set input image
    controller->SetInputImage(GetParameterFloatVectorImage("in"));
remicres's avatar
remicres committed
151

152
153
154
    // Set threshold
    float thres = GetParameterFloat("threshold");
    controller->SetThreshold(thres*thres);
remicres's avatar
remicres committed
155

156
157
    // Set number of iterations
    controller->SetNumberOfIterations(GetParameterInt("niter"));
remicres's avatar
remicres committed
158

159
160
    // Set temporary files prefix
    controller->SetTemporaryFilesPrefix(this->GetTemporaryFilesPrefix());
remicres's avatar
remicres committed
161

162
    // Switch tiling mode
163
164
    int inputTilingMode = GetParameterInt("tiling");
    if (inputTilingMode == TILING_AUTO)
remicres's avatar
remicres committed
165
      {
166
167
      // Automatic mode
      controller->SetTilingModeAuto();
remicres's avatar
remicres committed
168
      }
169
    else if (inputTilingMode == TILING_USER)
remicres's avatar
remicres committed
170
      {
171
172
173
174
175
176
      // User mode
      controller->SetTilingModeUser();
      controller->SetTileWidth(GetParameterInt("tiling.user.sizex"));
      controller->SetTileHeight(GetParameterInt("tiling.user.sizey"));
      controller->SetNumberOfFirstIterations(GetParameterInt("tiling.user.nfirstiter"));
      controller->SetInternalMemoryAvailable(GetParameterInt("tiling.user.memory"));
remicres's avatar
remicres committed
177
      }
178
179
    else if (inputTilingMode == TILING_NONE)
      {
180
181
      // None mode
      controller->SetTilingModeNone();
182
183
184
      }
    else
      {
185
      otbAppLogFATAL("Unknow tiling mode!");
186
      }
remicres's avatar
remicres committed
187

remicres's avatar
remicres committed
188
    // Run the segmentation
189
    controller->RunSegmentation();
remicres's avatar
remicres committed
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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
    // Get temporary files list
    m_TemporaryFilesList = controller->GetTemporaryFilesList();

    // Return the label image
    return controller->GetLabeledClusteredOutput();
  }



  void DoExecute()
  {
    /*
        To add:
        the output directory in case the global graph cannot fit in memory
     */

    // Input image
    ImageType::Pointer inputImage = GetParameterFloatVectorImage("in");

    // Output image
    UInt32ImageType::Pointer labelImage = UInt32ImageType::New();

    // Switch criterion
    int inputCriterion = GetParameterInt("criterion");
    if (inputCriterion == CRITERION_BAATZ)
      {
      // Baatz controller
      BaatzControllerType::Pointer baatzController = BaatzControllerType::New();

      // Specific parameters
      grm::BaatzParam params;
      params.m_SpectralWeight = GetParameterFloat("criterion.bs.cw");
      params.m_ShapeWeight = GetParameterFloat("criterion.bs.sw");
      baatzController->SetSpecificParameters(params);

      // Run segmentation
      labelImage = SetGenericParametersAndRunSegmentation<BaatzControllerType>(baatzController);
      }
    else if (inputCriterion == CRITERION_SPRING)
      {
      // Spring controller
      SpringControllerType::Pointer springController = SpringControllerType::New();

      // Run segmentation
      labelImage = SetGenericParametersAndRunSegmentation<SpringControllerType>(springController);
      }
    else if (inputCriterion == CRITERION_FLS)
      {
      // Full Lambda Schedule (FLS) controller
      FLSControllerType::Pointer flsController = FLSControllerType::New();

      // Run segmentation
      labelImage = SetGenericParametersAndRunSegmentation<FLSControllerType>(flsController);
      }
    else
      {
      otbAppLogFATAL("Unknow criterion!")
      }
remicres's avatar
remicres committed
249
250
251
252
253
254
255

    // Set output image projection, origin and spacing for labelImage
    labelImage->SetProjectionRef(inputImage->GetProjectionRef());
    labelImage->SetOrigin(inputImage->GetOrigin());
    labelImage->SetSpacing(inputImage->GetSpacing());
    SetParameterOutputImage<UInt32ImageType>("out", labelImage);

256

remicres's avatar
remicres committed
257
258
259
260
  }

  void AfterExecuteAndWriteOutputs()
  {
261
262
263
264
265
266
267
268
    // Delete temporary files
    for (unsigned int i = 0 ; i < m_TemporaryFilesList.size() ; i++)
      {
      if( remove(m_TemporaryFilesList.at(i).c_str() ) != 0  )
        {
        otbAppLogWARNING( "Error deleting file " << m_TemporaryFilesList.at(i) );
        }
      }
remicres's avatar
remicres committed
269
270
  }

271
272
273
private:
  std::vector<std::string> m_TemporaryFilesList;

remicres's avatar
remicres committed
274
275
276
277
278
279
}; // app class
} // end of namespace wrapper
} // end of namespace otb


OTB_APPLICATION_EXPORT(otb::Wrapper::LSGRM)
280