Commit e7720786 authored by Rémi Cresson's avatar Rémi Cresson

ADD: Move Mosaic remote module in OTB

parent f53e0e64
Pipeline #2648 failed with stages
in 6 minutes and 41 seconds
......@@ -87,3 +87,8 @@ otb_create_application(
NAME DynamicConvert
SOURCES otbDynamicConvert.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
OTB_CREATE_APPLICATION(
NAME Mosaic
SOURCES otbMosaic.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
This diff is collapsed.
......@@ -39,6 +39,7 @@ otb_module(OTBAppImageUtils
OTBStreaming
OTBTransform
OTBFunctor
OTBMosaic
TEST_DEPENDS
OTBCommandLine
......
......@@ -455,3 +455,63 @@ otb_test_application(NAME apTvUtSplitImage
${INPUTDATA}/poupees_sub_c3.png
${TEMP}/apTvUtSplitImageOutput_2.tif)
#----------- Mosaic TESTS ----------------
otb_test_application(NAME MosaicTestLargeFeathering
APP Mosaic
OPTIONS -il ${INPUTDATA}/SP67_FR_subset_1.tif ${INPUTDATA}/SP67_FR_subset_2.tif
-out ${TEMP}/apTvMosaicTestLargeFeathering.tif uint8
-comp.feather large
VALID --compare-image ${EPSILON_8}
${BASELINE}/apTvMosaicTestLargeFeathering.tif
${TEMP}/apTvMosaicTestLargeFeathering.tif)
otb_test_application(NAME MosaicTestSlimFeathering
APP Mosaic
OPTIONS -il ${INPUTDATA}/SP67_FR_subset_1.tif ${INPUTDATA}/SP67_FR_subset_2.tif
-out ${TEMP}/apTvMosaicTestSlimFeathering.tif uint8
-comp.feather slim
-comp.feather.slim.lenght 100
VALID --compare-image ${EPSILON_8}
${BASELINE}/apTvMosaicTestSlimFeathering.tif
${TEMP}/apTvMosaicTestSlimFeathering.tif)
otb_test_application(NAME MosaicTestSimpleWithHarmoBandRmse
APP Mosaic
OPTIONS -il ${INPUTDATA}/SP67_FR_subset_1.tif ${INPUTDATA}/SP67_FR_subset_2.tif
-out ${TEMP}/apTvMosaicTestSimpleWithHarmoBandRmse.tif uint8
-harmo.method band
-harmo.cost rmse
VALID --compare-image ${EPSILON_8}
${BASELINE}/apTvMosaicTestSimpleWithHarmoBandRmse.tif
${TEMP}/apTvMosaicTestSimpleWithHarmoBandRmse.tif)
otb_test_application(NAME MosaicTestSimpleWithHarmoRgbRmse
APP Mosaic
OPTIONS -il ${INPUTDATA}/SP67_FR_subset_1.tif ${INPUTDATA}/SP67_FR_subset_2.tif
-out ${TEMP}/apTvMosaicTestSimpleWithHarmoRgbRmse.tif uint8
-harmo.method rgb
-harmo.cost rmse
VALID --compare-image ${EPSILON_8}
${BASELINE}/apTvMosaicTestSimpleWithHarmoRgbRmse.tif
${TEMP}/apTvMosaicTestSimpleWithHarmoRgbRmse.tif)
otb_test_application(NAME MosaicTestSimpleWithCutline
APP Mosaic
OPTIONS -il ${INPUTDATA}/SP67_FR_subset_1.tif ${INPUTDATA}/SP67_FR_subset_2.tif
-out ${TEMP}/apTvMosaicTestSimpleWithCutline.tif uint8
-vdcut ${INPUTDATA}/SP67_FR_subset_1_cutline.shp ${INPUTDATA}/SP67_FR_subset_2_cutline.shp
VALID --compare-image ${EPSILON_8}
${BASELINE}/apTvMosaicTestSimpleWithCutline.tif
${TEMP}/apTvMosaicTestSimpleWithCutline.tif)
otb_test_application(NAME MosaicTestSimpleWithVdstats
APP Mosaic
OPTIONS -il ${INPUTDATA}/SP67_FR_subset_1.tif ${INPUTDATA}/SP67_FR_subset_2.tif
-out ${TEMP}/apTvMosaicTestSimpleWithVdstats.tif uint8
-vdstats ${INPUTDATA}/SP67_FR_subset_1_cutline.shp ${INPUTDATA}/SP67_FR_subset_2_cutline.shp
VALID --compare-image ${EPSILON_8}
${BASELINE}/apTvMosaicTestSimpleWithVdstats.tif
${TEMP}/apTvMosaicTestSimpleWithVdstats.tif)
#
# Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
# Copyright (C) 2019 Institut de Recherche Scientifique et Technique pour
# l'Environnement et l'Agriculture (IRSTEA)
#
# 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.
#
project(OTBMosaic)
otb_module_impl()
/*
* otbMosaicFromDirectoryHandler.h
*
* Created on: 24 mars 2016
* Author: cresson
*/
#ifndef MODULES_REMOTE_OTB_MosaicFromDirectoryHandler_INCLUDE_OTBMosaicFromDirectoryHandler_H_
#define MODULES_REMOTE_OTB_MosaicFromDirectoryHandler_INCLUDE_OTBMosaicFromDirectoryHandler_H_
#include "itkImageSource.h"
#include "itkExceptionObject.h"
#include "itkImageRegion.h"
#include "otbStreamingSimpleMosaicFilter.h"
#include "otbImageFileReader.h"
#include "itkDirectory.h"
#include "otbImageIOBase.h"
#include "otbImageIOFactory.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbGenericRSResampleImageFilter.h"
#include "itkNearestNeighborInterpolateImageFunction.h"
namespace otb
{
/** \class MosaicFromDirectoryHandler
* \brief This ImageSource produces an otb::image from multiple rasters
* stored in the m_Directory.
* TODO: Currently only .tif extension is supported. Might be nice to change it.
*
*
* \ingroup OTBMosaic
*
*/
template <class TOutputImage, class TReferenceImage>
class ITK_EXPORT MosaicFromDirectoryHandler : public itk::ImageSource<TOutputImage>
{
public:
/** Standard class typedefs. */
typedef MosaicFromDirectoryHandler Self;
typedef itk::ImageSource<TOutputImage> Superclass;
typedef itk::SmartPointer<Self> Pointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(MosaicFromDirectoryHandler, ImageSource);
/** Typedefs for output image */
typedef typename TOutputImage::SizeType SizeType;
typedef typename TOutputImage::IndexType IndexType;
typedef typename TOutputImage::SpacingType SpacingType;
typedef typename TOutputImage::PointType PointType;
typedef typename TOutputImage::RegionType ImageRegionType;
typedef typename TOutputImage::InternalPixelType OutputImagePixelType;
/** Typedefs for mosaic filter */
typedef otb::VectorImage<OutputImagePixelType> InternalMaskImageType;
typedef otb::StreamingSimpleMosaicFilter<
InternalMaskImageType> MosaicFilterType;
typedef typename MosaicFilterType::Pointer MosaicFilterPointerType;
/** Typedefs for image reader */
typedef otb::ImageFileReader<InternalMaskImageType> ReaderType;
typedef typename ReaderType::Pointer ReaderPointerType;
/** Typedefs for casting the image */
typedef otb::MultiToMonoChannelExtractROI<
OutputImagePixelType, OutputImagePixelType> CastFilterType;
typedef typename CastFilterType::Pointer CastFilterPointerType;
/** Typedefs for image reprojection */
typedef otb::GenericRSResampleImageFilter<
InternalMaskImageType, InternalMaskImageType> ResamplerType;
typedef typename ResamplerType::Pointer ResamplerPointerType;
typedef itk::NearestNeighborInterpolateImageFunction<
InternalMaskImageType, double> NNInterpolatorType;
/** Input directory accessors */
itkGetMacro(Directory, std::string);
itkSetMacro(Directory, std::string);
/** Output parameters setters */
itkSetMacro(OutputSpacing, SpacingType);
itkSetMacro(OutputSize, SizeType);
itkSetMacro(OutputOrigin, PointType);
void SetReferenceImage(TReferenceImage * ptr){m_RefImagePtr = ptr;}
itkSetMacro(UseReferenceImage, bool);
/** Prepare image allocation at the first call of the pipeline processing */
virtual void GenerateOutputInformation(void);
/** Does the real work. */
virtual void GenerateData();
protected:
MosaicFromDirectoryHandler();
virtual ~MosaicFromDirectoryHandler();
// Masks directory
std::string m_Directory;
// Output parameters
SpacingType m_OutputSpacing;
SizeType m_OutputSize;
PointType m_OutputOrigin;
// Internal filters
MosaicFilterPointerType mosaicFilter;
CastFilterPointerType castFilter;
std::vector<ReaderPointerType> readers;
std::vector<ResamplerPointerType> resamplers;
// Reference image pointer
bool m_UseReferenceImage;
TReferenceImage * m_RefImagePtr;
private:
MosaicFromDirectoryHandler(const Self &); //purposely not implemented
void operator =(const Self&); //purposely not implemented
};
} //namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include <otbMosaicFromDirectoryHandler.txx>
#endif
#endif /* MODULES_REMOTE_OTB_MosaicFromDirectoryHandler_INCLUDE_OTBMosaicFromDirectoryHandler_H_ */
/*
* otbMosaicFromDirectoryHandler.hxx
*
* Created on: 24 mars 2016
* Author: cresson
*/
#ifndef MODULES_REMOTE_OTB_MosaicFromDirectoryHandler_INCLUDE_OTBMosaicFromDirectoryHandler_HXX_
#define MODULES_REMOTE_OTB_MosaicFromDirectoryHandler_INCLUDE_OTBMosaicFromDirectoryHandler_HXX_
#include "otbMosaicFromDirectoryHandler.h"
#include "otbImageFileWriter.h"
namespace otb
{
template <class TOutputImage, class TReferenceImage>
MosaicFromDirectoryHandler<TOutputImage, TReferenceImage>
::MosaicFromDirectoryHandler()
{
mosaicFilter = MosaicFilterType::New();
castFilter = CastFilterType::New();
m_UseReferenceImage = false;
m_RefImagePtr = 0;
}
template <class TOutputImage, class TReferenceImage>
MosaicFromDirectoryHandler<TOutputImage, TReferenceImage>
::~MosaicFromDirectoryHandler()
{
}
template <class TOutputImage, class TReferenceImage>
void
MosaicFromDirectoryHandler<TOutputImage, TReferenceImage>
::GenerateOutputInformation()
{
if (m_Directory[m_Directory.size()-1] != '/')
{
// If not, we add the separator
m_Directory.append("/");
}
// Get the list of files in the directory
itk::Directory::Pointer dir = itk::Directory::New();
if (!dir->Load(m_Directory.c_str()))
{
itkExceptionMacro(<< "Unable to browse directory " << m_Directory);
}
// Instanciate a new mosaic filter
mosaicFilter = MosaicFilterType::New();
mosaicFilter->SetGlobalWarningDisplay(false);
readers.clear();
resamplers.clear();
// Browse the directory
for (unsigned int i = 0; i < dir->GetNumberOfFiles(); i++)
{
const char *filename = dir->GetFile(i);
std::string sfilename(filename);
sfilename = m_Directory + sfilename;
// Try to read the file
otb::ImageIOBase::Pointer imageIO =
otb::ImageIOFactory::CreateImageIO(sfilename.c_str(),otb::ImageIOFactory::ReadMode);
if( imageIO.IsNotNull() )
{
// create reader
ReaderPointerType reader = ReaderType::New();
reader->SetFileName(sfilename);
reader->UpdateOutputInformation();
readers.push_back(reader);
if (m_UseReferenceImage)
{
ResamplerPointerType resampler = ResamplerType::New();
resampler->SetInput(reader->GetOutput());
// Setup transform through projRef and Keywordlist
SpacingType defSpacing = m_RefImagePtr->GetSignedSpacing();
defSpacing[0] *= 10;
defSpacing[1] *= 10;
resampler->SetDisplacementFieldSpacing(defSpacing);
resampler->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist());
resampler->SetInputProjectionRef(reader->GetOutput()->GetProjectionRef());
resampler->SetOutputKeywordList(m_RefImagePtr->GetImageKeywordlist());
resampler->SetOutputProjectionRef(m_RefImagePtr->GetProjectionRef());
resampler->SetOutputOrigin(m_RefImagePtr->GetOrigin());
resampler->SetOutputSpacing(m_RefImagePtr->GetSignedSpacing());
resampler->SetOutputSize(m_RefImagePtr->GetLargestPossibleRegion().GetSize());
resampler->SetOutputStartIndex(m_RefImagePtr->GetLargestPossibleRegion().GetIndex());
typename NNInterpolatorType::Pointer interpolator = NNInterpolatorType::New();
resampler->SetInterpolator(interpolator);
resamplers.push_back(resampler);
mosaicFilter->PushBackInput(resampler->GetOutput());
}
else
{
mosaicFilter->PushBackInput(reader->GetOutput());
}
}
else
{
// itkWarningMacro(<<"Unable to read file " << sfilename);
}
}
if (m_UseReferenceImage)
{
mosaicFilter->SetOutputOrigin(m_RefImagePtr->GetOrigin());
mosaicFilter->SetOutputSpacing(m_RefImagePtr->GetSignedSpacing());
mosaicFilter->SetOutputSize(m_RefImagePtr->GetLargestPossibleRegion().GetSize());
}
else
{
mosaicFilter->SetOutputOrigin(m_OutputOrigin);
mosaicFilter->SetOutputSpacing(m_OutputSpacing);
mosaicFilter->SetOutputSize(m_OutputSize);
}
mosaicFilter->SetAutomaticOutputParametersComputation(false);
castFilter->SetInput(mosaicFilter->GetOutput());
castFilter->GraftOutput( this->GetOutput() );
castFilter->UpdateOutputInformation();
this->GraftOutput( castFilter->GetOutput() );
}
template <class TOutputImage, class TReferenceImage>
void
MosaicFromDirectoryHandler<TOutputImage, TReferenceImage>
::GenerateData()
{
castFilter->GraftOutput( this->GetOutput() );
castFilter->Update();
this->GraftOutput( castFilter->GetOutput() );
}
} // end namespace otb
#endif /* MODULES_REMOTE_OTB_MosaicFromDirectoryHandler_INCLUDE_OTBMosaicFromDirectoryHandler_HXX_ */
/*
* otbMosaicFunctors.h
*
* Created on: 16 août 2017
* Author: cresson
*/
#ifndef MODULES_REMOTE_MOSAIC_INCLUDE_OTBMOSAICFUNCTORS_H_
#define MODULES_REMOTE_MOSAIC_INCLUDE_OTBMOSAICFUNCTORS_H_
#include "vnl/vnl_matrix.h"
#include "vcl_compiler.h"
namespace otb{
namespace Functor{
/**
* \class RGB2LAB Functor
* \brief Base class for converting RGB into LAB color space (Ruderman et al.)
*
* \ingroup OTBMosaic
*/
template< class TInput, class TOutput>
class RGB2LAB
{
public:
RGB2LAB() {
M.set_size(3,3);
M[0][0] = 0.3811; M[0][1] = 0.5783; M[0][2] = 0.0406;
M[1][0] = 0.1967; M[1][1] = 0.7244; M[1][2] = 0.0790;
M[2][0] = 0.0241; M[2][1] = 0.1288; M[2][2] = 0.8531;
D1.set_size(3,3);
D1.fill(0.0);
D1[0][0] = 1.0 / vcl_sqrt(3.0);
D1[1][1] = 1.0 / vcl_sqrt(6.0);
D1[2][2] = 1.0 / vcl_sqrt(2.0);
D2.set_size(3,3);
D2.fill(1.0);
D2[1][2] = -2.0;
D2[2][1] = -1.0;
D2[2][2] = 0.0;
}
~RGB2LAB() {
}
bool operator!=( const RGB2LAB & ) const {
return false;
}
bool operator==( const RGB2LAB & other ) const {
return !(*this != other);
}
inline TOutput operator()( const TInput & A ) const
{
TOutput output;
output.SetSize(3);
if (A[0] == 0 && A[1] == 0 && A[2] == 0)
{
output.Fill(0);
return output;
}
// RGB
vnl_matrix<double> rgb(3,1);
rgb[0][0] = A[0];
rgb[1][0] = A[1];
rgb[2][0] = A[2];
// LMS
vnl_matrix<double> lms(3,1);
lms = M*rgb;
// LMS (log10)
const double log10 = vcl_log(10);
lms[0][0] = vcl_log( lms[0][0] ) / log10;
lms[1][0] = vcl_log( lms[1][0] ) / log10;
lms[2][0] = vcl_log( lms[2][0] ) / log10;
// LAB
vnl_matrix<double> lab(3,1);
lab = D1*(D2*lms);
output[0] = lab[0][0];
output[1] = lab[1][0];
output[2] = lab[2][0];
return output;
}
size_t OutputSize(const std::array<size_t,1> &) const {
return 3;
}
private:
vnl_matrix<double> M;
vnl_matrix<double> D1;
vnl_matrix<double> D2;
};
/**
* \class LAB2RGB Functor
* \brief Base class for converting LAB into RGB color space (Ruderman et al.)
*
* TODO: invert the function RGB2LAB than using the hardcoded one
*
* \ingroup OTBMosaic
*/
template< class TInput, class TOutput>
class LAB2RGB
{
public:
LAB2RGB() {
M.set_size(3,3);
M[0][0] = 4.4687; M[0][1] = -3.5887; M[0][2] = 0.1197;
M[1][0] = -1.2197; M[1][1] = 2.3831; M[1][2] = -0.1626;
M[2][0] = 0.0579; M[2][1] = -0.2584; M[2][2] = 1.1934;
D1.set_size(3,3);
D1.fill(0.0);
D1[0][0] = 1.0 / vcl_sqrt(3.0);
D1[1][1] = 1.0 / vcl_sqrt(6.0);
D1[2][2] = 1.0 / vcl_sqrt(2.0);
D2.set_size(3,3);
D2.fill(1.0);
D2[1][2] = -1.0;
D2[2][1] = -2.0;
D2[2][2] = 0.0;
}
~LAB2RGB() {
}
bool operator!=( const LAB2RGB & ) const
{
return false;
}
bool operator==( const LAB2RGB & other ) const
{
return !(*this != other);
}
inline TOutput operator()( const TInput & A ) const
{
TOutput output;
output.SetSize(3);
if (A[0] == 0 && A[1] == 0 && A[2] == 0)
{
output.Fill(0);
return output;
}
// LAB
vnl_matrix<double> lab(3,1);
lab[0][0] = A[0];
lab[1][0] = A[1];
lab[2][0] = A[2];
// LMS
vnl_matrix<double> lms(3,1);
lms = D2*(D1*lab);
lms[0][0] = vcl_pow(10.0, lms[0][0]);
lms[1][0] = vcl_pow(10.0, lms[1][0]);
lms[2][0] = vcl_pow(10.0, lms[2][0]);
// RGB
vnl_matrix<double> rgb(3,1);
rgb = M*lms;
output[0] = rgb[0][0];
output[1] = rgb[1][0];
output[2] = rgb[2][0];
return output;
}
inline size_t OutputSize(const std::array<size_t,1> &) const {
return 3;
}
private:
vnl_matrix<double> M;
vnl_matrix<double> D1;
vnl_matrix<double> D2;
};
} // namespace functor
} // namespace otb
#endif /* MODULES_REMOTE_MOSAIC_INCLUDE_OTBMOSAICFUNCTORS_H_ */
#ifndef MODULES_REMOTE_MOSAIC_INCLUDE_OTBPERSISTENTMOSAICFILTER_H_
#define MODULES_REMOTE_MOSAIC_INCLUDE_OTBPERSISTENTMOSAICFILTER_H_
#include "otbStreamingMosaicFilterBase.h"
namespace otb
{
/** \class PersistentMosaicFilter
* \brief This filter is the base class for all mosaic filter persisting data through multiple
* update.
* For instance, a filter computing global statistics on an mosaic with streaming
* capabilities will have to keep the temporary results for each streamed piece of the
* image in order to synthesize the global statistics at the end. This filter is an
* itk::ImageToImageFilter, providing two additional methods. The first one, Synthetize(),
* allows the user to synthesize temporary data produced by the multiple updates on different
* pieces of the image to the global result. The second one, Reset(), allows the user to
* reset the temporary data for a new input image for instance.
*
* \note This class contains pure virtual method, and can not be instantiated.
*
* \sa PersistentMosaicFilter
* \sa StreamingStatisticsMosaicFilter
*
* \ingroup OTBMosaic
*/
template <class TInputImage, class TOutputImage, class TPrecisionType>
class ITK_EXPORT PersistentMosaicFilter : public otb::StreamingMosaicFilterBase<TInputImage, TOutputImage, TPrecisionType>
{
public:
/** Standard typedefs */
typedef PersistentMosaicFilter Self;
typedef otb::StreamingMosaicFilterBase<TInputImage, TOutputImage, TPrecisionType> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Creation through object factory macro */
itkTypeMacro(PersistentMosaicFilter, StreamingMosaicFilterBase);
/** Input image typedefs. */
typedef typename Superclass::InputImageType InputImageType;
typedef typename Superclass::InputImagePointer InputImagePointer;
typedef typename Superclass::InputImagePointType InputImagePointType;
typedef typename Superclass::InputImagePixelType InputImagePixelType;
typedef typename Superclass::InputImageIndexType InputImageIndexType;
typedef typename Superclass::InputImageSizeType InputImageSizeType;
typedef typename Superclass::InputImageSpacingType InputImageSpacingType;
typedef typename Superclass::InputImageInternalPixelType InputImageInternalPixelType;
typedef typename Superclass::InputImageRegionType InputImageRegionType;
/** Output image typedefs. */
typedef typename Superclass::OutputImageType OutputImageType;
typedef typename Superclass::OutputImagePointer OutputImagePointer;
typedef typename Superclass::OutputImagePointType OutputImagePointType;
typedef typename Superclass::OutputImagePixelType OutputImagePixelType;
typedef typename Superclass::OutputImageIndexType OutputImageIndexType;
typedef typename Superclass::OutputImageSizeType OutputImageSizeType;
typedef typename Superclass::OutputImageSpacingType OutputImageSpacingType;
typedef typename Superclass::OutputImageInternalPixelType OutputImageInternalPixelType;
typedef typename Superclass::OutputImageRegionType OutputImageRegionType;
/** Internal computing typedef support. */
typedef typename Superclass::InternalValueType InternalValueType;
typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
typedef typename Superclass::InterpolatorType InterpolatorType;
typedef typename Superclass::InterpolatorPointerType InterpolatorPointerType;
typedef typename Superclass::DefaultInterpolatorType DefaultInterpolatorType;
typedef typename Superclass::InternalImageType InternalImageType;
typedef typename Superclass::InternalPixelType InternalPixelType;
typedef typename Superclass::IteratorType IteratorType;
typedef typename Superclass::ConstIteratorType ConstIteratorType;
typedef typename Superclass::StreamingTraitsType StreamingTraitsType;
/**
* Reset the persistent data of the filter.
*/
virtual void Reset(void) = 0;
/**
* Synthesize the persistent data of the filter.
*/
virtual void Synthetize(void) = 0;
protected:
/** Constructor */
PersistentMosaicFilter() {}
/** Destructor */
~PersistentMosaicFilter() ITK_OVERRIDE {}
/**PrintSelf method */
void PrintSelf(std::ostream& os, itk::Indent indent) const ITK_OVERRIDE
{
Superclass::PrintSelf(os, indent);
}
private:
PersistentMosaicFilter(const Self &); //purposely not implemented
void operator =(const Self&); //purposely not implemented
};
} // End namespace otb
#endif /* MODULES_REMOTE_MOSAIC_INCLUDE_OTBPERSISTENTMOSAICFILTER_H_ */