Commit 6c5948b9 authored by Gregoire Mercier's avatar Gregoire Mercier
Browse files

ENH: wavelet transform series

parent e424060e
/*=========================================================================
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 __otbHaarOperator_h
#define __otbHaarOperator_h
#include "otbWaveletOperator.h"
namespace otb {
/**
* \class LowPassHaarOperator
*
* \brief <b>EXPERIMENTAL FEATURE</b> A NeighborhoodOperator for performing a Haar based filtering
* at a pixel location.
*
* LowPassHaarOperator is a NeighborhoodOperator that should be applied to a
* NeighborhoodIterator using the NeighborhoodInnerProduct method.
* The Haar Operator is defiend in 1D as \f$ H(z) = ( 1 + z^{-1} ) / 2 \f$.
* In N dimensions, the operator is directional
*
* \sa WaveletOperator
* \sa NeighborhoodOperator
* \sa Neighborhood
* \sa ForwardDifferenceOperator
* \sa BackwardDifferenceOperator
*
* \ingroup Operators
*/
template < InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension,
class TAllocator = itk::NeighborhoodAllocator< TPixel > >
class ITK_EXPORT LowPassHaarOperator
: public WaveletOperator<TPixel, VDimension, TAllocator>
{
public:
/** Standard typedefs */
typedef LowPassHaarOperator Self;
typedef WaveletOperator<TPixel, VDimension, TAllocator> Superclass;
itkTypeMacro(LowPassHaarOperator, WaveletOperator);
typedef InverseOrForwardTransformationEnum DirectionOfTransformationEnumType;
itkStaticConstMacro(DirectionOfTransformation,DirectionOfTransformationEnumType,TDirectionOfTransformation);
LowPassHaarOperator()
{
this->SetRadius(1);
this->CreateToRadius(1);
this->SetWavelet( "Haar" );
}
LowPassHaarOperator(const Self& other)
: WaveletOperator<TPixel, VDimension, TAllocator>(other)
{
this->SetWavelet( "Haar" );
}
/**
* Assignment operator
*/
Self &operator=(const Self& other)
{
Superclass::operator=(other);
return *this;
}
/**
* Prints some debugging information
*/
virtual void PrintSelf(std::ostream &os, itk::Indent i) const
{
Superclass::PrintSelf(os, i.GetNextIndent());
os << i << "LowPassHaarOperator {this=" << this << "}" << std::endl;
}
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;
/**
* Set operator coefficients.
*/
CoefficientVector GenerateCoefficients()
{
// FIXME sqrt(2)
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);
#if 0
std::cerr << "Coeff H(" << this->GetWavelet();
if ( (int) DirectionOfTransformation == (int) FORWARD )
std::cerr << " Forward ) = ";
else
std::cerr << " Inverse ) = ";
for ( typename CoefficientVector::const_iterator iter = coeff.begin(); iter < coeff.end(); ++iter )
std::cerr << *iter << " ";
std::cerr << "\n";
#endif
return Superclass::UpSamplingCoefficients( coeff );
}
/** Arranges coefficients spatially in the memory buffer. */
void Fill(const CoefficientVector& coeff)
{
this->FillCenteredDirectional(coeff);
}
};
/**
* \class HighPassHaarOperator
*
* \brief A NeighborhoodOperator for performing a Haar based filtering
* at a pixel location.
*
* HighPassHaarOperator is a NeighborhoodOperator that should be applied a
* NeighborhoodIterator using the NeighborhoodInnerProduct method.
* The Haar Operator is defiend in 1D as \f$ G(z) = ( 1 - z^{-1} ) / 2 \f$.
* In N dimensions, the operator is directional
*
* \sa WaveletOperator
* \sa NeighborhoodOperator
* \sa Neighborhood
* \sa ForwardDifferenceOperator
* \sa BackwardDifferenceOperator
*
* \ingroup Operators
*/
template< InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension,
class TAllocator = itk::NeighborhoodAllocator< TPixel > >
class ITK_EXPORT HighPassHaarOperator
: public WaveletOperator<TPixel, VDimension, TAllocator>
{
public:
/** Standard typedefs */
typedef HighPassHaarOperator Self;
typedef WaveletOperator<TPixel, VDimension, TAllocator> Superclass;
itkTypeMacro(HighPassHaarOperator, WaveletOperator);
typedef InverseOrForwardTransformationEnum DirectionOfTransformationEnumType;
itkStaticConstMacro(DirectionOfTransformation,DirectionOfTransformationEnumType,TDirectionOfTransformation);
HighPassHaarOperator()
{
this->SetRadius(1);
this->CreateToRadius(1);
this->SetWavelet( "Haar" );
}
HighPassHaarOperator(const Self& other)
: WaveletOperator<TPixel, VDimension, TAllocator>(other)
{
this->SetWavelet( "Haar" );
}
/**
* Assignment operator
*/
Self &operator=(const Self& other)
{
Superclass::operator=(other);
return *this;
}
/**
* Prints some debugging information
*/
virtual void PrintSelf(std::ostream &os, itk::Indent i) const
{
Superclass::PrintSelf(os, i.GetNextIndent());
os << i << "HighPassHaarOperator {this=" << this << "}" << std::endl;
}
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;
/**
* Set operator coefficients.
* Due to the number of template parameter, we cannot specialized it with regard
* to the TDirectionOfTransformation value...
*/
CoefficientVector GenerateCoefficients()
{
CoefficientVector coeff;
typedef LowPassHaarOperator< FORWARD, TPixel, VDimension, TAllocator >
LowPassOperatorType;
LowPassOperatorType lowPassOperator;
lowPassOperator.SetDirection(0);
lowPassOperator.CreateDirectional();
CoefficientVector lowPassCoeff;
lowPassCoeff.resize( lowPassOperator.GetSize()[0] );
for ( typename LowPassOperatorType::ConstIterator iter = lowPassOperator.Begin();
iter != lowPassOperator.End(); ++iter )
lowPassCoeff.push_back( *iter );
switch ( DirectionOfTransformation )
{
case FORWARD:
coeff = this->GetHighPassFilterFromLowPassFilter( lowPassCoeff );
break;
case INVERSE:
coeff = this->GetInverseHighPassFilterFromForwardLowPassFilter( lowPassCoeff );
break;
default:
itkExceptionMacro(<<"Wavelet operator has to be INVERSE or FORWARD only!!");
break;
}
#if 0
std::cerr << "Coeff G(" << this->GetWavelet();
if ( (int) DirectionOfTransformation == (int) FORWARD )
std::cerr << " Forward ) = ";
else
std::cerr << " Inverse ) = ";
for ( typename CoefficientVector::const_iterator iter = coeff.begin(); iter < coeff.end(); ++iter )
std::cerr << *iter << " ";
std::cerr << "\n";
#endif
return Superclass::UpSamplingCoefficients( coeff );
}
/** Arranges coefficients spatially in the memory buffer. */
void Fill(const CoefficientVector& coeff)
{
this->FillCenteredDirectional(coeff);
}
};
} // end of namespace otb
#endif
/*=========================================================================
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 __otbSplieBiOrthogonalOperator_h
#define __otbSplieBiOrthogonalOperator_h
#include "itkMacro.h"
#include "itkExceptionObject.h"
#include "otbWaveletOperator.h"
namespace otb {
/**
* \class LowPassSplineBiOrthogonalOperator
*
* \brief <b>EXPERIMENTAL FEATURE</b> A NeighborhoodOperator for performing a Spline Bi-Orthogonal-based filtering
* at a pixel location.
*
* It may be configure with many filter orders. AT present time, so-called "9/7" filter is
* implemented. It may be fixed with SetWavelet method
*
* The LowPassSplineBiOrthogonalOperator is a NeighborhoodOperator that should be applied a
* NeighborhoodIterator using the NeighborhoodInnerProduct method.
* The 9/7 Operator is defiend in 1D as
* \f$ H(z) = 0.026748757411 z^{-4} -0.016864118443 z^{-3} -0.078223266529 z^{-2}
* + 0.266864118443 z^{-1} + 0.602949018236 + 0.266864118443 z
* -0.078223266529 z^2 -0.016864118443 z^3 + 0.026748757411 z^4 \f$.
*
* In N dimensions, the operator is directional
*
* \sa WaveletOperator
* \sa NeighborhoodOperator
* \sa Neighborhood
* \sa ForwardDifferenceOperator
* \sa BackwardDifferenceOperator
*
* \ingroup Operators
*/
template < InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension,
class TAllocator = itk::NeighborhoodAllocator< TPixel > >
class ITK_EXPORT LowPassSplineBiOrthogonalOperator
: public WaveletOperator<TPixel, VDimension, TAllocator>
{
public:
/** Standard typedefs */
typedef LowPassSplineBiOrthogonalOperator Self;
typedef WaveletOperator<TPixel, VDimension, TAllocator> Superclass;
itkTypeMacro(LowPassSplineBiOrthogonalOperator, WaveletOperator);
typedef InverseOrForwardTransformationEnum DirectionOfTransformationEnumType;
itkStaticConstMacro(DirectionOfTransformation,DirectionOfTransformationEnumType,TDirectionOfTransformation);
LowPassSplineBiOrthogonalOperator();
LowPassSplineBiOrthogonalOperator(const Self& other);
/**
* Assignment operator
*/
Self &operator=(const Self& other);
/**
* Prints some debugging information
*/
virtual void PrintSelf(std::ostream &os, itk::Indent i) const;
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;
/**
* Set operator coefficients.
*/
CoefficientVector GenerateCoefficients();
/** Arranges coefficients spatially in the memory buffer. */
void Fill(const CoefficientVector& coeff);
};
/**
* \class HighPassSplineBiOrthogonalOperator
*
* \brief A NeighborhoodOperator for performing a Spline Bi-Orthogonal-based filtering
* at a pixel location.
*
* HighPassSplineBiOrthogonalOperator is a NeighborhoodOperator that should be applied a
* NeighborhoodIterator using the NeighborhoodInnerProduct method.
* The 9/7 Operator is defiend in 1D as
* \f$ H(z) = 0.045635881557 z^{-3} -0.028771763114 z^{-2} -0.295635881557 z^{-1}
* + 0.557543526229 - 0.295635881557 z -0.028771763114 z^2 + 0.045635881557 z^3 \f$.
*
* In N dimensions, the operator is directional
*
* \sa WaveletOperator
* \sa NeighborhoodOperator
* \sa Neighborhood
* \sa ForwardDifferenceOperator
* \sa BackwardDifferenceOperator
*
* \ingroup Operators
*/
template < InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension,
class TAllocator = itk::NeighborhoodAllocator< TPixel > >
class ITK_EXPORT HighPassSplineBiOrthogonalOperator
: public WaveletOperator<TPixel, VDimension, TAllocator>
{
public:
/** Standard typedefs */
typedef HighPassSplineBiOrthogonalOperator Self;
typedef WaveletOperator<TPixel, VDimension, TAllocator> Superclass;
itkTypeMacro(HighPassSplineBiOrthogonalOperator, WaveletOperator);
typedef InverseOrForwardTransformationEnum DirectionOfTransformationEnumType;
itkStaticConstMacro(DirectionOfTransformation,DirectionOfTransformationEnumType,TDirectionOfTransformation);
HighPassSplineBiOrthogonalOperator ();
HighPassSplineBiOrthogonalOperator(const Self& other);
/**
* Assignment operator
*/
Self &operator=(const Self& other);
/**
* Prints some debugging information
*/
virtual void PrintSelf(std::ostream &os, itk::Indent i) const;
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;
/**
* Set operator coefficients.
*/
CoefficientVector GenerateCoefficients();
/** Arranges coefficients spatially in the memory buffer. */
void Fill(const CoefficientVector& coeff);
};
} // end of namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbSplineBiOrthogonalOperator.txx"
#endif
#endif
/*=========================================================================
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 __otbSplieBiOrthogonalOperator_txx
#define __otbSplieBiOrthogonalOperator_txx
#include "otbSplineBiOrthogonalOperator.h"
namespace otb {
template < InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension, class TAllocator >
LowPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator >
::LowPassSplineBiOrthogonalOperator()
{
this->SetWavelet( "9/7" );
switch ( DirectionOfTransformation )
{
case FORWARD:
this->SetRadius(4);
this->CreateToRadius(4);
break;
case INVERSE:
this->SetRadius(3);
this->CreateToRadius(3);
break;
default:
itkExceptionMacro(<<"Spline BiOrthogonal Wavelet operator has to be INVERSE or FORWARD only!!");
break;
}
}
template < InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension, class TAllocator >
LowPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator >
::LowPassSplineBiOrthogonalOperator
( const LowPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator > & other )
: WaveletOperator<TPixel, VDimension, TAllocator>(other)
{
this->SetWavelet( "9/7" );
}
template < InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension, class TAllocator >
LowPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator > &
LowPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator >
::operator=
( const LowPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator > & other )
{
Superclass::operator=(other);
return *this;
}
template < InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension, class TAllocator >
void
LowPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator >
::PrintSelf ( std::ostream &os, itk::Indent i ) const
{
Superclass::PrintSelf(os, i.GetNextIndent());
os << i << "LowPassSplineBiOrthogonalOperator {this=" << this << "}" << std::endl;
}
template < InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension, class TAllocator >
typename LowPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator >::CoefficientVector
LowPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator >
::GenerateCoefficients ()
{
CoefficientVector coeff;
if ( !strcmp( this->GetWavelet(), "9/7" ) )
{
switch ( DirectionOfTransformation )
{
case FORWARD:
{
coeff.push_back( 0.026748757411);
coeff.push_back(-0.016864118443);
coeff.push_back(-0.078223266529);
coeff.push_back( 0.266864118443);
coeff.push_back( 0.602949018236);
coeff.push_back( 0.266864118443);
coeff.push_back(-0.078223266529);
coeff.push_back(-0.016864118443);
coeff.push_back( 0.026748757411);
break;
}
case INVERSE:
{
typedef HighPassSplineBiOrthogonalOperator< FORWARD, TPixel, VDimension, TAllocator >
HighPassOperatorType;
HighPassOperatorType highPassOperator;
highPassOperator.SetDirection( 0 );
highPassOperator.CreateDirectional();
CoefficientVector highPassCoeff;
highPassCoeff.resize( highPassOperator.GetSize()[0] );
for ( typename HighPassOperatorType::ConstIterator iter = highPassOperator.Begin();
iter != highPassOperator.End(); ++iter )
highPassCoeff.push_back( *iter );
coeff = this->GetInverseLowPassFilterFromForwardHighPassFilter( highPassCoeff );
break;
}
default:
{
itkExceptionMacro(<<"Spline BiOrthogonal Wavelet operator has to be INVERSE or FORWARD only!!");
break;
}
}
}
/**
* There is no 'else'.
* Actually, we do nothing since Wavelet() != "9/7" corresponds to the first calls of
* GenerateCoefficients from the constructors
*/
#if 0
std::cerr << "Coeff H(" << this->GetWavelet();
if ( (int) DirectionOfTransformation == (int) FORWARD )
std::cerr << " Forward ) = ";
else
std::cerr << " Inverse ) = ";
for ( typename CoefficientVector::const_iterator iter = coeff.begin(); iter < coeff.end(); ++iter )
std::cerr << *iter << " ";
std::cerr << "\n";
#endif
return Superclass::UpSamplingCoefficients( coeff );
}
template < InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension, class TAllocator >
void
LowPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator >
::Fill(const CoefficientVector& coeff)
{
this->FillCenteredDirectional(coeff);
}
template < InverseOrForwardTransformationEnum TDirectionOfTransformation,
class TPixel, unsigned int VDimension, class TAllocator >
HighPassSplineBiOrthogonalOperator< TDirectionOfTransformation, TPixel, VDimension, TAllocator >
::HighPassSplineBiOrthogonalOperator ()
{
this->SetWavelet( "9/7" );
switch ( DirectionOfTransformation )
{
case FORWARD:
this->SetRadius(3);
this->CreateToRadius(3);
break;
case INVERSE:
this->SetRadius(4);
this->CreateToRadius(4);