diff --git a/Code/MultiScale/otbHaarOperator.h b/Code/MultiScale/otbHaarOperator.h index 05c31e46ef186c4e167c8c325512c532e8119ef4..bec642a77eec4b94a7978506436b2089a19ce6cf 100644 --- a/Code/MultiScale/otbHaarOperator.h +++ b/Code/MultiScale/otbHaarOperator.h @@ -20,8 +20,7 @@ #ifndef __otbHaarOperator__h #define __otbHaarOperator__h -#include "itkExceptionObject.h" -#include "itkNeighborhoodOperator.h" +#include "otbWaveletOperator.h" namespace otb { @@ -31,11 +30,12 @@ namespace otb { * \brief A NeighborhoodOperator for performing a Haar based filtering * at a pixel location. * - * LowPassHaarOperator is a NeighborhoodOperator that should be applied a + * LowPassHaarOperator is a NeighborhoodOperator that should be applied to a * NeighborhoodIterator using the NeighborhoodInnerProduct method. * The Haar Operator is defiend in 1D as \$ H(z) = ( 1 + z^{-1} ) / 2 \$. * In N dimensions, the operator is directional * + * \sa WaveletOperator * \sa NeighborhoodOperator * \sa Neighborhood * \sa ForwardDifferenceOperator @@ -46,23 +46,23 @@ namespace otb { template<class TPixel, unsigned int VDimension, class TAllocator = itk::NeighborhoodAllocator< TPixel > > class ITK_EXPORT LowPassHaarOperator - : public itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> + : public WaveletOperator<TPixel, VDimension, TAllocator> { public: /** Standard typedefs */ typedef LowPassHaarOperator Self; - typedef itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> Superclass; + typedef WaveletOperator<TPixel, VDimension, TAllocator> Superclass; - itkTypeMacro(LowPassHaarOperator, NeighborhoodOperator); + itkTypeMacro(LowPassHaarOperator, WaveletOperator); - LowPassHaarOperator() + LowPassHaarOperator() : WaveletOperator () { this->SetRadius(1); this->CreateToRadius(1); } LowPassHaarOperator(const Self& other) - : itk::NeighborhoodOperator<TPixel, VDimension, TAllocator>(other) + : WaveletOperator<TPixel, VDimension, TAllocator>(other) { /* ... */ } @@ -98,11 +98,14 @@ protected: CoefficientVector GenerateCoefficients() { CoefficientVector coeff; + // stands for z^{-1} + coeff.push_back(0.5); + // stands for z^0 + coeff.push_back(0.5); + // stands for z^1 coeff.push_back(0.0); - coeff.push_back(0.5); - coeff.push_back(0.5); - return coeff; + return Superclass::UpSamplingCoefficients( coeff ); } /** Arranges coefficients spatially in the memory buffer. */ @@ -120,9 +123,10 @@ protected: * * HighPassHaarOperator is a NeighborhoodOperator that should be applied a * NeighborhoodIterator using the NeighborhoodInnerProduct method. - * The Haar Operator is defiend in 1D as \$ G(z) = ( 1 + z^{-1} ) / 2 \$. + * The Haar Operator is defiend in 1D as \$ G(z) = ( 1 - z^{-1} ) / 2 \$. * In N dimensions, the operator is directional * + * \sa WaveletOperator * \sa NeighborhoodOperator * \sa Neighborhood * \sa ForwardDifferenceOperator @@ -133,14 +137,14 @@ protected: template<class TPixel, unsigned int VDimension, class TAllocator = itk::NeighborhoodAllocator< TPixel > > class ITK_EXPORT HighPassHaarOperator - : public itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> + : public WaveletOperator<TPixel, VDimension, TAllocator> { public: /** Standard typedefs */ typedef HighPassHaarOperator Self; - typedef itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> Superclass; + typedef WaveletOperator<TPixel, VDimension, TAllocator> Superclass; - itkTypeMacro(HighPassHaarOperator, NeighborhoodOperator); + itkTypeMacro(HighPassHaarOperator, WaveletOperator); HighPassHaarOperator() { @@ -149,7 +153,7 @@ public: } HighPassHaarOperator(const Self& other) - : itk::NeighborhoodOperator<TPixel, VDimension, TAllocator>(other) + : WaveletOperator<TPixel, VDimension, TAllocator>(other) { /* ... */ } @@ -185,11 +189,11 @@ protected: CoefficientVector GenerateCoefficients() { CoefficientVector coeff; - coeff.push_back(0.0); - coeff.push_back(0.5); coeff.push_back(-0.5); + coeff.push_back(0.5); + coeff.push_back(0.0); - return coeff; + return Superclass::UpSamplingCoefficients( coeff ); } /** Arranges coefficients spatially in the memory buffer. */ diff --git a/Code/MultiScale/otbWaveletOperator.h b/Code/MultiScale/otbWaveletOperator.h new file mode 100644 index 0000000000000000000000000000000000000000..476a3bce2ea47953354b3995a71d96329b0676c3 --- /dev/null +++ b/Code/MultiScale/otbWaveletOperator.h @@ -0,0 +1,147 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Copyright (c) Institut Telecom / Telecom Bretagne. All rights reserved. + See ITCopyright.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 __otbWaveletOperator__h +#define __otbWaveletOperator__h + +#include "itkExceptionObject.h" +#include "itkNeighborhoodOperator.h" + +namespace otb { + +/** + * \class WaveletOperator + * + * \brief A NeighborhoodOperator wavelet base class + * + * This class is the mother class for any wavelet operator that requires + * "a-trou" approach for shift-invariant wavelet transform. This class has + * to be derived, it cannot be used directly. + * + * Any wavelet operator that inherits from WaveletOperator is to be used + * as a NeighborhoodOperator that should be applied to a + * NeighborhoodIterator using the NeighborhoodInnerProduct method. + * + * It is assumed that any wavelet is directional. + * + * Set the level of up-sampling though SetUpSampleFactor() before calling + * CreateDirectional(). Each class that inherits from WaveletOperator has + * to re-implement GenerateCoefficients(). It has to end by: + * return this->UpSamplingCoefficients( coeff ) to perform the up-sampling + * + * \sa LowPassHaarOperator + * \sa HighPassHaarOperator + * \sa NeighborhoodOperator + * \sa Neighborhood + * + * \ingroup Operators + */ +template<class TPixel, unsigned int VDimension, + class TAllocator = itk::NeighborhoodAllocator< TPixel > > +class ITK_EXPORT WaveletOperator + : public itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> +{ +public: + /** Standard typedefs */ + typedef WaveletOperator Self; + typedef itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> Superclass; + + itkTypeMacro(WaveletOperator,NeighborhoodOperator); + + /** Construction */ + WaveletOperator() + { + m_UpSampleFactor = 0; + } + /** Construction by copy */ + WaveletOperator( const Self & other ) + : itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> (other) + { + m_UpsampleFactor = other.GetUpSampleFactor(); + } + virtual ~WaveletOperator() {} + + /** Assignment operator */ + Self &operator=(const Self& other) + { + Superclass::operator=(other); + m_UpSampleFactor = other.GetUpSampleFactor(); + return *this; + } + /** + * Prints some debugging information + */ + virtual void PrintSelf(std::ostream &os, itk::Indent i) const + { + Superclass::PrintSelf(os, i.GetNextIndent()); + os << i << "Up-Sampling factor " << this->m_UpSampleFactor << "\n"; + } + + /** + * Set/Get the level of up sampling of the filter + */ + itkGetMacro(UpSampleFactor,unsigned int); + itkSetMacro(UpSampleFactor,unsigned int); + + protected: + /** + * Typedef support for coefficient vector type. Necessary to + * work around compiler bug on VC++. + */ + typedef typename Superclass::CoefficientVector CoefficientVector; + typedef typename Superclass::PixelType PixelType; + + /** + * Perform the "a-trou" algorithm for shift-invariant transformation. + * It transforms the filter \$ H(z) \$ into \$ H(z^2) \$. + */ + CoefficientVector UpSamplingCoefficients ( CoefficientVector & coeff ) + { + if ( m_UpsampleFactor == 0 ) + return coeff; + + for ( unsigned int up = 0; up < m_UpsampleFactor; ++up ) + { + this->SetRadius( 2*this->GetRadius() ); + this->CreateToRadius( this->GetRadius() ); + + CoefficientVector upSampledCoeff; + upSampledCoeff.push_back( coeff[0] ); + for ( unsigned int i = 1; i < coeff.size(); ++i ) + { + upSampledCoeff.push_back( 0.0 ); + upSampledCoeff.push_back( coeff[i] ); + } + coeff = upSampledCoeff; + } + + return coeff; + } + + + + unsigned int m_UpSampleFactor; +}; + +#endif + + + + + diff --git a/Code/MultiScale/otb_9_7_Operator.h b/Code/MultiScale/otb_9_7_Operator.h index 956804da997b79b0822ad0edb7d4ef75da1f09d3..d1bb21d52c36a0b8903eafc4ffad43b908ee8422 100644 --- a/Code/MultiScale/otb_9_7_Operator.h +++ b/Code/MultiScale/otb_9_7_Operator.h @@ -20,8 +20,7 @@ #ifndef __otb_9_7_Operator__h #define __otb_9_7_Operator__h -#include "itkExceptionObject.h" -#include "itkNeighborhoodOperator.h" +#include "otbWaveletOperator.h" namespace otb { @@ -40,6 +39,7 @@ namespace otb { * * In N dimensions, the operator is directional * + * \sa WaveletOperator * \sa NeighborhoodOperator * \sa Neighborhood * \sa ForwardDifferenceOperator @@ -50,14 +50,14 @@ namespace otb { template<class TPixel, unsigned int VDimension, class TAllocator = itk::NeighborhoodAllocator< TPixel > > class ITK_EXPORT LowPass_9_7_Operator - : public itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> + : public WaveletOperator<TPixel, VDimension, TAllocator> { public: /** Standard typedefs */ typedef LowPass_9_7_Operator Self; - typedef itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> Superclass; + typedef WaveletOperator<TPixel, VDimension, TAllocator> Superclass; - itkTypeMacro(LowPass_9_7_Operator, NeighborhoodOperator); + itkTypeMacro(LowPass_9_7_Operator, WaveletOperator); LowPass_9_7_Operator() { @@ -66,7 +66,7 @@ public: } LowPass_9_7_Operator(const Self& other) - : itk::NeighborhoodOperator<TPixel, VDimension, TAllocator>(other) + : WaveletOperator<TPixel, VDimension, TAllocator>(other) { /* ... */ } @@ -112,7 +112,7 @@ protected: coeff.push_back(-0.016864118443); coeff.push_back( 0.026748757411); - return coeff; + return Superclass::UpSamplingCoefficients( coeff ); } /** Arranges coefficients spatially in the memory buffer. */ @@ -136,6 +136,7 @@ protected: * * In N dimensions, the operator is directional * + * \sa WaveletOperator * \sa NeighborhoodOperator * \sa Neighborhood * \sa ForwardDifferenceOperator @@ -146,14 +147,14 @@ protected: template<class TPixel, unsigned int VDimension, class TAllocator = itk::NeighborhoodAllocator< TPixel > > class ITK_EXPORT HighPass_9_7_Operator - : public itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> + : public WaveletOperator<TPixel, VDimension, TAllocator> { public: /** Standard typedefs */ typedef HighPass_9_7_Operator Self; - typedef itk::NeighborhoodOperator<TPixel, VDimension, TAllocator> Superclass; + typedef WaveletOperator<TPixel, VDimension, TAllocator> Superclass; - itkTypeMacro(HighPass_9_7_Operator, NeighborhoodOperator); + itkTypeMacro(HighPass_9_7_Operator, WaveletOperator); HighPass_9_7_Operator() { @@ -162,7 +163,7 @@ public: } HighPass_9_7_Operator(const Self& other) - : itk::NeighborhoodOperator<TPixel, VDimension, TAllocator>(other) + : WaveletOperator<TPixel, VDimension, TAllocator>(other) { /* ... */ } @@ -206,7 +207,7 @@ protected: coeff.push_back(-0.028771763114 ); coeff.push_back( 0.045635881557 ); - return coeff; + return Superclass::UpSamplingCoefficients( coeff ); } /** Arranges coefficients spatially in the memory buffer. */