otbEndmemberNumberEstimation.cxx 6.36 KiB
/*
 * 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.
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "otbStreamingStatisticsVectorImageFilter.h"
#include "otbEigenvalueLikelihoodMaximisation.h"
#include "otbVirtualDimensionality.h"
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);
  typedef otb::StreamingStatisticsVectorImageFilter<FloatVectorImageType, float> 
    StreamingStatisticsVectorImageFilterType;
  typedef otb::VirtualDimensionality<float> VirtualDimensionalityType;
  typedef otb::EigenvalueLikelihoodMaximisation<float> EigenvalueLikelihoodMaximisationType;
private:
  void DoInit() override
    SetName("EndmemberNumberEstimation");
    SetDescription("Estimates the number of endmembers in a hyperspectral image");
    // Documentation
    SetDocName("Endmember Number Estimation");
    SetDocLongDescription("This application estimates the number of endmembers "
    "in a hyperspectral image. It first computes statistics on the image and then "
    "apply an endmember number estimation algorithm using these statistics. Two "
    "algorithms are available: \n"
    "1) Virtual Dimensionality (vd) [1][2] \n"
    "2) Eigenvalue Likelihood Maximization (elm) [3][4] \n"
    "The application then returns the estimated number of endmembers. \n"
    "References : \n"
    "[1] C.-I. Chang and Q. Du, Estimation of number of spectrally distinct signal "
    "sources in hyperspectral imagery, IEEE Transactions on Geoscience and Remote "
    "Sensing, vol. 43, no. 3, mar 2004. \n"
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
"[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. " "2601-1616, sep 2006. \n" "[3] Unsupervised Endmember Extraction of Martian Hyperspectral Images, B.Luo, " "J. Chanussot, S. Dout\'e and X. Ceamanos, IEEE Whispers 2009, Grenoble France, 2009 \n" "[4] Unsupervised classification of hyperspectral images by using " "linear unmixing algorithm Luo, B. and Chanussot, J., IEEE Int. Conf. On Image \n" "Processing(ICIP) 2009, Cairo, Egypte, 2009" ); SetDocLimitations("None"); SetDocAuthors("OTB-Team"); SetDocSeeAlso("VertexComponentAnalysis, HyperspectralUnmixing"); AddDocTag(Tags::Hyperspectral); AddParameter(ParameterType_InputImage, "in", "Input Image Filename"); SetParameterDescription("in","The hyperspectral data cube input"); AddParameter(ParameterType_Choice, "algo", "Unmixing algorithm"); SetParameterDescription("algo", "The algorithm to use for the estimation"); AddChoice("algo.elm", "elm"); SetParameterDescription("algo.elm", "Eigenvalue Likelihood Maximization"); AddChoice("algo.vd", "vd"); SetParameterDescription("algo.vd", "virtual dimensionality"); AddParameter( ParameterType_Float , "algo.vd.far" , "false alarm rate" "Maximum training predictors"); SetMinimumParameterFloatValue("algo.vd.far",0); SetMaximumParameterFloatValue("algo.vd.far",1); SetDefaultParameterFloat( "algo.vd.far" , 1.0E-3 ); SetParameterDescription( "algo.vd.far" , "False alarm rate for the virtual dimensionality algorithm"); AddParameter(ParameterType_Int,"number","Number of endmembers"); SetParameterDescription("number", "Estimated number of endmembers"); SetParameterRole("number", Role_Output); // Doc example parameter settings SetDocExampleParameterValue("in", "cupriteSubHsi.tif"); SetDocExampleParameterValue("algo", "vd"); SetDocExampleParameterValue("algo.vd.far", "1.0E-3"); SetOfficialDocLink(); } void DoUpdateParameters() override { // Nothing to do here : all parameters are independent } void DoExecute() override { // Load input image auto inputImage = GetParameterImage("in"); otbAppLogINFO("Computing statistics on input image ..."); auto statisticsFilter = StreamingStatisticsVectorImageFilterType::New(); statisticsFilter->SetInput(inputImage); statisticsFilter->Update(); auto correlationMatrix = statisticsFilter->GetCorrelation().GetVnlMatrix(); auto covarianceMatrix = statisticsFilter->GetCovariance().GetVnlMatrix(); auto numberOfPixels = inputImage->GetLargestPossibleRegion().GetNumberOfPixels(); int numberOfEndmembers = 0; const std::string algorithm = GetParameterString("algo"); if (algorithm=="elm")
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
{ otbAppLogINFO("Estimation algorithm : Eigenvalue Likelihood Maximization."); auto elm = EigenvalueLikelihoodMaximisationType::New(); elm->SetCovariance(covarianceMatrix); elm->SetCorrelation(correlationMatrix); elm->SetNumberOfPixels(numberOfPixels); elm->Compute(); numberOfEndmembers = elm->GetNumberOfEndmembers(); } else if (algorithm=="vd") { otbAppLogINFO("Estimation algorithm : Virtual Dimensionality."); auto vd = VirtualDimensionalityType::New(); vd->SetCovariance(covarianceMatrix); vd->SetCorrelation(correlationMatrix); vd->SetNumberOfPixels(numberOfPixels); vd->SetFAR(GetParameterFloat("algo.vd.far")); vd->Compute(); numberOfEndmembers = vd->GetNumberOfEndmembers(); } SetParameterInt("number", numberOfEndmembers); } }; } } OTB_APPLICATION_EXPORT(otb::Wrapper::EndmemberNumberEstimation)