diff --git a/Modules/Applications/AppFusion/app/otbBundleToPerfectSensor.cxx b/Modules/Applications/AppFusion/app/otbBundleToPerfectSensor.cxx index 2f31cd6344d4c8a76db4436b4303e1aed42af98d..62741969214b647891ac0bc47f282906080cf86b 100644 --- a/Modules/Applications/AppFusion/app/otbBundleToPerfectSensor.cxx +++ b/Modules/Applications/AppFusion/app/otbBundleToPerfectSensor.cxx @@ -16,25 +16,14 @@ =========================================================================*/ #include "otbWrapperApplicationFactory.h" +#include "otbWrapperCompositeApplication.h" -#include "otbMultiToMonoChannelExtractROI.h" -#include "otbGenericRSResampleImageFilter.h" -#include "otbGridResampleImageFilter.h" -#include "otbImportGeoInformationImageFilter.h" -#include "otbBCOInterpolateImageFunction.h" -#include "otbSimpleRcsPanSharpeningFusionImageFilter.h" -#include "itkFixedArray.h" - -// Elevation handler -#include "otbWrapperElevationParametersHandler.h" - -#include "otbPleiadesPToXSAffineTransformCalculator.h" namespace otb { namespace Wrapper { -class BundleToPerfectSensor : public Application +class BundleToPerfectSensor : public CompositeApplication { public: /** Standard class typedefs. */ @@ -46,7 +35,7 @@ public: /** Standard macro */ itkNewMacro(Self); - itkTypeMacro(BundleToPerfectSensor, otb::Application); + itkTypeMacro(BundleToPerfectSensor, otb::Wrapper::CompositeApplication); private: @@ -65,38 +54,27 @@ private: 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."); - - // Elevation - ElevationParametersHandler::AddElevationParameters(this, "elev"); - - // Superposition mode - AddParameter(ParameterType_Choice,"mode", "Mode"); - SetParameterDescription("mode", "Superimposition mode"); - - AddChoice("mode.default", "Default mode"); - SetParameterDescription("mode.default", "Default superimposition mode : " - "uses any projection reference or sensor model found in the images"); - - AddChoice("mode.phr", "Pleiades mode"); - SetParameterDescription("mode.phr", "Pleiades superimposition mode, " - "designed for the case of a P+XS bundle in SENSOR geometry. It uses" - " a simple transform on the XS image : a scaling and a residual " - "translation."); + ClearApplications(); + AddApplication("Superimpose", "superimpose", "Reproject XS onto Pan"); + AddApplication("Pansharpening", "pansharp", "Fusion of XS and Pan"); + + ShareParameter("inp","superimpose.inr","Input PAN Image","Input panchromatic image."); + ShareParameter("inxs","superimpose.inm","Input XS Image","Input XS image."); + ShareParameter("out","pansharp.out"); + ShareParameter("elev","superimpose.elev"); + ShareParameter("mode","superimpose.mode"); + ShareParameter("lms","superimpose.lms", + "Spacing of the deformation field", + "Spacing of the deformation field. Default is 10 times the PAN image spacing."); + ShareParameter("fv","superimpose.fv"); + ShareParameter("ram","superimpose.ram"); + + Connect("pansharp.inp","superimpose.inr"); + Connect("pansharp.ram","superimpose.ram"); + + GetInternalApplication("superimpose")->SetParameterString("interpolator","bco"); + GetInternalApplication("pansharp")->SetParameterString("method","rcs"); - AddParameter(ParameterType_Float, "lms", "Spacing of the deformation field"); - SetParameterDescription("lms"," Spacing of the deformation field. Default is 10 times the PAN image spacing."); - - AddRAMParameter(); - - MandatoryOff("lms"); - // Doc example parameter settings SetDocExampleParameterValue("inp", "QB_Toulouse_Ortho_PAN.tif"); SetDocExampleParameterValue("inxs", "QB_Toulouse_Ortho_XS.tif"); @@ -106,150 +84,19 @@ private: void DoUpdateParameters() ITK_OVERRIDE { - if(!HasUserValue("mode") && HasValue("inp") && HasValue("inxs") && otb::PleiadesPToXSAffineTransformCalculator::CanCompute(GetParameterImage("inp"),GetParameterImage("inxs"))) - { - otbAppLogWARNING("Forcing PHR mode with PHR data. You need to add \"-mode default\" to force the default mode with PHR images."); - SetParameterString("mode","phr"); - } + UpdateInternalParameters("superimpose"); } void DoExecute() ITK_OVERRIDE { - FloatVectorImageType* panchroV = GetParameterImage("inp"); - FloatVectorImageType* xs = GetParameterImage("inxs"); - - 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> InternalImageType; - typedef otb::MultiToMonoChannelExtractROI<float,float> ExtractFilterType; - - ExtractFilterType::Pointer channelSelect = ExtractFilterType::New(); - m_Ref.push_back(channelSelect.GetPointer()); - channelSelect->SetChannel(1); - channelSelect->SetInput(panchroV); - channelSelect->UpdateOutputInformation(); - InternalImageType::Pointer panchro = channelSelect->GetOutput(); - - typedef otb::BCOInterpolateImageFunction<FloatVectorImageType> InterpolatorType; - typedef otb::GenericRSResampleImageFilter<FloatVectorImageType, FloatVectorImageType> ResamplerType; - typedef otb::GridResampleImageFilter<FloatVectorImageType, FloatVectorImageType> BasicResamplerType; - typedef otb::ImportGeoInformationImageFilter<FloatVectorImageType,InternalImageType> ImportGeoInformationFilterType; - typedef otb::SimpleRcsPanSharpeningFusionImageFilter<InternalImageType, FloatVectorImageType, FloatVectorImageType> FusionFilterType; + ExecuteInternal("superimpose"); - // Resample filter - ResamplerType::Pointer resampler = ResamplerType::New(); - m_Ref.push_back(resampler.GetPointer()); - - BasicResamplerType::Pointer basicResampler = BasicResamplerType::New(); - m_Ref.push_back(basicResampler.GetPointer()); - - ImportGeoInformationFilterType::Pointer geoImport = ImportGeoInformationFilterType::New(); - m_Ref.push_back(geoImport.GetPointer()); - - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - resampler->SetInterpolator(interpolator); - basicResampler->SetInterpolator(interpolator); - - // Fusion filter - FusionFilterType::Pointer fusionFilter = FusionFilterType::New(); - m_Ref.push_back(fusionFilter.GetPointer()); - fusionFilter->SetPanInput(panchro); - - // Setup the DEM Handler - otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"elev"); - - // Set up output image information - FloatVectorImageType::SpacingType spacing = panchro->GetSpacing(); - FloatVectorImageType::IndexType start = panchro->GetLargestPossibleRegion().GetIndex(); - FloatVectorImageType::SizeType size = panchro->GetLargestPossibleRegion().GetSize(); - FloatVectorImageType::PointType origin = panchro->GetOrigin(); - - FloatVectorImageType::PixelType defaultValue; - itk::NumericTraits<FloatVectorImageType::PixelType>::SetLength(defaultValue, xs->GetNumberOfComponentsPerPixel()); + GetInternalApplication("pansharp")->SetParameterInputImage("inxs", + GetInternalApplication("superimpose")->GetParameterOutputImage("out")); - if(GetParameterString("mode") == "default") - { - otbAppLogINFO("Using the default mode"); - if(IsParameterEnabled("lms") && HasValue("lms")) - { - double defScalarSpacing = GetParameterFloat("lms"); - otbAppLogINFO(<< "Generating coarse deformation field (spacing="<<defScalarSpacing<<")" << std::endl); - FloatVectorImageType::SpacingType defSpacing; - - defSpacing[0] = defScalarSpacing; - defSpacing[1] = defScalarSpacing; - - resampler->SetDisplacementFieldSpacing(defSpacing); - } - else - { - FloatVectorImageType::SpacingType defSpacing; - defSpacing[0]=10*spacing[0]; - defSpacing[1]=10*spacing[1]; - resampler->SetDisplacementFieldSpacing(defSpacing); - } - - resampler->SetInput(xs); - resampler->SetOutputOrigin(origin); - resampler->SetOutputSpacing(spacing); - resampler->SetOutputSize(size); - resampler->SetOutputStartIndex(start); - resampler->SetOutputKeywordList(panchro->GetImageKeywordlist()); - resampler->SetOutputProjectionRef(panchro->GetProjectionRef()); - resampler->SetEdgePaddingValue(defaultValue); - fusionFilter->SetXsInput(resampler->GetOutput()); - } - else if(GetParameterString("mode")=="phr") - { - otbAppLogINFO("Using the PHR mode"); - - otb::PleiadesPToXSAffineTransformCalculator::TransformType::OffsetType offset - = otb::PleiadesPToXSAffineTransformCalculator::ComputeOffset(GetParameterImage("inp"), - GetParameterImage("inxs")); - - origin+=offset; - origin[0]=origin[0]/4; - origin[1]=origin[1]/4; - - basicResampler->SetOutputOrigin(origin); - basicResampler->SetInput(xs); - basicResampler->SetOutputOrigin(origin); - - FloatVectorImageType::SpacingType xsSpacing = GetParameterImage("inxs")->GetSpacing(); - xsSpacing*=0.25; - - basicResampler->SetOutputSpacing(xsSpacing); - basicResampler->SetOutputSize(size); - basicResampler->SetOutputStartIndex(start); - basicResampler->SetEdgePaddingValue(defaultValue); - - geoImport->SetInput(basicResampler->GetOutput()); - geoImport->SetSource(panchro); - - fusionFilter->SetXsInput(geoImport->GetOutput()); - - // Set the profRef & Keywordlist from Pan into the resampled XS image - basicResampler->UpdateOutputInformation(); - itk::MetaDataDictionary& dict = basicResampler->GetOutput()->GetMetaDataDictionary(); - itk::EncapsulateMetaData<std::string>(dict, MetaDataKey::ProjectionRefKey, - panchro->GetProjectionRef()); - itk::EncapsulateMetaData<ImageKeywordlist>(dict, MetaDataKey::OSSIMKeywordlistKey, - panchro->GetImageKeywordlist()); - } - else - { - otbAppLogWARNING("Unknown mode"); - } - - SetParameterOutputImage("out", fusionFilter->GetOutput()); + ExecuteInternal("pansharp"); } - std::vector<itk::ProcessObject::Pointer> m_Ref; - }; diff --git a/Modules/Applications/AppFusion/otb-module.cmake b/Modules/Applications/AppFusion/otb-module.cmake index 54fe75ccac06953703f04292cf71acadd3a4939c..e09047b0b4b7372b86c007a6b70532d6b6f4e691 100644 --- a/Modules/Applications/AppFusion/otb-module.cmake +++ b/Modules/Applications/AppFusion/otb-module.cmake @@ -10,6 +10,7 @@ otb_module(OTBAppFusion OTBInterpolation TEST_DEPENDS + OTBAppProjection OTBTestKernel OTBCommandLine diff --git a/Modules/Applications/AppProjection/app/otbSuperimpose.cxx b/Modules/Applications/AppProjection/app/otbSuperimpose.cxx index a2fc5e2549333380e9b2cca755f2cacf3f43eeea..ac37bdc6e7ce080d7ec95303d3f52e7d02e69be8 100644 --- a/Modules/Applications/AppProjection/app/otbSuperimpose.cxx +++ b/Modules/Applications/AppProjection/app/otbSuperimpose.cxx @@ -104,6 +104,7 @@ private: AddParameter(ParameterType_Float, "lms", "Spacing of the deformation field"); SetParameterDescription("lms","Generate a coarser deformation field with the given spacing"); SetDefaultParameterFloat("lms", 4.); + DisableParameter("lms"); MandatoryOff("lms"); AddParameter(ParameterType_Float, "fv", "Fill Value"); @@ -219,20 +220,24 @@ private: if(GetParameterString("mode")=="default") { + FloatVectorImageType::SpacingType defSpacing; if(IsParameterEnabled("lms")) { float defScalarSpacing = vcl_abs(GetParameterFloat("lms")); otbAppLogDEBUG("Generating coarse deformation field (spacing="<<defScalarSpacing<<")"); - FloatVectorImageType::SpacingType defSpacing; defSpacing[0] = defScalarSpacing; defSpacing[1] = defScalarSpacing; if (spacing[0]<0.0) defSpacing[0] *= -1.0; if (spacing[1]<0.0) defSpacing[1] *= -1.0; - - m_Resampler->SetDisplacementFieldSpacing(defSpacing); } + else + { + defSpacing[0]=10*spacing[0]; + defSpacing[1]=10*spacing[1]; + } + m_Resampler->SetDisplacementFieldSpacing(defSpacing); // Setup transform through projRef and Keywordlist m_Resampler->SetInputKeywordList(movingImage->GetImageKeywordlist()); diff --git a/Modules/Applications/AppProjection/test/CMakeLists.txt b/Modules/Applications/AppProjection/test/CMakeLists.txt index bff04845b68deeb44c0924471b7d10066d522319..81eea8e987ac15269fb0677ce0b80dedadfc892f 100644 --- a/Modules/Applications/AppProjection/test/CMakeLists.txt +++ b/Modules/Applications/AppProjection/test/CMakeLists.txt @@ -320,6 +320,7 @@ otb_test_application(NAME apTvPrSuperimpose -inm ${INPUTDATA}/QB_Toulouse_Ortho_XS_ROI_170x230.tif -elev.dem ${INPUTDATA}/DEM/srtm_directory -out ${TEMP}/apTvPrSuperimpose.tif int16 + -lms 4.0 VALID --compare-image ${EPSILON_7} ${BASELINE}/apTvPrSuperimpose.tif ${TEMP}/apTvPrSuperimpose.tif)