Commit 73406694 authored by Victor Poughon's avatar Victor Poughon

Merge branch 'number_of_endmember_estimation' into 'develop'

Number of endmember estimation application

See merge request orfeotoolbox/otb!344
parents e4b5abc4 c4ff6702
......@@ -27,3 +27,8 @@ otb_create_application(
NAME VertexComponentAnalysis
SOURCES otbVertexComponentAnalysis.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
otb_create_application(
NAME EndmemberNumberEstimation
SOURCES otbEndmemberNumberEstimation.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
/*
* 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("Estimate the number of endmembers in a hyperspectral image");
// Documentation
SetDocName("Endmember Number Estimation");
SetDocLongDescription("Estimate the number of endmembers "
"in a hyperspectral image. First, compute statistics on the image and then "
"apply an endmember number estimation algorithm using these statistics. Two "
"algorithms are available:\n\n"
"1. Virtual Dimensionality (VD) [1][2]\n"
"2. Eigenvalue Likelihood Maximization (ELM) [3][4]\n\n"
"The application then returns the estimated number of endmembers.\n\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\n"
"[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\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\n"
"[4] Unsupervised classification of hyperspectral images by using "
"linear unmixing algorithm Luo, B. and Chanussot, J., IEEE Int. Conf. On Image"
"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_Int,"number","Number of endmembers");
SetParameterDescription("number", "The output estimated number of endmembers");
SetParameterRole("number", Role_Output);
AddParameter(ParameterType_Choice, "algo", "Unmixing algorithm");
SetParameterDescription("algo", "The algorithm to use for the estimation");
AddChoice("algo.elm", "Eigenvalue Likelihood Maximization");
SetParameterDescription("algo.elm", "");
AddChoice("algo.vd", "Virtual Dimensionality");
SetParameterDescription("algo.vd", "");
AddParameter( ParameterType_Float , "algo.vd.far" , "False alarm rate");
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");
AddRAMParameter();
// 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);
AddProcess(statisticsFilter->GetStreamer(), "Statistic estimation step");
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")
{
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)
......@@ -95,13 +95,13 @@ private:
// Documentation
SetDocName("Hyperspectral data unmixing");
SetDocLongDescription("The application applies a linear unmixing algorithm"
"to an hyperspectral data cube. This method supposes that the mixture between"
"aterials in the scene is macroscopic and simulates a linear mixing model of"
SetDocLongDescription("The application applies a linear unmixing algorithm "
"to an hyperspectral data cube. This method supposes that the mixture between "
"aterials in the scene is macroscopic and simulates a linear mixing model of "
"spectra.\n\n"
"The Linear Mixing Model (LMM) acknowledges that reflectance"
"spectrum associated with each pixel is a linear combination of pure"
"materials in the recovery area, commonly known as endmembers. Endmembers can"
"The Linear Mixing Model (LMM) acknowledges that reflectance "
"spectrum associated with each pixel is a linear combination of pure "
"materials in the recovery area, commonly known as endmembers. Endmembers can "
"be estimated using the VertexComponentAnalysis application.\n\n"
"The application allows estimating the abundance maps with several algorithms:\n\n"
"* Unconstrained Least Square (ucls)\n"
......@@ -121,10 +121,14 @@ private:
SetParameterDescription("in","The hyperspectral data cube input");
AddParameter(ParameterType_OutputImage, "out", "Output Image");
SetParameterDescription("out","The output abundance map. The abundance fraction are stored in a multispectral image where band N corresponds to the fraction of endmembers N in each pixel.");
SetParameterDescription("out","The output abundance map. The abundance "
"fraction are stored in a multispectral image where band N corresponds "
"to the fraction of endmembers N in each pixel.");
AddParameter(ParameterType_InputImage, "ie", "Input endmembers");
SetParameterDescription("ie","The endmembers (estimated pure pixels) to use for unmixing. Must be stored as a multispectral image, where each pixel is interpreted as an endmember.");
SetParameterDescription("ie","The endmembers (estimated pure pixels) to "
"use for unmixing. Must be stored as a multispectral image, where "
"each pixel is interpreted as an endmember.");
AddParameter(ParameterType_Choice, "ua", "Unmixing algorithm");
SetParameterDescription("ua", "The algorithm to use for unmixing");
......
......@@ -50,25 +50,25 @@ private:
void DoInit() override
{
SetName("VertexComponentAnalysis");
SetDescription("Given a set of mixed spectral vectors, estimate"
"reference substances also known as endmembers using the Vertex"
SetDescription("Given a set of mixed spectral vectors, estimate "
"reference substances also known as endmembers using the Vertex "
"Component Analysis algorithm.");
// Documentation
SetDocName("Vertex Component Analysis");
SetDocLongDescription("Apply the Vertex Component Analysis [1] to"
"an hyperspectral image to extract endmembers. Given a set of mixed"
"spectral vectors (multispectral or hyperspectral), the application"
"estimates the spectral signature of reference substances also known"
SetDocLongDescription("Apply the Vertex Component Analysis [1] to "
"an hyperspectral image to extract endmembers. Given a set of mixed "
"spectral vectors (multispectral or hyperspectral), the application "
"estimates the spectral signature of reference substances also known "
"as endmembers.");
SetDocLimitations("None");
SetDocAuthors("OTB-Team");
SetDocSeeAlso("[1] J. M. P. Nascimento and J. M. B. Dias, Vertex"
"component analysis: a fast algorithm to unmix hyperspectral data,"
"in IEEE Transactions on Geoscience and Remote Sensing, vol. 43,"
"no. 4, pp. 898-910, April 2005.J. M. P. Nascimento and"
"J. M. B. Dias, Vertex component analysis: a fast algorithm to"
"unmix hyperspectral data, in IEEE Transactions on Geoscience and"
SetDocSeeAlso("[1] J. M. P. Nascimento and J. M. B. Dias, Vertex "
"component analysis: a fast algorithm to unmix hyperspectral data, "
"in IEEE Transactions on Geoscience and Remote Sensing, vol. 43, "
"no. 4, pp. 898-910, April 2005.J. M. P. Nascimento and "
"J. M. B. Dias, Vertex component analysis: a fast algorithm to "
"unmix hyperspectral data, in IEEE Transactions on Geoscience and "
"Remote Sensing, vol. 43, no. 4, pp. 898-910, April 2005.");
AddDocTag(Tags::Hyperspectral);
......@@ -78,9 +78,9 @@ private:
SetParameterDescription("in","Input hyperspectral data cube");
AddParameter(ParameterType_OutputImage, "outendm", "Output Endmembers");
SetParameterDescription("outendm","Endmembers, stored in a"
"one-line multi-spectral image.Each pixel corresponds to one"
"endmembers and each band values corresponds to the spectral"
SetParameterDescription("outendm","Endmembers, stored in a "
"one-line multi-spectral image.Each pixel corresponds to one "
"endmembers and each band values corresponds to the spectral "
"signature of the corresponding endmember.");
MandatoryOn("outendm");
......
......@@ -53,3 +53,24 @@ otb_test_application(NAME apTvHyVertexComponentAnalysis
${TEMP}/apTvHyVertexComponentAnalysis.tif
)
#----------- EndmemberNumberEstimation TESTS ----------------
otb_test_application(NAME apTvHyEndmemberNumberEstimation_vd
APP EndmemberNumberEstimation
OPTIONS -in ${OTB_DATA_ROOT}/Input/Hyperspectral/synthetic/hsi_cube.tif
-algo vd
-algo.vd.far 0.001
TESTENVOPTIONS ${TEMP}/aptTvHyEndmemberNumberEstimation_vd.txt
VALID --compare-ascii ${EPSILON_7}
${BASELINE_FILES}/aptTvHyEndmemberNumberEstimation.txt
${TEMP}/aptTvHyEndmemberNumberEstimation_vd.txt
)
otb_test_application(NAME apTvHyEndmemberNumberEstimation_elm
APP EndmemberNumberEstimation
OPTIONS -in ${OTB_DATA_ROOT}/Input/Hyperspectral/synthetic/hsi_cube.tif
-algo elm
TESTENVOPTIONS ${TEMP}/aptTvHyEndmemberNumberEstimation_elm.txt
VALID --compare-ascii ${EPSILON_7}
${BASELINE_FILES}/aptTvHyEndmemberNumberEstimation.txt
${TEMP}/aptTvHyEndmemberNumberEstimation_elm.txt
)
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment