Skip to content
Snippets Groups Projects
Commit 2d0b525c authored by Guillaume Pasero's avatar Guillaume Pasero
Browse files

Merge branch 'app_domain_transform' into develop

parents 5f25288c ab50f657
Branches
Tags
No related merge requests found
Showing
with 1651 additions and 24 deletions
project(OTBAppDomainTransform)
otb_module_impl()
otb_create_application(
NAME DomainTransform
SOURCES otbDomainTransform.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.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.
=========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "otbWaveletImageFilter.h"
#include "otbWaveletInverseImageFilter.h"
#include "otbWaveletGenerator.h"
#include <itkConfigure.h>
#include <itkForwardFFTImageFilter.h>
#include <itkInverseFFTImageFilter.h>
#include <itkUnaryFunctorImageFilter.h>
#include <itkFFTShiftImageFilter.h>
#include "otbComplexToVectorImageCastFilter.h"
namespace otb
{
namespace Wrapper
{
template< class TInput, class TOutput>
class ToComplexPixel
{
public:
ToComplexPixel ( ) { };
~ToComplexPixel( ) { };
bool operator!=( const ToComplexPixel & ) const
{
return false;
}
bool operator==( const ToComplexPixel & other ) const
{
return !(*this != other);
}
inline TOutput operator( )( const TInput & A ) const
{
return TOutput( static_cast<typename TOutput::value_type> ( A[0] ),
static_cast<typename TOutput::value_type> ( A[1] ) );
}
};
class DomainTransform : public Application
{
public:
/** Standard class typedefs. */
typedef DomainTransform Self;
typedef Application Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef float InputPixelType;
typedef float OutputPixelType;
/** Standard macro */
itkNewMacro(Self);
itkTypeMacro(Self, otb::Application);
private:
DomainTransform() {}
~DomainTransform() ITK_OVERRIDE
{
// This is a trick to make sure fftw will cleanup its threads when application
// shared lib is released.
#if defined(ITK_USE_FFTWF)
fftwf_cleanup_threads();
fftwf_cleanup();
#endif
#if defined(ITK_USE_FFTWD)
fftw_cleanup_threads();
fftw_cleanup();
#endif
}
void DoInit() ITK_OVERRIDE
{
SetName("DomainTransform");
SetDescription("Domain Transform application for wavelet and fourier");
// Documentation
SetDocName("DomainTransform");
SetDocLongDescription("Domain Transform application for wavelet and fourier");
SetDocLimitations("This application is not streamed, check your system resources when processing large images");
SetDocAuthors("OTB-Team");
SetDocSeeAlso("otbWaveletImageFilter, otbWaveletInverseImageFilter, otbWaveletTransform");
AddDocTag(Tags::Filter);
AddParameter(ParameterType_InputImage, "in", "Input Image");
SetParameterDescription("in", "This will take an input image to be transformed"
" image. For FFT inverse transform, it expects a complex image as two-band"
" image in which first band represent real part and second band represent"
" imaginary part.");
AddRAMParameter();
AddParameter(ParameterType_Choice, "mode", "mode");
SetParameterDescription("mode", "This parameter allows one to select between"
" fft(fourier) and wavelet");
AddChoice("mode.fft", "FFT transform");
SetParameterDescription("mode.fft", "FFT transform");
AddParameter(ParameterType_Empty, "mode.fft.shift", "false");
SetParameterDescription("mode.fft.shift", "Shift transform of fft filter");
AddChoice("mode.wavelet", "wavelet");
SetParameterDescription("mode.wavelet", "Wavelet transform");
AddParameter(ParameterType_Choice, "mode.wavelet.form", "Select wavelet form");
AddChoice("mode.wavelet.form.haar", "HAAR");
AddChoice("mode.wavelet.form.db4", "DAUBECHIES4");
AddChoice("mode.wavelet.form.db6", "DAUBECHIES6");
AddChoice("mode.wavelet.form.db8", "DAUBECHIES8");
AddChoice("mode.wavelet.form.db12", "DAUBECHIES12");
AddChoice("mode.wavelet.form.db20", "DAUBECHIES20");
AddChoice("mode.wavelet.form.sb24", "SPLINE_BIORTHOGONAL_2_4");
AddChoice("mode.wavelet.form.sb44", "SPLINE_BIORTHOGONAL_4_4");
AddChoice("mode.wavelet.form.sym8", "SYMLET8");
//Default value
SetParameterString("mode", "wavelet");
SetParameterString("mode.wavelet.form", "haar");
AddParameter(ParameterType_Int,"mode.wavelet.nlevels","Number of decomposition levels");
SetParameterDescription("mode.wavelet.nlevels","Number of decomposition levels");
SetDefaultParameterInt("mode.wavelet.nlevels",2);
SetMinimumParameterIntValue("mode.wavelet.nlevels",2);
AddParameter(ParameterType_Choice,"dir", "Direction");
AddChoice("dir.fwd", "Forward");
AddChoice("dir.inv", "Inverse");
AddParameter(ParameterType_OutputImage, "out", "Output Image");
SetParameterDescription("out", "This parameter holds the output file name to"
" which transformed image will be written. This has a slightly different"
" behaviour depending on transform type. \n For Wavelet, output is a"
" single band image for both forward and inverse transform. \n For FFT"
" forward transform, output is two band image where first band represents"
" real part and second band represents imaginary part of a complex image.");
SetDocExampleParameterValue("in", "input.tif");
SetDocExampleParameterValue("mode.wavelet.form", "haar");
SetDocExampleParameterValue("out", "output_wavelet_haar.tif");
}
void DoUpdateParameters() ITK_OVERRIDE
{
}
void DoExecute() ITK_OVERRIDE
{
int dir = GetParameterInt("dir");
int mode = GetParameterInt("mode");
if( dir != 0 && dir != 1)
{
itkExceptionMacro(<< "-dir is '"
<< dir << "'."
<< "It must be either 'fwd' or 'inv'");
}
if( mode != 0 && mode != 1)
{
itkExceptionMacro( << "mode is '"
<< mode << "'."
<< "It must must be either 'fft' or 'wavelet'");
}
if ( mode == 1)
{
int wavelet_type = GetParameterInt("mode.wavelet.form");
unsigned int nlevels = GetParameterInt("mode.wavelet.nlevels");
switch (wavelet_type)
{
case 0:
{
DoWaveletTransform<otb::Wavelet::HAAR>(dir, nlevels);
break;
}
case 1:
{
DoWaveletTransform<otb::Wavelet::DB4>(dir, nlevels);
break;
}
case 2:
{
DoWaveletTransform<otb::Wavelet::DB4>(dir, nlevels);
break;
}
case 3:
{
DoWaveletTransform<otb::Wavelet::DB6>(dir, nlevels);
break;
}
case 4:
{
DoWaveletTransform<otb::Wavelet::DB8>(dir, nlevels);
break;
}
case 5:
{
DoWaveletTransform<otb::Wavelet::DB12>(dir, nlevels);
break;
}
case 6:
{
DoWaveletTransform<otb::Wavelet::DB20>(dir, nlevels);
break;
}
case 7:
{
DoWaveletTransform<otb::Wavelet::SPLINE_BIORTHOGONAL_2_4 >(dir, nlevels);
break;
}
case 8:
{
DoWaveletTransform<otb::Wavelet::SPLINE_BIORTHOGONAL_4_4>(dir, nlevels);
break;
}
case 9:
{
DoWaveletTransform<otb::Wavelet::SYMLET8>(dir, nlevels);
break;
}
default:
{
itkExceptionMacro( << "Invalid wavelet type: '" << wavelet_type << "'");
break;
}
}
}
else
{
// fft ttransform
bool shift = IsParameterEnabled( "mode.fft.shift");
typedef otb::Image< std::complex<OutputPixelType> > ComplexOutputImageType;
if (dir == 0 )
{
//forward fft
typedef otb::Image<InputPixelType> TInputImage;
typedef TInputImage::Pointer TInputImagePointer;
//get input paramter as otb::Image<InputPixelType>
TInputImagePointer inImage = GetParameterImage<TInputImage>("in");
//typedef itk::::ForwardFFTImageFilter over otbImage< InputPixelType >
typedef itk::ForwardFFTImageFilter < TInputImage, ComplexOutputImageType > FFTFilter;
FFTFilter::Pointer fwdFilter = FFTFilter::New();
fwdFilter->SetInput( inImage );
//typedef VectorImage for output of UnaryFunctorImageFilter
typedef otb::VectorImage<OutputPixelType> TOutputImage;
typedef otb::ComplexToVectorImageCastFilter<
ComplexOutputImageType,
TOutputImage > ComplexToVectorImageCastFilter;
ComplexToVectorImageCastFilter::Pointer unaryFunctorImageFilter = ComplexToVectorImageCastFilter::New();
if( shift)
{
otbAppLogINFO( << "Applying Shift image filter" );
typedef itk::FFTShiftImageFilter<
typename FFTFilter::OutputImageType,
typename FFTFilter::OutputImageType > FFTShiftFilterType;
FFTShiftFilterType::Pointer
fftShiftFilter = FFTShiftFilterType::New();
fftShiftFilter->SetInput( fwdFilter->GetOutput() );
fftShiftFilter->Update();
unaryFunctorImageFilter->SetInput(fftShiftFilter->GetOutput() );
}
else
{
unaryFunctorImageFilter->SetInput(fwdFilter->GetOutput());
}
unaryFunctorImageFilter->Update();
//set output image
SetParameterOutputImage<TOutputImage>("out",
unaryFunctorImageFilter->GetOutput());
}
else
{
//inverse fft
typedef otb::VectorImage<InputPixelType> TInputImage;
typedef TInputImage::Pointer TInputImagePointer;
TInputImagePointer inImage = GetParameterImage("in");
// typedef TComplexImage for InverseFFTImageFilter input
// This a image type of std::complex<InputPixelType>
typedef otb::Image<
std::complex<InputPixelType>, 2 > TComplexImage;
//typedef TOutputImage for InverseFFTImageFilter output
typedef otb::Image< OutputPixelType > TOutputImage;
// a unary functor to convert vectorimage to complex image
typedef itk::UnaryFunctorImageFilter
<TInputImage,
TComplexImage,
ToComplexPixel
<TInputImage::PixelType,
TComplexImage::PixelType> > UnaryFunctorImageFilter;
UnaryFunctorImageFilter::Pointer
unaryFunctorImageFilter = UnaryFunctorImageFilter::New();
if( shift)
{
typedef itk::FFTShiftImageFilter<
TInputImage,
TInputImage > FFTShiftFilterType;
FFTShiftFilterType::Pointer
fftShiftFilter = FFTShiftFilterType::New();
fftShiftFilter->SetInput( inImage );
fftShiftFilter->Update();
unaryFunctorImageFilter->SetInput(fftShiftFilter->GetOutput() );
}
else
{
unaryFunctorImageFilter->SetInput(inImage);
}
unaryFunctorImageFilter->Update();
//typedef itk::::InverseFFTImageFilter over TComplexImage
typedef itk::InverseFFTImageFilter
< TComplexImage,
TOutputImage > FFTFilter;
FFTFilter::Pointer invFilter = FFTFilter::New();
invFilter->SetInput( unaryFunctorImageFilter->GetOutput() );
invFilter->Update();
//set output image
SetParameterOutputImage<TOutputImage>("out", invFilter->GetOutput());
}
}
}
template<otb::Wavelet::Wavelet TWaveletOperator>
void DoWaveletTransform(const int dir,
const unsigned int nlevels,
const std::string inkey = "in",
const std::string outkey = "out")
{
typedef otb::Image< InputPixelType > TInputImage;
typedef otb::Image< OutputPixelType > TOutputImage;
typedef typename TInputImage::Pointer TInputImagePointer;
TInputImagePointer inImage = GetParameterImage<TInputImage>(inkey);
if( dir == 0)
{
typedef otb::WaveletImageFilter<
TInputImage,
TOutputImage,
TWaveletOperator> TWaveletImageFilter;
typedef typename
TWaveletImageFilter::Pointer
TWaveletImageFilterPointer;
TWaveletImageFilterPointer waveletImageFilter =
TWaveletImageFilter::New();
waveletImageFilter->SetInput(inImage);
waveletImageFilter->SetNumberOfDecompositions(nlevels);
waveletImageFilter->Update();
SetParameterOutputImage<TOutputImage>(outkey, waveletImageFilter->GetOutput() );
}
else
{
typedef otb::WaveletInverseImageFilter<
TInputImage,
TOutputImage,
TWaveletOperator > TWaveletImageFilter;
typedef typename
TWaveletImageFilter::Pointer
TWaveletImageFilterPointer;
TWaveletImageFilterPointer waveletImageFilter =
TWaveletImageFilter::New();
waveletImageFilter->SetInput(inImage);
waveletImageFilter->SetNumberOfDecompositions(nlevels);
waveletImageFilter->Update();
SetParameterOutputImage<TOutputImage>( outkey, waveletImageFilter->GetOutput() );
}
}
};
} // end of namespace Wrapper
} // end of namespace otb
OTB_APPLICATION_EXPORT(otb::Wrapper::DomainTransform)
set(DOCUMENTATION "Application to perform Wavelet and Fourier transform. This application is not streamed")
otb_module(OTBAppDomainTransform
DEPENDS
OTBWavelet
OTBApplicationEngine
TEST_DEPENDS
OTBTestKernel
OTBCommandLine
DESCRIPTION
"${DOCUMENTATION}"
)
otb_module_test()
otb_test_application(NAME apTvDomainTransform_wav_db20_fwd
APP DomainTransform
OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
-mode wavelet
-mode.wavelet.form db20
-mode.wavelet.nlevels 2
-dir fwd
-out ${TEMP}/apTvDomainTransform_wav_db20_fwd.tif
)
otb_test_application(NAME apTvDomainTransform_wav_haar_inv
APP DomainTransform
OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
-mode wavelet
-mode.wavelet.form haar
-dir inv
-out ${TEMP}/apTvDomainTransform_wav_haar_inv.tif
)
otb_test_application(NAME apTvDomainTransform_fft_shift_fwd
APP DomainTransform
OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
-mode fft
-mode.fft.shift true
-dir fwd
-out ${TEMP}/apTvDomainTransform_fft_shift_fwd.tif
)
otb_test_application(NAME apTvDomainTransform_fft_inv
APP DomainTransform
OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
-mode fft
-dir inv
-out ${TEMP}/apTvDomainTransform_fft_shift_inv.tif
)
......@@ -102,7 +102,6 @@ protected:
SubsampleImageFilter ()
{
m_SubsampleFactor.Fill(1);
//this->SetNumberOfThreads(1);
}
~SubsampleImageFilter() ITK_OVERRIDE {}
......
......@@ -83,7 +83,7 @@ SubsampleImageFilter<TInputImage, TOutputImage, TDirectionOfTransformation>
{
Superclass::CallCopyOutputRegionToInputRegion(destRegion, srcRegion);
if (static_cast<int>(DirectionOfTransformation) == Wavelet::INVERSE)
if (DirectionOfTransformation == Wavelet::INVERSE)
{
typename OutputImageRegionType::IndexType srcIndex = srcRegion.GetIndex();
typename OutputImageRegionType::SizeType srcSize = srcRegion.GetSize();
......@@ -112,7 +112,7 @@ SubsampleImageFilter<TInputImage, TOutputImage, TDirectionOfTransformation>
{
Superclass::CallCopyInputRegionToOutputRegion(destRegion, srcRegion);
if (static_cast<int>(DirectionOfTransformation) == Wavelet::INVERSE)
if (DirectionOfTransformation == Wavelet::INVERSE)
{
typename InputImageRegionType::IndexType srcIndex = srcRegion.GetIndex();
typename InputImageRegionType::SizeType srcSize = srcRegion.GetSize();
......@@ -161,8 +161,7 @@ SubsampleImageFilter<TInputImage, TOutputImage, TDirectionOfTransformation>
SubsampledImageRegionConstIterator<InputImageType> inputIter
(this->GetInput(), inputRegionForThread);
if (static_cast<int>(itkGetStaticConstMacro(DirectionOfTransformation))
== static_cast<int>(Wavelet::FORWARD))
if (DirectionOfTransformation == Wavelet::FORWARD)
{
inputIter.SetSubsampleFactor(GetSubsampleFactor());
inputIter.GoToBegin();
......
......@@ -399,6 +399,11 @@ protected:
WaveletFilterBank();
~WaveletFilterBank() ITK_OVERRIDE {}
void VerifyInputInformation() ITK_OVERRIDE
{
}
/** GenerateOutputInformation
* Set the size of the output image depending on the decimation factor
* Copy information from the input image if existing.
......
......@@ -27,9 +27,6 @@
#include "itkPeriodicBoundaryCondition.h"
// FIXME
#define __myDebug__ 0
namespace otb {
/**
......@@ -54,7 +51,6 @@ WaveletFilterBank<TInputImage, TOutputImage, TWaveletOperator, Wavelet::FORWARD>
m_UpSampleFilterFactor = 0;
m_SubsampleImageFactor = 1;
//this->SetNumberOfThreads(1);
}
template <class TInputImage, class TOutputImage, class TWaveletOperator>
......@@ -66,11 +62,9 @@ WaveletFilterBank<TInputImage, TOutputImage, TWaveletOperator, Wavelet::FORWARD>
if (GetSubsampleImageFactor() == 1) return;
#if __myDebug__
otbGenericMsgDebugMacro(<< " down sampling output regions by a factor of " << GetSubsampleImageFactor());
otbGenericMsgDebugMacro(<< "initial region " << this->GetInput()->GetLargestPossibleRegion().GetSize()[0]
<< "," << this->GetInput()->GetLargestPossibleRegion().GetSize()[1]);
#endif
OutputImageRegionType newRegion;
this->CallCopyInputRegionToOutputRegion(newRegion, this->GetInput()->GetLargestPossibleRegion());
......@@ -80,9 +74,8 @@ WaveletFilterBank<TInputImage, TOutputImage, TWaveletOperator, Wavelet::FORWARD>
this->GetOutput(i)->SetRegions(newRegion);
}
#if __myDebug__
otbGenericMsgDebugMacro(<< "new region output " << newRegion.GetSize()[0] << "," << newRegion.GetSize()[1]);
#endif
}
template <class TInputImage, class TOutputImage, class TWaveletOperator>
......@@ -185,12 +178,13 @@ WaveletFilterBank<TInputImage, TOutputImage, TWaveletOperator, Wavelet::FORWARD>
this->CallCopyInputRegionToOutputRegion(InputImageDimension - 1 - direction,
smallerRegion, largerRegion);
for (unsigned int i = 0; i < m_InternalImages[direction].size(); ++i)
const unsigned int d = InputImageDimension - 2 - direction;
for (unsigned int i = 0; i < m_InternalImages[d].size(); ++i)
{
m_InternalImages[InputImageDimension - 2 - direction][i] = OutputImageType::New();
m_InternalImages[InputImageDimension - 2 - direction][i]->SetRegions(smallerRegion);
m_InternalImages[InputImageDimension - 2 - direction][i]->Allocate();
m_InternalImages[InputImageDimension - 2 - direction][i]->FillBuffer(0);
m_InternalImages[d][i] = OutputImageType::New();
m_InternalImages[d][i]->SetRegions(smallerRegion);
m_InternalImages[d][i]->Allocate();
m_InternalImages[d][i]->FillBuffer(0);
}
largerRegion = smallerRegion;
......@@ -642,21 +636,18 @@ WaveletFilterBank<TInputImage, TOutputImage, TWaveletOperator, Wavelet::INVERSE>
}
}
#if __myDebug__
otbGenericMsgDebugMacro(<< " up sampling output regions by a factor of " << GetSubsampleImageFactor());
otbGenericMsgDebugMacro(<< "initial region "
<< this->GetInput(0)->GetLargestPossibleRegion().GetSize()[0]
<< "," << this->GetInput(0)->GetLargestPossibleRegion().GetSize()[1]);
#endif
OutputImageRegionType newRegion;
this->CallCopyInputRegionToOutputRegion(newRegion, this->GetInput(0)->GetLargestPossibleRegion());
this->GetOutput()->SetRegions(newRegion);
#if __myDebug__
otbGenericMsgDebugMacro(<< "new region output " << newRegion.GetSize()[0] << "," << newRegion.GetSize()[1]);
#endif
}
template <class TInputImage, class TOutputImage, class TWaveletOperator>
......@@ -1178,7 +1169,7 @@ WaveletFilterBank<TInputImage, TOutputImage, TWaveletOperator, Wavelet::INVERSE>
typename FilterType::Pointer overSampledLowPass = FilterType::New();
overSampledLowPass->SetInput(cropedLowPass);
overSampledLowPass->SetSubsampleFactor(delta);
overSampledLowPass->SetNumberOfThreads(1);
overSampledLowPass->SetNumberOfThreads(1);
overSampledLowPass->Update();
InputImagePointerType cropedHighPass = InputImageType::New();
......@@ -1197,7 +1188,7 @@ WaveletFilterBank<TInputImage, TOutputImage, TWaveletOperator, Wavelet::INVERSE>
typename FilterType::Pointer overSampledHighPass = FilterType::New();
overSampledHighPass->SetInput(cropedHighPass);
overSampledHighPass->SetSubsampleFactor(delta);
overSampledHighPass->SetNumberOfThreads(1);
overSampledHighPass->SetNumberOfThreads(1);
overSampledHighPass->Update();
InnerProductType innerProduct;
......
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.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 otbWaveletImageFilter_h
#define otbWaveletImageFilter_h
#include "otbWaveletOperator.h"
#include "otbWaveletFilterBank.h"
#include "otbWaveletTransform.h"
#include "otbWaveletsBandsListToWaveletsSynopsisImageFilter.h"
namespace otb {
/** \class WaveletImageFilter
* \brief
* This filter performs wavelet forward transform.
* It takes three template arguments: Input, Output and WaveletOperator
* This filter is not streamed.
*
* \ingroup OTBWavelet
* \sa WaveletInverseImageFilter
* \sa WaveletsBandsListToWaveletsSynopsisImageFilter
* \sa WaveletGenerator
*/
template < class TInputImage,
class TOutputImage,
Wavelet::Wavelet TMotherWaveletOperator >
class WaveletImageFilter :
public itk::ImageToImageFilter< TInputImage, TOutputImage >
{
public:
/** Standard class typedefs. */
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
itkStaticConstMacro( ImageDimension, unsigned int, InputImageType::ImageDimension );
itkStaticConstMacro( MotherWaveletOperator, short, TMotherWaveletOperator );
itkStaticConstMacro( DirectionOfTransformation, short, otb::Wavelet::FORWARD );
typedef WaveletImageFilter<InputImageType,OutputImageType, TMotherWaveletOperator> Self;
typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef typename InputImageType::PixelType InputPixelType;
typedef otb::WaveletOperator< TMotherWaveletOperator, otb::Wavelet::FORWARD, InputPixelType, ImageDimension >
WaveletOperatorType;
typedef otb::WaveletFilterBank< InputImageType, InputImageType, WaveletOperatorType, otb::Wavelet::FORWARD >
FilterBankType;
typedef otb::WaveletTransform< InputImageType, InputImageType, FilterBankType, otb::Wavelet::FORWARD >
WaveletTransformFilterType;
typedef typename WaveletTransformFilterType::Pointer
WaveletTransformFilterPointerType;
typedef typename WaveletTransformFilterType::OutputImageListType
WaveletTransformFilterOutputImageListType;
typedef otb::WaveletsBandsListToWaveletsSynopsisImageFilter<WaveletTransformFilterOutputImageListType, OutputImageType>
WaveletBandsListToWaveletsSynopsisImageFilterType;
typedef typename WaveletBandsListToWaveletsSynopsisImageFilterType::Pointer
WaveletBandsListToWaveletsSynopsisImageFilterPointerType;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(WaveletImageFilter, ImageToImageFilter);
itkGetMacro(NumberOfDecompositions,unsigned int);
itkSetMacro(NumberOfDecompositions,unsigned int);
protected:
WaveletImageFilter();
virtual ~WaveletImageFilter();
virtual void GenerateInputRequestedRegion();
virtual void GenerateData();
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
private:
WaveletImageFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
WaveletTransformFilterPointerType m_WaveletTransform;
WaveletBandsListToWaveletsSynopsisImageFilterPointerType m_WaveletBandsListToWaveletsSynopsis;
unsigned int m_NumberOfDecompositions;
};
}
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbWaveletImageFilter.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.
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 otbWaveletImageFilter_txx
#define otbWaveletImageFilter_txx
#include "otbWaveletImageFilter.h"
namespace otb
{
/** Constructor */
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
WaveletImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::WaveletImageFilter() : m_NumberOfDecompositions(2)
{
m_WaveletTransform = WaveletTransformFilterType::New();
m_WaveletTransform->SetSubsampleImageFactor(2);
m_WaveletBandsListToWaveletsSynopsis = WaveletBandsListToWaveletsSynopsisImageFilterType::New();
m_WaveletBandsListToWaveletsSynopsis->SetInput( m_WaveletTransform->GetOutput() );
}
/** Destructor */
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
WaveletImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::~WaveletImageFilter()
{
}
/**
* GenerateInputRequestedRegion
*/
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
void
WaveletImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::GenerateInputRequestedRegion(void)
{
// call the superclass' implementation of this method
Superclass::GenerateInputRequestedRegion();
// get pointers to the inputs
typename InputImageType::Pointer input =
const_cast<InputImageType *> (this->GetInput());
if ( !input )
{
return;
}
input->SetRequestedRegionToLargestPossibleRegion();
}
/**
* Main computation method
*/
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
void
WaveletImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::GenerateData()
{
m_WaveletTransform->SetInput( this->GetInput() );
m_WaveletTransform->SetNumberOfDecompositions( m_NumberOfDecompositions );
m_WaveletBandsListToWaveletsSynopsis->GraftOutput( this->GetOutput() );
m_WaveletBandsListToWaveletsSynopsis->Update();
this->GraftOutput( m_WaveletBandsListToWaveletsSynopsis->GetOutput() );
}
/**
* PrintSelf Method
*/
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
void
WaveletImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
}
#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.
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 otbWaveletInverseImageFilter_h
#define otbWaveletInverseImageFilter_h
#include "otbWaveletOperator.h"
#include "otbWaveletFilterBank.h"
#include "otbWaveletTransform.h"
#include "otbWaveletsSynopsisImageToWaveletsBandsListFilter.h"
namespace otb {
/** \class WaveletInverseImageFilter
* \brief
* This filter performs wavelet inverse transform.
* It takes three template arguments: Input, Output and WaveletOperator
* This filter is not streamed.
* \ingroup OTBWavelet
* \sa WaveletImageFilter
* \sa WaveletsSynopsisImageToWaveletsBandsListFilter
* \sa WaveletGenerator
*/
template < class TInputImage,
class TOutputImage,
Wavelet::Wavelet TMotherWaveletOperator >
class WaveletInverseImageFilter :
public itk::ImageToImageFilter< TInputImage, TOutputImage >
{
public:
/** Standard class typedefs. */
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
itkStaticConstMacro( ImageDimension, unsigned int, InputImageType::ImageDimension );
itkStaticConstMacro( MotherWaveletOperator, short, TMotherWaveletOperator );
itkStaticConstMacro( DirectionOfTransformation, short , otb::Wavelet::FORWARD );
typedef WaveletInverseImageFilter<InputImageType,OutputImageType, TMotherWaveletOperator> Self;
typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef typename InputImageType::PixelType InputPixelType;
typedef typename OutputImageType::PixelType OutputPixelType;
typedef otb::WaveletOperator< TMotherWaveletOperator, otb::Wavelet::INVERSE, OutputPixelType, ImageDimension >
WaveletOperatorType;
typedef otb::WaveletFilterBank< OutputImageType, OutputImageType, WaveletOperatorType, otb::Wavelet::INVERSE >
FilterBankType;
typedef otb::WaveletTransform< OutputImageType, OutputImageType, FilterBankType, otb::Wavelet::INVERSE >
WaveletInverseTransformFilterType;
typedef typename WaveletInverseTransformFilterType::Pointer
WaveletInverseTransformFilterPointerType;
typedef otb::WaveletsSynopsisImageToWaveletsBandsListFilter<InputImageType, typename WaveletInverseTransformFilterType::InputImageListType>
WaveletsSynopsisImageToWaveletsBandsListFilterType;
typedef typename WaveletsSynopsisImageToWaveletsBandsListFilterType::Pointer
WaveletsSynopsisImageToWaveletsBandsListFilterPointerType;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(WaveletInverseImageFilter, ImageToImageFilter);
itkGetMacro(NumberOfDecompositions,unsigned int);
itkSetMacro(NumberOfDecompositions,unsigned int);
/** If the filter is modified, the internal filters need to be modified too */
virtual void Modified() const;
protected:
WaveletInverseImageFilter();
virtual ~WaveletInverseImageFilter();
virtual void GenerateInputRequestedRegion();
virtual void GenerateData();
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
private:
WaveletInverseImageFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
WaveletsSynopsisImageToWaveletsBandsListFilterPointerType m_SynopsisImageToWaveletsBandsList;
WaveletInverseTransformFilterPointerType m_WaveletTransform;
unsigned int m_NumberOfDecompositions;
};
}
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbWaveletInverseImageFilter.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.
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 __otbWaveletInverseImageFilter_txx
#define __otbWaveletInverseImageFilter_txx
#include "otbWaveletInverseImageFilter.h"
namespace otb
{
/** Constructor */
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
WaveletInverseImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::WaveletInverseImageFilter() : m_NumberOfDecompositions(2)
{
m_SynopsisImageToWaveletsBandsList = WaveletsSynopsisImageToWaveletsBandsListFilterType::New();
m_SynopsisImageToWaveletsBandsList->SetDecimationRatio(2);
m_WaveletTransform = WaveletInverseTransformFilterType::New();
m_WaveletTransform->SetSubsampleImageFactor(2);
m_WaveletTransform->SetInput( m_SynopsisImageToWaveletsBandsList->GetOutput() );
}
/** Destructor */
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
WaveletInverseImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::~WaveletInverseImageFilter()
{
}
/** Destructor */
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
void
WaveletInverseImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::Modified() const
{
Superclass::Modified();
m_SynopsisImageToWaveletsBandsList->Modified();
m_WaveletTransform->Modified();
}
/**
* GenerateInputRequestedRegion
*/
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
void
WaveletInverseImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::GenerateInputRequestedRegion(void)
{
// call the superclass' implementation of this method
Superclass::GenerateInputRequestedRegion();
// get pointers to the inputs
typename InputImageType::Pointer input =
const_cast<InputImageType *> (this->GetInput());
if ( !input )
{
return;
}
input->SetRequestedRegionToLargestPossibleRegion();
}
/**
* Main computation method
*/
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
void
WaveletInverseImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::GenerateData()
{
m_SynopsisImageToWaveletsBandsList->SetInput( this->GetInput() );
m_SynopsisImageToWaveletsBandsList->SetNumberOfLevels( m_NumberOfDecompositions );
m_WaveletTransform->GraftOutput( this->GetOutput() );
m_WaveletTransform->Update();
this->GraftOutput( m_WaveletTransform->GetOutput() );
}
/**
* PrintSelf Method
*/
template <class TInputImage, class TOutputImage, Wavelet::Wavelet TMotherWaveletOperator>
void
WaveletInverseImageFilter<TInputImage, TOutputImage, TMotherWaveletOperator>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
}
#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.
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 otbWaveletsBandsListToWaveletsSynopsisImageFilter_h
#define otbWaveletsBandsListToWaveletsSynopsisImageFilter_h
#include "otbImageListToImageFilter.h"
namespace otb
{
/** \class WaveletsBandsListToWaveletsSynopsisImageFilter
* \brief Converts a list of wavelets bands to the traditionnal multi-resolution wavelets view
*
* The decimation ratio is taken into account.
*
* \ingroup OTBWavelet
* \sa WaveletsSynopsisImageToWaveletsBandsListFilter
*/
template <class TImageList, class TImage>
class ITK_EXPORT WaveletsBandsListToWaveletsSynopsisImageFilter
: public ImageListToImageFilter<typename TImageList::ImageType, TImage>
{
public:
/** Standard typedefs */
typedef WaveletsBandsListToWaveletsSynopsisImageFilter Self;
typedef ImageListToImageFilter<
typename TImageList::ImageType,TImage> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Type macro */
itkNewMacro(Self);
/** Useful typedefs */
typedef TImageList InputImageListType;
typedef typename InputImageListType::ImageType InputImageType;
typedef TImage OutputImageType;
typedef typename OutputImageType::RegionType RegionType;
/** Creation through object factory macro */
itkTypeMacro(WaveletsBandsListToWaveletsSynopsisImageFilter,ImageToImageListFilter);
/** Set the decimation ratio */
itkSetMacro(DecimationRatio,unsigned int);
/** Get the decimation ratio */
itkGetMacro(DecimationRatio,unsigned int);
protected:
/** Main computation method */
virtual void ThreadedGenerateData(const RegionType & outputRegionForThread, itk::ThreadIdType threadId);
/** GenerateOutputInformation
* Set the number of bands of the output.
* Copy informations from the first image of the list if existing.
**/
virtual void GenerateOutputInformation(void);
/**
* GenerateInputRequestedRegion
* Set the requested region of each image in the list.
*/
virtual void GenerateInputRequestedRegion(void);
/** Constructor */
WaveletsBandsListToWaveletsSynopsisImageFilter();
/** Destructor */
virtual ~WaveletsBandsListToWaveletsSynopsisImageFilter();
/**PrintSelf method */
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
private:
WaveletsBandsListToWaveletsSynopsisImageFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
/** The decimation ratio used in the decomposition */
unsigned int m_DecimationRatio;
};
}// End namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbWaveletsBandsListToWaveletsSynopsisImageFilter.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.
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 otbWaveletsBandsListToWaveletsSynopsisImageFilter_txx
#define otbWaveletsBandsListToWaveletsSynopsisImageFilter_txx
#include "otbWaveletsBandsListToWaveletsSynopsisImageFilter.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionConstIterator.h"
#include "otbMacro.h"
#include "itkProgressReporter.h"
namespace otb
{
/** Constructor */
template <class TImageList, class TImage>
WaveletsBandsListToWaveletsSynopsisImageFilter<TImageList,TImage>
::WaveletsBandsListToWaveletsSynopsisImageFilter() : m_DecimationRatio(2)
{}
/** Destructor */
template <class TImageList, class TImage>
WaveletsBandsListToWaveletsSynopsisImageFilter<TImageList,TImage>
::~WaveletsBandsListToWaveletsSynopsisImageFilter()
{}
/**
* GenerateOutputInformation
*/
template <class TImageList, class TImage>
void
WaveletsBandsListToWaveletsSynopsisImageFilter<TImageList,TImage>
::GenerateOutputInformation(void)
{
// We must set the size of the output image to be twice the size of the last image
// of the image list, which is the first band.
if(this->GetOutput())
{
if (this->GetInput()->Size()>0)
{
// Retrieve the largest band
typename InputImageType::Pointer lastBand = this->GetInput()->Back();
// Retrieve the region of the largest band
RegionType largestBandRegion = lastBand->GetLargestPossibleRegion();
// Retrieve the size of the largest region
typename RegionType::SizeType outputSize = largestBandRegion.GetSize();
// Multiply this size by two
outputSize[0]*=m_DecimationRatio;
outputSize[1]*=m_DecimationRatio;
// Build the output region
RegionType outputLargestRegion;
outputLargestRegion.SetSize(outputSize);
// Copy information to the output image
this->GetOutput()->CopyInformation(lastBand);
this->GetOutput()->SetLargestPossibleRegion(outputLargestRegion);
}
}
}
/**
* GenerateInputRequestedRegion
*/
template <class TImageList, class TImage>
void
WaveletsBandsListToWaveletsSynopsisImageFilter<TImageList,TImage>
::GenerateInputRequestedRegion(void)
{
typename InputImageListType::Pointer inputPtr = this->GetInput();
typename InputImageListType::ConstIterator inputListIt = inputPtr->Begin();
while (inputListIt!=inputPtr->End())
{
inputListIt.Get()->SetRequestedRegionToLargestPossibleRegion();
++inputListIt;
}
}
/**
* Main computation method
*/
template <class TImageList, class TImage>
void
WaveletsBandsListToWaveletsSynopsisImageFilter<TImageList,TImage>
::ThreadedGenerateData(const RegionType & outputRegionForThread,
itk::ThreadIdType threadId)
{
// Retrieve input and output pointers
typename InputImageListType::Pointer inputPtr = this->GetInput();
typename OutputImageType::Pointer outputPtr = this->GetOutput();
// Set up progress reporting
itk::ProgressReporter progress(this,
threadId,
outputRegionForThread.GetNumberOfPixels());
// defines input and output iterators
typedef itk::ImageRegionConstIterator<InputImageType> InputIteratorType;
typedef itk::ImageRegionIterator<OutputImageType> OutputIteratorType;
// Set up an iterator on the input wavelets band
typename InputImageListType::ConstIterator inputListIt = inputPtr->Begin();
unsigned int bandIndex = 0;
// Compute number of decomposition levels
unsigned int numberOfDecompositionLevels = (inputPtr->Size()-1)/3;
// Retrieve the largest possible region size
typename RegionType::SizeType largestSize = outputPtr->GetLargestPossibleRegion().GetSize();
// Iterate on each band
for (;inputListIt!=inputPtr->End();++inputListIt,++bandIndex)
{
// Build a band offset
typename RegionType::OffsetType currentOffset;
currentOffset.Fill(0);
// Initialise Current level
unsigned int currentLevel = 0;
unsigned int currentSubBand = 0;
if(bandIndex > 0)
{
// Compute current level and sub band
currentLevel = 1 + (bandIndex-1)/3;
currentSubBand = (bandIndex-1)%3;
// Compute potentiel offset in x and y
unsigned int offsetX = largestSize[0]/(unsigned int)vcl_pow((double)m_DecimationRatio,(double)1+numberOfDecompositionLevels-currentLevel);
unsigned int offsetY = largestSize[1]/(unsigned int)vcl_pow((double)m_DecimationRatio,(double)1+numberOfDecompositionLevels-currentLevel);
// Compute final offset according to the subband index
if(currentSubBand == 0)
{
currentOffset[0]+=offsetX;
}
else if(currentSubBand == 1)
{
currentOffset[1]+=offsetY;
}
else
{
currentOffset[0]+=offsetX;
currentOffset[1]+=offsetY;
}
}
// Retrieve current band region
RegionType currentBandRegion = inputListIt.Get()->GetLargestPossibleRegion();
// Apply offset to get the current output region
RegionType currentOutputRegion = currentBandRegion;
typename RegionType::IndexType currentOutputIndex = currentBandRegion.GetIndex();
currentOutputIndex+=currentOffset;
currentOutputRegion.SetIndex(currentOutputIndex);
// Crop with the outputRegionForThread. If the crop fails,
// it means that currentOutputRegion is outside of outputRegionForThread,
// and in this case we skip to the next image in the list.
if(currentOutputRegion.Crop(outputRegionForThread))
{
// Compute the corresponding input region
RegionType currentInputRegion = currentBandRegion;
currentOutputIndex = currentOutputRegion.GetIndex();
typename RegionType::IndexType currentInputIndex = currentBandRegion.GetIndex();
for(unsigned int i = 0; i < InputImageType::ImageDimension;++i)
{
currentInputIndex[i]+=currentOutputIndex[i];
currentInputIndex[i]-=currentOffset[i];
}
currentInputRegion.SetSize(currentOutputRegion.GetSize());
currentInputRegion.SetIndex(currentInputIndex);
InputIteratorType inIt(inputListIt.Get(),currentInputRegion);
OutputIteratorType outIt(outputPtr,currentOutputRegion);
// Go to begin
inIt.GoToBegin();
outIt.GoToBegin();
// Copy pixels
while(!inIt.IsAtEnd() && !outIt.IsAtEnd())
{
// Copy pixel value
outIt.Set(static_cast<typename OutputImageType::InternalPixelType>(inIt.Get()));
// Step forward
++inIt;
++outIt;
progress.CompletedPixel();
}
}
}
}
/**
* PrintSelf Method
*/
template <class TImageType, class TImageList>
void
WaveletsBandsListToWaveletsSynopsisImageFilter<TImageType,TImageList>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
} // End 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.
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 otbWaveletsSynopsisImageToWaveletsBandsListFilter_h
#define otbWaveletsSynopsisImageToWaveletsBandsListFilter_h
#include "otbImageToImageListFilter.h"
#include "itkRegionOfInterestImageFilter.h"
namespace otb
{
/** \class WaveletsSynopsisImageToWaveletsBandsListFilter
* \brief This class convert the standard wavelets view to a list of bands.
*
* \ingroup OTBWavelet
* \sa WaveletsBandsListToWaveletsSynopsisImageFilter
*/
template <class TImage, class TImageList>
class ITK_EXPORT WaveletsSynopsisImageToWaveletsBandsListFilter
: public ImageToImageListFilter<TImage,typename TImageList::ImageType>
{
public:
/** Standard typedefs */
typedef WaveletsSynopsisImageToWaveletsBandsListFilter Self;
typedef ImageToImageListFilter<TImage,
typename TImageList::ImageType> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Type macro */
itkNewMacro(Self);
/** Creation through object factory macro */
itkTypeMacro(WaveletsSynopsisImageToWaveletsBandsListFilter,ImageToImageListFilter);
/** Template parameters typedefs */
typedef TImage InputImageType;
typedef typename InputImageType::RegionType RegionType;
typedef TImageList OutputImageListType;
typedef typename OutputImageListType::ImageType OutputImageType;
typedef itk::RegionOfInterestImageFilter<
InputImageType,
InputImageType > ExtractFilterType;
typedef typename ExtractFilterType::Pointer ExtractFilterPointerType;
typedef std::vector<ExtractFilterPointerType> ExtractFilterVectorType;
/** Set the number of levels */
itkSetMacro(NumberOfLevels,unsigned int);
/** Get the number of levels */
itkGetMacro(NumberOfLevels,unsigned int);
/** Set the decimation ratio */
itkSetMacro(DecimationRatio,unsigned int);
/** Get the decimation ratio */
itkGetMacro(DecimationRatio,unsigned int);
/** If the filter is modified, the extract list need to be regenerated */
virtual void Modified() const;
protected:
/** Constructor */
WaveletsSynopsisImageToWaveletsBandsListFilter();
/** Destructor */
virtual ~WaveletsSynopsisImageToWaveletsBandsListFilter();
/**PrintSelf method */
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
/** Generate the input requested region from the first element in the list. */
virtual void GenerateInputRequestedRegion(void);
/** Generate the output information by building the output list. */
virtual void GenerateOutputInformation(void);
/** Main computation method */
virtual void GenerateData(void);
private:
WaveletsSynopsisImageToWaveletsBandsListFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
/** The number of levels in the decomposition */
unsigned int m_NumberOfLevels;
/** The decimation ratio used in the decomposition */
unsigned int m_DecimationRatio;
/** The vector of extraction filters for each band */
ExtractFilterVectorType m_ExtractFilters;
/** True if extract list is up-to-date */
mutable bool m_ExtractFiltersUpToDate;
};
}// End namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbWaveletsSynopsisImageToWaveletsBandsListFilter.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.
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 otbWaveletsSynopsisImageToWaveletsBandsListFilter_txx
#define otbWaveletsSynopsisImageToWaveletsBandsListFilter_txx
#include "otbWaveletsSynopsisImageToWaveletsBandsListFilter.h"
namespace otb
{
/** Constructor */
template <class TImage, class TImageList>
WaveletsSynopsisImageToWaveletsBandsListFilter<TImage,TImageList>
::WaveletsSynopsisImageToWaveletsBandsListFilter() : m_NumberOfLevels(1),
m_DecimationRatio(2),
m_ExtractFilters(),
m_ExtractFiltersUpToDate(false)
{}
/** Destructor */
template <class TImage, class TImageList>
WaveletsSynopsisImageToWaveletsBandsListFilter<TImage,TImageList>
::~WaveletsSynopsisImageToWaveletsBandsListFilter()
{
m_ExtractFilters.clear();
}
/** Modify overload */
template <class TImage, class TImageList>
void
WaveletsSynopsisImageToWaveletsBandsListFilter<TImage,TImageList>
::Modified() const
{
// Call superclass implementation
Superclass::Modified();
m_ExtractFiltersUpToDate = false;
}
/** Generate the input requested region from the first element in the list. */
template <class TImage, class TImageList>
void
WaveletsSynopsisImageToWaveletsBandsListFilter<TImage,TImageList>
::GenerateOutputInformation(void)
{
typename OutputImageListType::Pointer outputPtr = this->GetOutput();
typename InputImageType::ConstPointer inputPtr = this->GetInput();
// Check if we need to regenerate the extract filters
if (inputPtr && !m_ExtractFiltersUpToDate)
{
// Retrieve image size
typename RegionType::SizeType largestSize = inputPtr->GetLargestPossibleRegion().GetSize();
// Compute the number of output images
unsigned int numberOfOutputImages = m_NumberOfLevels*3 + 1;
// Clear the output image list
outputPtr->Clear();
// Clear the extract filter vector
m_ExtractFilters.clear();
// For each output image
for (unsigned int i=0;i<numberOfOutputImages;++i)
{
// Build the current extract filter
typename ExtractFilterType::Pointer currentExtract = ExtractFilterType::New();
currentExtract->SetInput(inputPtr);
// Add it to the filter list
m_ExtractFilters.push_back(currentExtract);
// Add its output to the filter's output
outputPtr->PushBack(currentExtract->GetOutput());
// Build the corresponding region
RegionType currentRegion;
typename RegionType::IndexType currentIndex;
typename RegionType::SizeType currentSize;
currentIndex.Fill(0);
// If this is not the first sub-band
if(i > 0)
{
// Compute current sub-band and level
unsigned int currentLevel = (i-1)/3;
unsigned int currentSubBand = (i-1)%3;
unsigned int offsetX = largestSize[0]/(unsigned int)vcl_pow((double)m_DecimationRatio,(double)m_NumberOfLevels-currentLevel);
unsigned int offsetY = largestSize[1]/(unsigned int)vcl_pow((double)m_DecimationRatio,(double)m_NumberOfLevels-currentLevel);
// Compute current size
currentSize[0] = offsetX;
currentSize[1] = offsetY;
// Compute current index
if(currentSubBand == 0)
{
currentIndex[0]+= offsetX;
}
else if(currentSubBand == 1)
{
currentIndex[1]= offsetY;
}
else
{
currentIndex[0]= offsetX;
currentIndex[1]= offsetY;
}
}
else
{
// The coarsest scale size
currentSize[0] = largestSize[0]/(unsigned int)vcl_pow((double)m_DecimationRatio,(double)m_NumberOfLevels);
currentSize[1] = largestSize[1]/(unsigned int)vcl_pow((double)m_DecimationRatio,(double)m_NumberOfLevels);
}
// Build current region
currentRegion.SetIndex(currentIndex);
currentRegion.SetSize(currentSize);
//std::cout<<"Band: "<<i<<", region "<<currentRegion<<std::endl;
currentExtract->SetRegionOfInterest(currentRegion);
}
m_ExtractFiltersUpToDate = true;
}
}
/** Generate the output information by building the output list. */
template <class TImage, class TImageList>
void
WaveletsSynopsisImageToWaveletsBandsListFilter<TImage,TImageList>
::GenerateInputRequestedRegion(void)
{
typename InputImageType::Pointer inputPtr = this->GetInput();
if (inputPtr)
{
inputPtr->SetRequestedRegionToLargestPossibleRegion();
}
}
/**
* Main computation method
*/
template <class TImage, class TImageList>
void
WaveletsSynopsisImageToWaveletsBandsListFilter<TImage,TImageList>
::GenerateData(void)
{
// Update each extract fillter
for(typename ExtractFilterVectorType::iterator it = m_ExtractFilters.begin();
it!=m_ExtractFilters.end();++it)
{
(*it)->Update();
}
}
/**
* PrintSelf Method
*/
template <class TImage, class TImageList>
void
WaveletsSynopsisImageToWaveletsBandsListFilter<TImage,TImageList>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
} // End namespace otb
#endif
......@@ -15,6 +15,7 @@ otbWaveletFilterBank.cxx
otbWaveletPacketTransformNew.cxx
otbWaveletFilterBankNew.cxx
otbWaveletOperatorNew.cxx
otbWaveletImageToImageFilter.cxx
)
add_executable(otbWaveletTestDriver ${OTBWaveletTests})
......@@ -572,3 +573,11 @@ otb_add_test(NAME msTuWaveletFilterBankNew COMMAND otbWaveletTestDriver
otb_add_test(NAME msTuWaveletOperatorNew COMMAND otbWaveletTestDriver
otbWaveletOperatorNew )
otb_add_test(NAME msTvWaveletImageToImageFilter COMMAND otbWaveletTestDriver
--compare-image ${EPSILON_6}
${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
${TEMP}/msTvWaveletImageToImageFilterOut.tif
otbWaveletImageToImageFilter
${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
${TEMP}/msTvWaveletImageToImageFilterOut.tif
)
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.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.
=========================================================================*/
/*
This test code will run a WaveletImageFilter on given input image. Output
from this filter is then fed to WaveletInverseImageFilter which does
the inverse transform. Hence output of inverse transform passed to
ImageFileWriter will result in the input image.
Wavelet operator used is HAAR (otb::Wavelet::HAAR).
This filter works only in single-threaded setup
*/
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbWaveletImageFilter.h"
#include "otbWaveletInverseImageFilter.h"
int otbWaveletImageToImageFilter(int argc, char * argv[])
{
const char * inputFileName = argv[1];
const char * outputFileName = argv[argc-1];
/* Wavelet operator */
const otb::Wavelet::Wavelet OperatorType = otb::Wavelet::HAAR;
const int Dimension = 2;
typedef double PixelType;
typedef otb::Image<PixelType, Dimension> ImageType;
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef otb::WaveletImageFilter<
ImageType,
ImageType,
OperatorType> FwdFilterType;
typedef otb::WaveletInverseImageFilter<
ImageType,
ImageType,
OperatorType> InvFilterType;
typedef otb::ImageFileWriter<ImageType> WriterType;
// itk::MultiThreader::SetGlobalMaximumNumberOfThreads( 1 );
/* Reading */
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(inputFileName);
/* Forward Transformation */
FwdFilterType::Pointer fwdFilter = FwdFilterType::New();
fwdFilter->SetInput(reader->GetOutput());
fwdFilter->Update();
/* Inverse Transformation */
InvFilterType::Pointer invFilter = InvFilterType::New();
invFilter->SetInput(fwdFilter->GetOutput());
invFilter->Update();
/* Writing output */
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(outputFileName);
writer->SetInput(invFilter->GetOutput());
writer->Update();
return EXIT_SUCCESS;
}
......@@ -14,4 +14,5 @@ void RegisterTests()
REGISTER_TEST(otbWaveletPacketTransformNew);
REGISTER_TEST(otbWaveletFilterBankNew);
REGISTER_TEST(otbWaveletOperatorNew);
REGISTER_TEST(otbWaveletImageToImageFilter);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment