otbEndmemberNumberEstimation.cxx 6.49 KB
Newer Older
1
/*
2
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *
 * 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.
 */

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

Cedric's avatar
Cedric committed
24
#include "otbStreamingStatisticsVectorImageFilter.h"
25
26
#include "otbEigenvalueLikelihoodMaximisation.h"
#include "otbVirtualDimensionality.h"
Cedric's avatar
Cedric committed
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
namespace otb
{
namespace Wrapper
{

class EndmemberNumberEstimation : public Application
{
public:
  /** Standard class typedefs. */
  typedef EndmemberNumberEstimation         Self;
  typedef Application                       Superclass;
  typedef itk::SmartPointer<Self>           Pointer;
  typedef itk::SmartPointer<const Self>     ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(EndmemberNumberEstimation, otb::Application);

47
48
49
  typedef otb::StreamingStatisticsVectorImageFilter<FloatVectorImageType, double> StreamingStatisticsVectorImageFilterType;
  typedef otb::VirtualDimensionality<double>                                      VirtualDimensionalityType;
  typedef otb::EigenvalueLikelihoodMaximisation<double>                           EigenvalueLikelihoodMaximisationType;
Cedric's avatar
Cedric committed
50

51
52
53
54
private:
  void DoInit() override
  {
    SetName("EndmemberNumberEstimation");
55
    SetDescription("Estimate the number of endmembers in a hyperspectral image");
56
57

    // Documentation
58
59
    SetDocLongDescription("Estimate the number of endmembers "
    "in a hyperspectral image. First, compute statistics on the image and then "
60
    "apply an endmember number estimation algorithm using these statistics. Two "
61
62
    "algorithms are available:\n\n"

63
    "1. Virtual Dimensionality (HFC-VD) [1][2]\n"
64
65
66
67
    "2. Eigenvalue Likelihood Maximization (ELM) [3][4]\n\n"

    "The application then returns the estimated number of endmembers.\n\n"

68
69
    "[1] C.-I. Chang and Q. Du, Estimation of number of spectrally distinct signal "
    "sources in hyperspectral imagery, IEEE Transactions on Geoscience and Remote "
70
71
    "Sensing, vol. 43, no. 3, mar 2004.\n\n"

72
73
74
    "[2] J. Wang and C.-I. Chang, Applications of independent component analysis "
    "in endmember extraction and abundance quantification for hyperspectral imagery"
    ", IEEE Transactions on Geoscience and Remote Sensing, vol. 44, no. 9, pp. "
75
76
    "2601-1616, sep 2006.\n\n"

77
    "[3] Unsupervised Endmember Extraction of Martian Hyperspectral Images, B.Luo, "
78
79
    "J. Chanussot, S. Dout\'e and X. Ceamanos, IEEE Whispers 2009, Grenoble France, 2009\n\n"

80
    "[4] Unsupervised classification of hyperspectral images by using "
Cedric's avatar
Cedric committed
81
    "linear unmixing algorithm Luo, B. and Chanussot, J., IEEE Int. Conf. On Image"
82
83
84
    "Processing(ICIP) 2009, Cairo, Egypte, 2009"
    );

85
86
87
88
89
90
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("VertexComponentAnalysis, HyperspectralUnmixing");

    AddDocTag(Tags::Hyperspectral);

Cedric's avatar
Cedric committed
91
    AddParameter(ParameterType_InputImage,  "in", "Input Image Filename");
92
93
    SetParameterDescription("in","The hyperspectral data cube input");

94
95
96
97
    AddParameter(ParameterType_Int,"number","Number of endmembers");
    SetParameterDescription("number", "The output estimated number of endmembers");
    SetParameterRole("number", Role_Output);

98
99
    AddParameter(ParameterType_Choice, "algo", "Unmixing algorithm");
    SetParameterDescription("algo", "The algorithm to use for the estimation");
100
    AddChoice("algo.elm", "Eigenvalue Likelihood Maximization");
101
    SetParameterDescription("algo.elm", "Eigenvalue Likelihood Maximization algorithm");
102
    AddChoice("algo.vd", "Virtual Dimensionality");
103
    SetParameterDescription("algo.vd", "HFC Virtual Dimensionality algorithm");
104

Cedric's avatar
Cedric committed
105
106
107
    AddParameter( ParameterType_Float , "algo.vd.far" , "False alarm rate");
    SetMinimumParameterFloatValue("algo.vd.far", 0);
    SetMaximumParameterFloatValue("algo.vd.far", 1);
108
109
    SetDefaultParameterFloat( "algo.vd.far" , 1.0E-3 );
    SetParameterDescription( "algo.vd.far" , 
Cedric's avatar
Cedric committed
110
      "False alarm rate for the virtual dimensionality algorithm");
111

112
113
    AddRAMParameter();
    
114
115
    // Doc example parameter settings
    SetDocExampleParameterValue("in", "cupriteSubHsi.tif");
Cedric's avatar
Cedric committed
116
117
    SetDocExampleParameterValue("algo", "vd");
    SetDocExampleParameterValue("algo.vd.far", "1.0E-3");
118
119
120
121
122
123
124
125
126
127
128

    SetOfficialDocLink();
  }

  void DoUpdateParameters() override
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute() override
  {
Cedric's avatar
Cedric committed
129
130
131
    // Load input image
    auto inputImage = GetParameterImage("in");

132
    otbAppLogINFO("Computing statistics on input image...");
Cedric's avatar
Cedric committed
133
    auto statisticsFilter = StreamingStatisticsVectorImageFilterType::New();
Cedric's avatar
Cedric committed
134
    statisticsFilter->SetInput(inputImage);
135
    AddProcess(statisticsFilter->GetStreamer(), "Statistic estimation step");
136

Cedric's avatar
Cedric committed
137
    statisticsFilter->Update();
Cedric's avatar
Cedric committed
138
139
140
141
142

    auto correlationMatrix = statisticsFilter->GetCorrelation().GetVnlMatrix();
    auto covarianceMatrix = statisticsFilter->GetCovariance().GetVnlMatrix();
    auto numberOfPixels = inputImage->GetLargestPossibleRegion().GetNumberOfPixels();

143
144
145
146
    int numberOfEndmembers = 0;
    const std::string algorithm = GetParameterString("algo");
    if (algorithm=="elm")
      {
147
      otbAppLogINFO("Estimation algorithm: Eigenvalue Likelihood Maximization.");
148
      auto elm = EigenvalueLikelihoodMaximisationType::New();
Cedric's avatar
Cedric committed
149
150
151
      elm->SetCovariance(covarianceMatrix);
      elm->SetCorrelation(correlationMatrix);
      elm->SetNumberOfPixels(numberOfPixels);
152
153
154
155
156
      elm->Compute();
      numberOfEndmembers = elm->GetNumberOfEndmembers();
      }
    else if (algorithm=="vd")
      {
157
      otbAppLogINFO("Estimation algorithm: HFC Virtual Dimensionality.");
158
      auto vd = VirtualDimensionalityType::New();
Cedric's avatar
Cedric committed
159
160
161
      vd->SetCovariance(covarianceMatrix);
      vd->SetCorrelation(correlationMatrix);
      vd->SetNumberOfPixels(numberOfPixels);
162
      vd->SetFAR(GetParameterFloat("algo.vd.far"));
163
164
165
166
      vd->Compute();
      numberOfEndmembers = vd->GetNumberOfEndmembers();
      }
    SetParameterInt("number", numberOfEndmembers);
167
168
169
170
171
172
173
174
  }

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::EndmemberNumberEstimation)