From a40dc8d6f265416ddd8041a1de5c136244e956a3 Mon Sep 17 00:00:00 2001 From: Emmanuel Christophe <emmanuel.christophe@orfeo-toolbox.org> Date: Thu, 6 Dec 2007 17:54:33 +0000 Subject: [PATCH] Pan sharpening --- .../BasicFilters/otbDivideVectorImageFilter.h | 122 ++++++++++++++++ ...bSimpleRcsPanSharpeningFusionImageFilter.h | 117 ++++++++++++++++ ...impleRcsPanSharpeningFusionImageFilter.txx | 131 ++++++++++++++++++ Examples/Fusion/PanSharpeningExample.cxx | 44 ++++++ 4 files changed, 414 insertions(+) create mode 100644 Code/BasicFilters/otbDivideVectorImageFilter.h create mode 100644 Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.h create mode 100644 Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.txx create mode 100644 Examples/Fusion/PanSharpeningExample.cxx diff --git a/Code/BasicFilters/otbDivideVectorImageFilter.h b/Code/BasicFilters/otbDivideVectorImageFilter.h new file mode 100644 index 0000000000..0bca78aa10 --- /dev/null +++ b/Code/BasicFilters/otbDivideVectorImageFilter.h @@ -0,0 +1,122 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Some parts of this code are derived from ITK. See ITKCopyright.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. + +=========================================================================*/ +#ifndef __otbDivideVectorImageFilter_h +#define __otbDivideVectorImageFilter_h + +#include "itkBinaryFunctorImageFilter.h" +#include "itkNumericTraits.h" + +namespace otb +{ + +/** \class DivideVectorImageFilter + * \brief Implements an operator for pixel-wise division of two images. + * + * This class is only a temporary fix to use in otbSimpleRcsPanSharpeningFusionImageFilter. Should be useless after 2007-12-11 + * + * \ingroup IntensityImageFilters Multithreaded + */ + +namespace Function { + +template< class TInput1, class TInput2, class TOutput> +class Div +{ +public: + Div() {}; + ~Div() {}; + bool operator!=( const Div & ) const + { + return false; + } + bool operator==( const Div & other ) const + { + return !(*this != other); + } + inline TOutput operator()( const TInput1 & A, const TInput2 & B) + { +// if(B != (TInput2) 0) + return (TOutput)(A / B); +// else +// return NumericTraits<TOutput>::max(); + } +}; +} + +template <class TInputImage1, class TInputImage2, class TOutputImage> +class ITK_EXPORT DivideVectorImageFilter : + public +itk::BinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage, + Function::Div< + typename TInputImage1::PixelType, + typename TInputImage2::PixelType, + typename TOutputImage::PixelType> > +{ +public: + /** + * Standard "Self" typedef. + */ + typedef DivideVectorImageFilter Self; + + /** + * Standard "Superclass" typedef. + */ + typedef itk::BinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage, + Function::Div< + typename TInputImage1::PixelType, + typename TInputImage2::PixelType, + typename TOutputImage::PixelType> + > Superclass; + + /** + * Smart pointer typedef support + */ + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** + * Method for creation through the object factory. + */ + itkNewMacro(Self); + +#ifdef ITK_USE_CONCEPT_CHECKING + /** Begin concept checking */ + itkConceptMacro(IntConvertibleToInput2Check, + (Concept::Convertible<int, typename TInputImage2::PixelType>)); + itkConceptMacro(Input1Input2OutputDivisionOperatorsCheck, + (Concept::DivisionOperators<typename TInputImage1::PixelType, + typename TInputImage2::PixelType, + typename TOutputImage::PixelType>)); + /** End concept checking */ +#endif + +protected: + DivideVectorImageFilter() {} + virtual ~DivideVectorImageFilter() {} + DivideVectorImageFilter(const Self&) {} + void operator=(const Self&) {} + +}; + +} // end namespace otb + + +#endif diff --git a/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.h b/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.h new file mode 100644 index 0000000000..60ccfce77f --- /dev/null +++ b/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.h @@ -0,0 +1,117 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Some parts of this code are derived from ITK. See ITKCopyright.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. + +=========================================================================*/ +#ifndef __otbSimpleRcsPanSharpeningFusionImageFilter_h +#define __otbSimpleRcsPanSharpeningFusionImageFilter_h + +#include "itkImageToImageFilter.h" +#include "itkMeanImageFilter.h" +// #include "itkDivideImageFilter.h" +#include "otbDivideVectorImageFilter.h"//TODO to correct after the fix from ITK +#include "itkMultiplyImageFilter.h" + +namespace otb { + /** + * \class SimpleRcsPanSharpeningFusionImageFilter + * \brief This class performs a simple Pan sharpening operation + * + * Given a Pan image and the corresponding Xs image (oversampled to have the + * same number of pixels), this filter realizes a simple Pan sharpening + * operation: + * + * \f[ \frac{XS}{\mathrm{Filtered}(PAN)} PAN \f] + * + * + * + **/ + + template <class TPanImageType,class TXsImageType,class TOutputImageType> +class ITK_EXPORT SimpleRcsPanSharpeningFusionImageFilter : + public itk::ImageToImageFilter<TPanImageType, TOutputImageType> + { + public: + typedef SimpleRcsPanSharpeningFusionImageFilter Self; + typedef itk::ImageToImageFilter + <TPanImageType, TOutputImageType> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + typedef otb::Image<double,2> InternalImageType; + typedef otb::VectorImage<double> InternalVectorImageType; + + + /** Method for creation through object factory */ + itkNewMacro(Self); + + /** Run-time type information */ + itkTypeMacro(SimpleRcsPanSharpeningFusionImageFilter, + itk::ImageToImageFilter); + + /** Display */ + void PrintSelf( std::ostream& os, itk::Indent indent ) const; + + typedef typename InternalImageType::SizeType RadiusType; + + itkGetMacro( Radius, RadiusType); + itkSetMacro( Radius, RadiusType); + + virtual void SetPanInput( const TPanImageType * image); + const TPanImageType * GetPanInput(void); + + virtual void SetXsInput( const TXsImageType * path); + const TXsImageType * GetXsInput(void); + + protected: + + SimpleRcsPanSharpeningFusionImageFilter(); + + typedef itk::MeanImageFilter + <TPanImageType, InternalImageType> MeanFilterType; + typedef otb::DivideVectorImageFilter + <InternalVectorImageType,InternalImageType, + InternalVectorImageType> DivideFilterType; + typedef itk::MultiplyImageFilter + <InternalVectorImageType,TPanImageType,TOutputImageType> MultiplyFilterType; + + +// Software Guide : EndCodeSnippet + + void GenerateData(); + + private: + + SimpleRcsPanSharpeningFusionImageFilter(Self&); // intentionally not implemented + void operator=(const Self&); // intentionally not implemented + + typename MeanFilterType::Pointer m_MeanFilter; + typename DivideFilterType::Pointer m_DivideFilter; + typename MultiplyFilterType::Pointer m_MultiplyFilter; + + RadiusType m_Radius; + + }; + +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbSimpleRcsPanSharpeningFusionImageFilter.txx" +#endif + +#endif + diff --git a/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.txx b/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.txx new file mode 100644 index 0000000000..a0cba29c98 --- /dev/null +++ b/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.txx @@ -0,0 +1,131 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Some parts of this code are derived from ITK. See ITKCopyright.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. + +=========================================================================*/ +#ifndef __otbSimpleRcsPanSharpeningFusionImageFilter_txx +#define __otbSimpleRcsPanSharpeningFusionImageFilter_txx + +#include "otbSimpleRcsPanSharpeningFusionImageFilter.h" + + +namespace otb +{ + template <class TPanImageType, class TXsImageType, class TOutputImageType> + SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType> + ::SimpleRcsPanSharpeningFusionImageFilter() + { + this->SetNumberOfRequiredInputs(2); + m_MeanFilter = MeanFilterType::New(); + m_DivideFilter = DivideFilterType::New(); + m_MultiplyFilter = MultiplyFilterType::New(); + + m_Radius[0]=3; + m_Radius[1]=3; + m_MeanFilter->SetRadius(m_Radius); + + m_DivideFilter->SetInput2(m_MeanFilter->GetOutput()); + m_MultiplyFilter->SetInput1(m_DivideFilter->GetOutput()); + + } + + template <class TPanImageType, class TXsImageType, class TOutputImageType> + void + SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType> + ::SetPanInput(const TPanImageType *image) + { + // We have 2 inputs: an image and a vector image + + // Process object is not const-correct so the const_cast is required here + this->itk::ProcessObject::SetNthInput(0, + const_cast< TPanImageType* >( image ) ); + this->Modified(); + } + + template <class TPanImageType, class TXsImageType, class TOutputImageType> + const TPanImageType * + SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType> + ::GetPanInput(void) + { + if (this->GetNumberOfInputs() < 1) + { + return 0; + } + + return static_cast<const TPanImageType * > + (this->itk::ProcessObject::GetInput(0) ); + } + + template <class TPanImageType, class TXsImageType, class TOutputImageType> + void + SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType> + ::SetXsInput(const TXsImageType *image) + { + // We have 2 inputs: an image and a vector image + + // Process object is not const-correct so the const_cast is required here + this->itk::ProcessObject::SetNthInput(1, + const_cast< TXsImageType* >( image ) ); + this->Modified(); + } + + template <class TPanImageType, class TXsImageType, class TOutputImageType> + const TXsImageType * + SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType> + ::GetXsInput(void) + { + if (this->GetNumberOfInputs() < 2) + { + return 0; + } + + return static_cast<const TXsImageType * > + (this->itk::ProcessObject::GetInput(1) ); + } + + + template <class TPanImageType,class TXsImageType,class TOutputImageType> + void + SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType> + ::GenerateData() + { + m_MeanFilter->SetInput( this->GetPanInput() ); + m_DivideFilter->SetInput1(this->GetXsInput()); + + m_MultiplyFilter->SetInput2(this->GetPanInput()); + + m_MultiplyFilter->GraftOutput( this->GetOutput() ); + m_MultiplyFilter->Update(); + this->GraftOutput( m_MultiplyFilter->GetOutput() ); + } + + template <class TPanImageType,class TXsImageType,class TOutputImageType> + void + SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType> + ::PrintSelf( std::ostream& os, itk::Indent indent ) const + { + Superclass::PrintSelf(os,indent); + + os + << indent << "Radius:" << this->m_Radius + << std::endl; + } + +} // end namespace otb + +#endif diff --git a/Examples/Fusion/PanSharpeningExample.cxx b/Examples/Fusion/PanSharpeningExample.cxx new file mode 100644 index 0000000000..2deca33348 --- /dev/null +++ b/Examples/Fusion/PanSharpeningExample.cxx @@ -0,0 +1,44 @@ + +#include "otbImage.h" +#include "otbVectorImage.h" +#include "otbImageFileReader.h" +#include "otbStreamingImageFileWriter.h" +#include "otbSimpleRcsPanSharpeningFusionImageFilter.h" + + +int main( int argc, char* argv[] ) +{ + typedef otb::Image<double, 2> ImageType; + typedef otb::VectorImage<double, 2> VectorImageType; + typedef otb::ImageFileReader<ImageType> ReaderType; + typedef otb::ImageFileReader<VectorImageType> ReaderVectorType; + + typedef otb::VectorImage<unsigned int, 2> VectorIntImageType; + + + + ReaderVectorType::Pointer readerXS=ReaderVectorType::New(); + ReaderType::Pointer readerPAN=ReaderType::New(); + + + readerPAN->SetFileName(argv[1]); + readerXS->SetFileName(argv[2]); + + typedef otb::SimpleRcsPanSharpeningFusionImageFilter + <ImageType,VectorImageType,VectorIntImageType> FusionFilterType; + FusionFilterType::Pointer fusion = FusionFilterType::New(); + fusion->SetPanInput(readerPAN->GetOutput()); + fusion->SetXsInput(readerXS->GetOutput()); + + + typedef otb::StreamingImageFileWriter<VectorIntImageType> WriterType; + WriterType::Pointer writer=WriterType::New(); + writer->SetFileName(argv[3]); + writer->SetInput(fusion->GetOutput()); + writer->Update(); + + return 0; + +} + + -- GitLab