otbKMeansClassification.cxx 5.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Jonathan Guinet's avatar
Jonathan Guinet committed
20

21
#include "otbClassKMeansBase.h"
22

Jonathan Guinet's avatar
Jonathan Guinet committed
23 24 25
namespace otb
{
namespace Wrapper
26 27
{

28
class KMeansClassification: public ClassKMeansBase
Jonathan Guinet's avatar
Jonathan Guinet committed
29 30 31 32
{
public:
  /** Standard class typedefs. */
  typedef KMeansClassification Self;
33
  typedef ClassKMeansBase Superclass;
Jonathan Guinet's avatar
Jonathan Guinet committed
34 35
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;
36

Jonathan Guinet's avatar
Jonathan Guinet committed
37 38
  /** Standard macro */
  itkNewMacro(Self);
39

40
  itkTypeMacro(Self, Superclass);
41

Jonathan Guinet's avatar
Jonathan Guinet committed
42
private:
43
  void DoInit() ITK_OVERRIDE
Jonathan Guinet's avatar
Jonathan Guinet committed
44 45
  {
    SetName("KMeansClassification");
46 47
    SetDescription("Unsupervised KMeans image classification");

48
    SetDocName("Unsupervised KMeans image classification");
49
    SetDocLongDescription("Performs unsupervised KMeans image classification."
50 51 52 53 54 55 56 57
      "KMeansClassification is a composite application, "
      "using an existing training and classification application."
      "The SharkKMeans model is used.\n"
      "The steps of this composite application :\n"
        "1) ImageEnveloppe : create a shapefile (1 polygon),\n"
        "2) PolygonClassStatistics : compute the statistics,\n"
        "3) SampleSelection : select the samples by constant strategy in the shapefile "
            "(1000000 samples max),\n"
58
        "4) SamplesExtraction : extract the samples descriptors (update of SampleSelection output file),\n"
59 60
        "5) ComputeImagesStatistics : compute images second order statistics,\n"
        "6) TrainVectorClassifier : train the SharkKMeans model,\n"
61 62 63 64 65 66
        "7) ImageClassifier : performs the classification of the input image "
            "according to a model file.\n\n"
        "It's possible to choice random/periodic modes of the SampleSelection application.\n"
        "If you want keep the temporary files (sample selected, model file, ...), "
        "initialize cleanup parameter.\n"
        "For more information on shark KMeans algorithm [1].");
67

68 69
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
70 71 72
    SetDocSeeAlso("ImageEnveloppe PolygonClassStatistics SampleSelection SamplesExtraction "
      "PolygonClassStatistics TrainVectorClassifier ImageClassifier\n"
      "[1] http://image.diku.dk/shark/sphinx_pages/build/html/rest_sources/tutorials/algorithms/kmeans.html");
73

74
    AddDocTag(Tags::Learning);
75 76 77 78 79
    AddDocTag(Tags::Segmentation);

    // Perform initialization
    ClearApplications();

80
    // initialisation parameters and synchronizes parameters
81 82 83 84
    initKMParams();

    AddRANDParameter();

85
    // Doc example parameter settings
86
    SetDocExampleParameterValue("in", "QB_1_ortho.tif");
87
    SetDocExampleParameterValue("ts", "1000");
88
    SetDocExampleParameterValue("nc", "5");
89
    SetDocExampleParameterValue("maxit", "1000");
90
    SetDocExampleParameterValue("out", "ClassificationFilterOutput.tif uint8");
91

92
    SetOfficialDocLink();
Jonathan Guinet's avatar
Jonathan Guinet committed
93
  }
94

95
  void DoUpdateParameters() ITK_OVERRIDE
96 97 98
  {
  }

99
  void DoExecute() ITK_OVERRIDE
100
  {
Marina Bertolino's avatar
Marina Bertolino committed
101 102
    if (IsParameterEnabled("vm") && HasValue("vm")) ConnectKMClassificationMask();

103
    KMeansFileNamesHandler fileNames;
Jonathan Guinet's avatar
Jonathan Guinet committed
104

105
    std::string fieldName = "field";
Jonathan Guinet's avatar
Jonathan Guinet committed
106

107
    fileNames.CreateTemporaryFileNames(GetParameterString( "out" ));
108

109
    // Create an image envelope
110
    ComputeImageEnvelope(fileNames.tmpVectorFile);
111
    // Add a new field at the ImageEnvelope output file
112
    ComputeAddField(fileNames.tmpVectorFile, fieldName);
Jonathan Guinet's avatar
Jonathan Guinet committed
113

114
    // Compute PolygonStatistics app
115 116
    UpdateKMPolygonClassStatisticsParameters(fileNames.tmpVectorFile);
    ComputePolygonStatistics(fileNames.polyStatOutput, fieldName);
117

118 119 120 121 122
    // Compute number of sample max for KMeans
    const int theoricNBSamplesForKMeans = GetParameterInt("ts");
    const int upperThresholdNBSamplesForKMeans = 1000 * 1000;
    const int actualNBSamplesForKMeans = std::min(theoricNBSamplesForKMeans,
                                                  upperThresholdNBSamplesForKMeans);
123 124
    otbAppLogINFO(<< actualNBSamplesForKMeans << " is the maximum sample size that will be used." \
                  << std::endl);
Jonathan Guinet's avatar
Jonathan Guinet committed
125

126
    // Compute SampleSelection and SampleExtraction app
127
    SelectAndExtractSamples(fileNames.polyStatOutput, fieldName,
128
                            fileNames.sampleOutput,
129
                            actualNBSamplesForKMeans);
130

131 132 133
    // Compute Images second order statistics
    ComputeImageStatistics(GetParameterString("in"), fileNames.imgStatOutput);

134
    // Compute a train model with TrainVectorClassifier app
135
    TrainKMModel(GetParameterImage("in"), fileNames.sampleOutput,
136
                 fileNames.modelFile);
137

138 139
    // Compute a classification of the input image according to a model file
    KMeansClassif();
140

141
    // remove all tempory files
142
    if( IsParameterEnabled( "cleanup" ) )
143
      {
144
      otbAppLogINFO( <<"Final clean-up ..." );
145
      fileNames.clear();
146
      }
147 148
  }

149 150 151 152 153 154
private :
  void UpdateKMPolygonClassStatisticsParameters(const std::string &vectorFileName)
  {
    GetInternalApplication( "polystats" )->SetParameterString( "vec", vectorFileName, false );
    UpdateInternalParameters( "polystats" );
  }
155

Jonathan Guinet's avatar
Jonathan Guinet committed
156
};
157

Jonathan Guinet's avatar
Jonathan Guinet committed
158 159
}
}
160

Jonathan Guinet's avatar
Jonathan Guinet committed
161
OTB_APPLICATION_EXPORT(otb::Wrapper::KMeansClassification)
162