Skip to content
Snippets Groups Projects
Commit 66306721 authored by Sebastien Harasse's avatar Sebastien Harasse
Browse files

ENH: Adding functor filter for functor with (pixel,index) parameters and with...

ENH: Adding functor filter for functor with (pixel,index) parameters and with a GetOutputSize() method
to specify the number of components per pixel.
parent b43c8d3f
No related branches found
No related tags found
No related merge requests found
/*=========================================================================
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 __otbUnaryFunctorWithIndexWithOutputSizeImageFilter_h
#define __otbUnaryFunctorWithIndexWithOutputSizeImageFilter_h
#include "itkImageToImageFilter.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "itkProcessObject.h"
namespace otb
{
/** \class UnaryFunctorWithIndexWithOutputSizeImageFilter
* \brief Implements neighborhood-wise generic operation on image
*
* This class is parameterized over the input image type
* and the type of the output image. It is also parameterized by the
* operation to be applied. A Functor style is used.
*
* \ingroup IntensityImageFilters Multithreaded
*/
template <class TInputImage, class TOutputImage, class TFunction>
class ITK_EXPORT UnaryFunctorWithIndexWithOutputSizeImageFilter
: public itk::ImageToImageFilter<TInputImage, TOutputImage>
{
public:
/** Standard class typedefs. */
typedef UnaryFunctorWithIndexWithOutputSizeImageFilter Self;
typedef itk::ImageToImageFilter<TInputImage, TOutputImage> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(UnaryFunctorWithIndexWithOutputSizeImageFilter, ImageToImageFilter);
/** Some convenient typedefs. */
typedef TFunction FunctorType;
typedef typename Superclass::InputImageType InputImageType;
typedef typename InputImageType::ConstPointer InputImagePointer;
typedef typename InputImageType::RegionType InputImageRegionType;
typedef typename InputImageType::PixelType InputImagePixelType;
typedef typename InputImageType::SizeType InputImageSizeType;
typedef typename InputImageType::IndexType InputImageIndexType;
typedef typename Superclass::OutputImageType OutputImageType;
typedef typename OutputImageType::Pointer OutputImagePointer;
typedef typename OutputImageType::RegionType OutputImageRegionType;
typedef typename OutputImageType::PixelType OutputImagePixelType;
typedef itk::ProcessObject ProcessObjectType;
/** Get the functor object. The functor is returned by reference.
* (Functors do not have to derive from itk::LightObject, so they do
* not necessarily have a reference count. So we cannot return a
* SmartPointer.) */
FunctorType& GetFunctor()
{
this->Modified();
return m_Functor;
}
/** Get the functor object. The functor is returned by reference.
* (Functors do not have to derive from itk::LightObject, so they do
* not necessarily have a reference count. So we cannot return a
* SmartPointer.) */
const FunctorType& GetFunctor() const
{
return m_Functor;
}
/** Set the functor object. This replaces the current Functor with a
* copy of the specified Functor. This allows the user to specify a
* functor that has ivars set differently than the default functor.
* This method requires an operator!=() be defined on the functor
* (or the compiler's default implementation of operator!=() being
* appropriate). */
void SetFunctor(const FunctorType& functor)
{
m_Functor = functor;
this->Modified();
}
typedef itk::ImageRegionConstIteratorWithIndex<TInputImage> IteratorType;
protected:
/**
* Constructor
*/
UnaryFunctorWithIndexWithOutputSizeImageFilter();
/**
* Destructor
*/
virtual ~UnaryFunctorWithIndexWithOutputSizeImageFilter() {}
/** UnaryFunctorWithIndexWithOutputSizeImageFilter can be implemented as a multithreaded filter.
* Therefore, this implementation provides a ThreadedGenerateData() routine
* which is called for each processing thread. The output image data is
* allocated automatically by the superclass prior to calling
* ThreadedGenerateData(). ThreadedGenerateData can only write to the
* portion of the output image specified by the parameter
* "outputRegionForThread"
*
* \sa ImageToImageFilter::ThreadedGenerateData(),
* ImageToImageFilter::GenerateData() */
virtual void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId);
/**
* Pad the input requested region by radius
*/
virtual void GenerateInputRequestedRegion(void);
/** UnaryFunctorWithIndexWithOutputSizeImageFilter can produce an image which has a different number of bands
* than its input image. As such, UnaryFunctorImageFilter
* needs to provide an implementation for
* GenerateOutputInformation() in order to inform the pipeline
* execution model. The original documentation of this method is
* below.
*
* \sa ProcessObject::GenerateOutputInformaton() */
virtual void GenerateOutputInformation()
{
Superclass::GenerateOutputInformation();
typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
outputPtr->SetNumberOfComponentsPerPixel( // propagate vector length info
this->GetFunctor().GetOutputSize());
}
private:
UnaryFunctorWithIndexWithOutputSizeImageFilter(const Self &); //purposely not implemented
void operator =(const Self&); //purposely not implemented
FunctorType m_Functor;
};
} // namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbUnaryFunctorWithIndexWithOutputSizeImageFilter.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 __otbUnaryFunctorWithIndexWithOutputSizeImageFilter_txx
#define __otbUnaryFunctorWithIndexWithOutputSizeImageFilter_txx
#include "otbUnaryFunctorWithIndexWithOutputSizeImageFilter.h"
#include "itkImageRegionIterator.h"
#include "itkProgressReporter.h"
namespace otb
{
/**
* Constructor
*/
template <class TInputImage, class TOutputImage, class TFunction>
UnaryFunctorWithIndexWithOutputSizeImageFilter<TInputImage, TOutputImage, TFunction>
::UnaryFunctorWithIndexWithOutputSizeImageFilter()
{
this->SetNumberOfRequiredInputs(1);
}
template <class TInputImage, class TOutputImage, class TFunction>
void
UnaryFunctorWithIndexWithOutputSizeImageFilter<TInputImage, TOutputImage, TFunction>
::GenerateInputRequestedRegion()
{
// call the superclass' implementation of this method
Superclass::GenerateInputRequestedRegion();
// get pointers to the input and output
typename Superclass::InputImagePointer inputPtr =
const_cast<TInputImage *>(this->GetInput());
typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
if (!inputPtr || !outputPtr)
{
return;
}
// get a copy of the input requested region (should equal the output
// requested region)
typename TInputImage::RegionType inputRequestedRegion;
inputRequestedRegion = inputPtr->GetRequestedRegion();
// crop the input requested region at the input's largest possible region
if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
{
inputPtr->SetRequestedRegion(inputRequestedRegion);
return;
}
else
{
// Couldn't crop the region (requested region is outside the largest
// possible region). Throw an exception.
// store what we tried to request (prior to trying to crop)
inputPtr->SetRequestedRegion(inputRequestedRegion);
// build an exception
itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
std::ostringstream msg;
msg << this->GetNameOfClass()
<< "::GenerateInputRequestedRegion()";
e.SetLocation(msg.str().c_str());
e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
e.SetDataObject(inputPtr);
throw e;
}
}
/**
* ThreadedGenerateData Performs the neighborhood-wise operation
*/
template <class TInputImage, class TOutputImage, class TFunction>
void
UnaryFunctorWithIndexWithOutputSizeImageFilter<TInputImage, TOutputImage, TFunction>
::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId)
{
InputImagePointer inputPtr = dynamic_cast<const TInputImage*>(ProcessObjectType::GetInput(0));
OutputImagePointer outputPtr = this->GetOutput(0);
InputImageRegionType inputRegionForThread;
this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
// Define the iterators
IteratorType inputIt = IteratorType(inputPtr, inputRegionForThread);
itk::ImageRegionIterator<TOutputImage> outputIt(outputPtr, outputRegionForThread);
itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
inputIt.GoToBegin();
outputIt.GoToBegin();
while (!inputIt.IsAtEnd())
{
outputIt.Set(m_Functor(inputIt.Get(), inputIt.GetIndex()));
++inputIt;
++outputIt;
progress.CompletedPixel(); // potential exception thrown here
}
}
} // end namespace otb
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment