Newer
Older
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "itkVectorIndexSelectionCastImageFilter.h"
#include "otbGenericRSResampleImageFilter.h"
#include "otbBCOInterpolateImageFunction.h"
#include "otbSimpleRcsPanSharpeningFusionImageFilter.h"
#include "otbBayesianFusionFilter.h"
#include "otbGenericRSResampleImageFilter.h"
#include "otbBCOInterpolateImageFunction.h"
#include "otbLmvmPanSharpeningFusionImageFilter.h"
#include "itkPixelBuilder.h"
#include "itkFixedArray.h"
// Elevation handler
#include "otbWrapperElevationParametersHandler.h"
namespace otb
{
namespace Wrapper
{
class Pansharpening : public Application
{
public:
/** Standard class typedefs. */
typedef Application Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef itk::ImageToImageFilter<FloatVectorImageType, FloatVectorImageType> FusionFilterType;
typedef otb::SimpleRcsPanSharpeningFusionImageFilter<FloatImageType, FloatVectorImageType, FloatVectorImageType> SimpleRCSFilterType;
typedef otb::LmvmPanSharpeningFusionImageFilter
<FloatImageType, FloatVectorImageType, FloatVectorImageType, double> LmvmFilterType;
typedef otb::BayesianFusionFilter<FloatVectorImageType, FloatVectorImageType, FloatImageType, FloatVectorImageType> BayesianFilterType;
typedef otb::BCOInterpolateImageFunction<FloatVectorImageType> InterpolatorType;
typedef otb::GenericRSResampleImageFilter<FloatVectorImageType,
FloatVectorImageType> ResamplerType;
/** Standard macro */
itkNewMacro(Self);
itkTypeMacro(Pansharpening, otb::Application);
private:
void DoInit()
{
SetName("Pansharpening");
SetDescription("Perform P+XS pansharpening");
// Documentation
SetDocName("Pansharpening");
SetDocLongDescription("This application performs P+XS pansharpening. Pansharpening is a process of merging high-resolution panchromatic and lower resolution multispectral imagery to create a single high-resolution color image. Algorithms available in the applications are: RCS, bayesian fusion and Local Mean and Variance Matching(LMVM).");
SetDocLimitations("None");
SetDocAuthors("OTB-Team");
SetDocSeeAlso(" ");
AddDocTag(Tags::Geometry);
AddDocTag(Tags::Pansharpening);
AddParameter(ParameterType_InputImage, "inp", "Input PAN Image");
SetParameterDescription("inp"," Input panchromatic image.");
AddParameter(ParameterType_InputImage, "inxs", "Input XS Image");
SetParameterDescription("inxs"," Input XS image.");
AddParameter(ParameterType_OutputImage, "out", "Output image");
SetParameterDescription("out"," Output image.");
AddParameter(ParameterType_Choice, "method", "Algorithm");
SetParameterDescription("method", "Selection of the pan-sharpening method.");
AddChoice("method.rcs", "RCS");
SetParameterDescription("method.rcs", "Simple RCS Pan sharpening operation.");
AddChoice("method.lmvm", "LMVM");
SetParameterDescription("method.lmvm", "Local Mean and Variance Matching (LMVM) Pan sharpening.");
AddParameter(ParameterType_Int, "method.lmvm.radiusx", "X radius" );
SetParameterDescription("method.lmvm.radiusx","Set the x radius of the sliding window." );
SetMinimumParameterIntValue("method.lmvm.radiusx", 1);
SetDefaultParameterInt("method.lmvm.radiusx", 3);
AddParameter(ParameterType_Int, "method.lmvm.radiusy", "Y radius");
SetParameterDescription("method.lmvm.radiusy", "Set the y radius of the sliding window.");
SetMinimumParameterIntValue("method.lmvm.radiusy", 1);
SetDefaultParameterInt("method.lmvm.radiusy", 3);
AddChoice("method.bayes", "Bayesian");
SetParameterDescription("method.bayes", "Bayesian fusion.");
AddParameter(ParameterType_Float, "method.bayes.lambda", "Weight");
SetParameterDescription("method.bayes.lambda", "Set the weighting value.");
SetMinimumParameterFloatValue("method.bayes.lambda", 0);
SetDefaultParameterFloat("method.bayes.lambda", 0.9999);
AddParameter(ParameterType_Float, "method.bayes.s", "S coefficient");
SetParameterDescription("method.bayes.s", "Set the S coefficient.");
SetMinimumParameterFloatValue("method.bayes.s", 1);
SetDefaultParameterFloat("method.bayes.s", 1);
AddRAMParameter();
// Doc example parameter settings
SetDocExampleParameterValue("inp", "QB_Toulouse_Ortho_PAN.tif");
SetDocExampleParameterValue("inxs", "QB_Toulouse_Ortho_XS.tif");
SetDocExampleParameterValue("out", "Pansharpening.tif uint16");
}
void DoUpdateParameters()
{
// Nothing to do here : all parameters are independent
}
void DoExecute()
{
FloatVectorImageType* panchroV = GetParameterImage("inp");
if ( panchroV->GetNumberOfComponentsPerPixel() != 1 )
{
itkExceptionMacro(<< "The panchromatic image must be a single channel image")
}
// Transform the PAN image to otb::Image
typedef otb::Image<FloatVectorImageType::InternalPixelType> FloatImageType;
typedef itk::VectorIndexSelectionCastImageFilter<FloatVectorImageType, FloatImageType> VectorIndexSelectionCastImageFilterType;
VectorIndexSelectionCastImageFilterType::Pointer channelSelect = VectorIndexSelectionCastImageFilterType::New();
m_Ref.push_back(channelSelect.GetPointer());
channelSelect->SetIndex(0);
channelSelect->SetInput(panchroV);
channelSelect->UpdateOutputInformation();
FloatImageType::Pointer panchro = channelSelect->GetOutput();
FloatVectorImageType* xs = GetParameterImage("inxs");
switch (GetParameterInt("method"))
{
case 0:
{
SimpleRCSFilterType::Pointer filter = SimpleRCSFilterType::New();
m_Ref.push_back(filter.GetPointer());
filter->SetPanInput(panchro);
filter->SetXsInput(xs);
filter->UpdateOutputInformation();
otbAppLogINFO( << "Simple RCS algorithm" );
m_FusionFilter = filter;
break;
}
case 1:
{
LmvmFilterType::Pointer filter = LmvmFilterType::New();
filter->SetXsInput(xs);
filter->SetPanInput(panchro);
double radiusx = static_cast<unsigned int> (GetParameterInt("method.lmvm.radiusx"));
double radiusy = static_cast<unsigned int> (GetParameterInt("method.lmvm.radiusy"));
FloatImageType::SizeType radius;
radius[0] = radiusx;
radius[1] = radiusy;
filter->SetRadius(radius);
itk::Array<double> filterCoeffs;
filterCoeffs.SetSize((2 * radius[0] + 1) * (2 * radius[1] + 1));
filterCoeffs.Fill(1);
filter->SetFilter(filterCoeffs);
filter->UpdateOutputInformation();
otbAppLogINFO( << "Lmvm algorithm" );
m_FusionFilter = filter;
break;
}
case 2:
{
BayesianFilterType::Pointer filter = BayesianFilterType::New();
double lambda = static_cast<double> (GetParameterFloat("method.bayes.lambda"));
double s = static_cast<double> (GetParameterFloat("method.bayes.s"));
filter->SetS(s);
filter->SetLambda(lambda);
filter->SetMultiSpect(xs);
filter->SetMultiSpectInterp(xs);
filter->SetPanchro(panchro);
filter->UpdateOutputInformation();
otbAppLogINFO( << "Bayesian fusion algorithm" );
m_FusionFilter = filter;
break;
}
default:
{
otbAppLogFATAL(<<"non defined method "<<GetParameterInt("method")<<std::endl);
break;
}
return;
}
SetParameterOutputImage("out", m_FusionFilter->GetOutput());
}
std::vector<itk::ProcessObject::Pointer> m_Ref;
FusionFilterType::Pointer m_FusionFilter;
};
}
}
OTB_APPLICATION_EXPORT(otb::Wrapper::Pansharpening)