Commit 241149b0 authored by Cyrille Valladeau's avatar Cyrille Valladeau
Browse files

ENH : cplx calib + functor filter that uses index

parent d00cf363
/*=========================================================================
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 __otbUnaryFunctorWithIndexImageFilter_h
#define __otbUnaryFunctorWithIndexImageFilter_h
#include "itkImageToImageFilter.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "itkProcessObject.h"
namespace otb
{
/** \class UnaryFunctorWithIndexImageFilter
* \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 UnaryFunctorWithIndexImageFilter
: public itk::ImageToImageFilter<TInputImage,TOutputImage>
{
public:
/** Standard class typedefs. */
typedef UnaryFunctorWithIndexImageFilter 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(UnaryFunctorWithIndexImageFilter,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
*/
UnaryFunctorWithIndexImageFilter();
/**
* Destructor
*/
virtual ~UnaryFunctorWithIndexImageFilter() {};
/** UnaryFunctorWithIndexImageFilter 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);
private:
UnaryFunctorWithIndexImageFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
FunctorType m_Functor;
};
} // namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbUnaryFunctorWithIndexImageFilter.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 __otbUnaryFunctorWithIndexImageFilter_txx
#define __otbUnaryFunctorWithIndexImageFilter_txx
#include "otbUnaryFunctorWithIndexImageFilter.h"
#include "itkImageRegionIterator.h"
#include "itkProgressReporter.h"
namespace otb
{
/**
* Constructor
*/
template <class TInputImage, class TOutputImage, class TFunction >
UnaryFunctorWithIndexImageFilter<TInputImage,TOutputImage,TFunction>
::UnaryFunctorWithIndexImageFilter()
{
this->SetNumberOfRequiredInputs( 1 );
}
template <class TInputImage, class TOutputImage, class TFunction >
void
UnaryFunctorWithIndexImageFilter<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__);
itk::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
UnaryFunctorWithIndexImageFilter<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
......@@ -123,7 +123,7 @@ private:
* \ingroup Functor
* \ingroup Radiometry
*/
template<class TInputIt, class TOutput>
template<class TInput, class TOutput>
class TerraSarCalibrationImageFunctor
{
public:
......@@ -134,8 +134,9 @@ public:
typedef std::vector<DoubleVectorType> DoubleVectorVectorType;
typedef std::vector<long int> LIntVectorType;
typedef itk::Size<2> SizeType;
typedef typename TInputIt::PixelType InputPixelType;
typedef TerraSarRadarBrightnessImageFunctor<InputPixelType, TOutput> BrightnessFunctorType;
typedef itk::Index<2> IndexType;
//typedef typename TInputIt::PixelType InputPixelType;
typedef TerraSarRadarBrightnessImageFunctor<TInput, TOutput> BrightnessFunctorType;
/** Accessors */
void SetCalFactor( double val ) { m_CalFactor = val; m_RadarBrightness.SetCalFactor(val); };
......@@ -164,10 +165,13 @@ public:
void SetPRF( double val ) { m_PRF = val; m_InvPRF = 1./m_PRF; };
double GetPRF() const { return m_PRF; };
double GetInvPRF() const { return m_InvPRF; };
//BrightnessFunctorType GetRadarBrightness() const { return m_RadarBrightness; };
//BrightnessFunctorType GetRadarBrightness() { return m_RadarBrightness; };
double ComputeCurrentNoise( unsigned int colId );
DoubleVectorType ComputeCurrentCoeffs( unsigned int lineId );
inline TOutput operator() (const TInputIt & inIt);
inline TOutput operator() (const TInput & inPix, IndexType index);
private:
/** Calibration Factor */
......@@ -198,8 +202,10 @@ private:
double m_InvPRF;
/** Radar Brightness functor */
BrightnessFunctorType m_RadarBrightness;
};
/** TODO : Use inheritance **/
/**
* \class TerraSarCalibrationComplexImageFunctor
......@@ -209,53 +215,84 @@ private:
* \ingroup Radiometry
*/
template <class TInput, class TOutput>
class TerraSarCalibrationComplexImageFunctor
class TerraSarCalibrationComplexImageFunctor
{
public:
TerraSarCalibrationComplexImageFunctor() {};
TerraSarCalibrationComplexImageFunctor();
virtual ~TerraSarCalibrationComplexImageFunctor() {};
typedef std::vector<double> DoubleVectorType;
typedef std::vector<DoubleVectorType> DoubleVectorVectorType;
typedef std::vector<long int> LIntVectorType;
typedef itk::Size<2> SizeType;
typedef TerraSarCalibrationImageFunctor<TInput, TOutput> SigmaNaughtFunctorType;
typedef itk::Index<2> IndexType;
//typedef typename TInputIt::PixelType InputPixelType;
typedef TerraSarRadarBrightnessImageFunctor<double, double> BrightnessFunctorType;
/** Accessors */
void SetCalFactor( double val ) { m_SigmaNaughtFunctor.SetCalFactor(val); };
double GetCalFactor() { return m_SigmaNaughtFunctor.GetCalFactor(); };
void SetNoiseRangeValidityMin( double val ) { m_SigmaNaughtFunctor.SetNoiseRangeValidityMin(val); };
double GetNoiseRangeValidityMin() { return m_SigmaNaughtFunctor.GetNoiseRangeValidityMin(); };
void SetNoiseRangeValidityMax( double val ) { m_SigmaNaughtFunctor.SetNoiseRangeValidityMax(val); };
double GetNoiseRangeValidityMax() { return m_SigmaNaughtFunctor.GetNoiseRangeValidityMax(); };
void SetNoiseRangeValidityRef( double val ) { m_SigmaNaughtFunctor.SetNoiseRangeValidityRe(val); };
double GetNoiseRangeValidityRef() { return m_SigmaNaughtFunctor.GetNoiseRangeValidityRef(); };
void SetLocalIncidentAngle( double val ){m_SigmaNaughtFunctor.SetLocalIncidentAngle(val);};
double GetLocalIncidentAngle() { return m_SigmaNaughtFunctor.GetLocalIncidentAngle(); };
double GetSinLocalIncidentAngle() const { return m_SigmaNaughtFunctor.GetSinLocalIncidentAngle(); };
void SetNoisePolynomialCoefficientsList( DoubleVectorVectorType vect ) { m_SigmaNaughtFunctor.SetNoisePolynomialCoefficientsList(vect); };
DoubleVectorVectorType GetNoisePolynomialCoefficientsList() { return m_SigmaNaughtFunctor.GetNoisePolynomialCoefficientsList(); };
void SetImageSize( SizeType size ) { m_SigmaNaughtFunctor.SetImageSize(size); };
SizeType GetImageSize() { return m_SigmaNaughtFunctor.GetImageSize(); };
/* We assume that the input pixel is a complex */
inline TOutput operator() (const TInput & inPix)
{
// Beta naught computation, will be the Modulus of the result
double sigma = m_SigmaNaughtFunctor(std::abs(inPix));
// Phase
double phase = std::arg(inPix);
void SetCalFactor( double val ) { m_CalFactor = val; m_RadarBrightness.SetCalFactor(val); };
double GetCalFactor() const { return m_CalFactor; };
void SetNoiseRangeValidityMin( double val ) { m_NoiseRangeValidityMin = val; };
double GetNoiseRangeValidityMin() const { return m_NoiseRangeValidityMin; };
void SetNoiseRangeValidityMax( double val ) { m_NoiseRangeValidityMax = val; };
double GetNoiseRangeValidityMax() const { return m_NoiseRangeValidityMax; };
void SetNoiseRangeValidityRef( double val ) { m_NoiseRangeValidityRef = val; };
double GetNoiseRangeValidityRef() const { return m_NoiseRangeValidityRef; };
void SetLocalIncidentAngle( double val )
{
m_LocalIncidentAngle = val;
m_SinLocalIncidentAngle = vcl_sin(m_LocalIncidentAngle*CONST_PI_180);
};
double GetLocalIncidentAngle() const { return m_LocalIncidentAngle; };
double GetSinLocalIncidentAngle() const { return m_SinLocalIncidentAngle; };
void SetNoisePolynomialCoefficientsList( DoubleVectorVectorType vect ) { m_NoisePolynomialCoefficientsList = vect; };
DoubleVectorVectorType GetNoisePolynomialCoefficientsList() const { return m_NoisePolynomialCoefficientsList; };
void SetImageSize( SizeType size ) { m_ImageSize = size; };
SizeType GetImageSize() const { return m_ImageSize; };
void SetUseFastCalibrationMethod( bool b ) { m_UseFastCalibrationMethod = b; };
bool GetUseFastCalibrationMethod() const { return m_UseFastCalibrationMethod; };
void SetTimeUTC( LIntVectorType vect ) { m_TimeUTC = vect; };
LIntVectorType GetTimeUTC() const { return m_TimeUTC; };
void SetPRF( double val ) { m_PRF = val; m_InvPRF = 1./m_PRF; };
double GetPRF() const { return m_PRF; };
double GetInvPRF() const { return m_InvPRF; };
//BrightnessFunctorType GetRadarBrightness() const { return m_RadarBrightness; };
//BrightnessFunctorType GetRadarBrightness() { return m_RadarBrightness; };
// We retrieve the complex value from the modulus and the phase.
std::complex<double> res = std::complex<double>(sigma*vcl_cos(phase), sigma*vcl_sin(phase) );
double ComputeCurrentNoise( unsigned int colId );
DoubleVectorType ComputeCurrentCoeffs( unsigned int lineId );
inline TOutput operator() (const TInput & inPix, IndexType index);
return static_cast<TOutput>(res);
}
private:
/** Calibration Factor */
SigmaNaughtFunctorType m_SigmaNaughtFunctor;
double m_CalFactor;
/** Noise minimal range validity */
double m_NoiseRangeValidityMin;
/** Noise maxinimal range validity */
double m_NoiseRangeValidityMax;
/** Noise reference range */
double m_NoiseRangeValidityRef;
/** Sensor local incident angle in degree */
double m_LocalIncidentAngle;
/** sin of the LocalIncidentAngle */
double m_SinLocalIncidentAngle;
/** Vector of vector that contain noise polinomial coefficient */
DoubleVectorVectorType m_NoisePolynomialCoefficientsList;
/** Image Size */
SizeType m_ImageSize;
/** Fast Calibration Method. If set to trus, will consider only the first noise coefficient else,
* will use all of them and applied it according to its acquisition UTC time and the coordinates
* of the pixel in the image. */
bool m_UseFastCalibrationMethod;
/** TimeUTC for each noise coefficient acquisition (in second). */
LIntVectorType m_TimeUTC;
/** Pulse Repetition Frequency */
double m_PRF;
/** Inverse Pulse Repetition Frequency */
double m_InvPRF;
/** Radar Brightness functor */
BrightnessFunctorType m_RadarBrightness;
};
}// end namespace functor
......
......@@ -29,8 +29,8 @@ namespace otb
namespace Functor
{
/** Constructor */
template <class TInputIt, class TOutput>
TerraSarCalibrationImageFunctor<TInputIt, TOutput>
template <class TInput, class TOutput>
TerraSarCalibrationImageFunctor<TInput, TOutput>
::TerraSarCalibrationImageFunctor()
{
m_CalFactor = 1.;
......@@ -46,9 +46,9 @@ TerraSarCalibrationImageFunctor<TInputIt, TOutput>
}
template <class TInputIt, class TOutput>
template <class TInput, class TOutput>
double
TerraSarCalibrationImageFunctor<TInputIt, TOutput>
TerraSarCalibrationImageFunctor<TInput, TOutput>
::ComputeCurrentNoise( unsigned int colId )
{
double curRange = 0.;
......@@ -68,9 +68,9 @@ TerraSarCalibrationImageFunctor<TInputIt, TOutput>
}
template <class TInputIt, class TOutput>
typename TerraSarCalibrationImageFunctor<TInputIt, TOutput>::DoubleVectorType
TerraSarCalibrationImageFunctor<TInputIt, TOutput>
template <class TInput, class TOutput>
typename TerraSarCalibrationImageFunctor<TInput, TOutput>::DoubleVectorType
TerraSarCalibrationImageFunctor<TInput, TOutput>
::ComputeCurrentCoeffs( unsigned int lineId )
{
DoubleVectorType curCoeffs;
......@@ -107,15 +107,15 @@ TerraSarCalibrationImageFunctor<TInputIt, TOutput>
return curCoeffs;
}
template <class TInputIt, class TOutput>
inline TOutput
TerraSarCalibrationImageFunctor<TInputIt, TOutput>
::operator() (const TInputIt & inIt)
template <class TInput, class TOutput>
TOutput
TerraSarCalibrationImageFunctor<TInput, TOutput>
::operator()(const TInput & inPix, IndexType index)
{
double diffCurRange = ComputeCurrentNoise( static_cast<unsigned int>(inIt.GetIndex()[0]) ) - m_NoiseRangeValidityRef;
DoubleVectorType curCoeff = ComputeCurrentCoeffs( static_cast<unsigned int>(inIt.GetIndex()[1]) );
double diffCurRange = ComputeCurrentNoise( static_cast<unsigned int>(index[0]) ) - m_NoiseRangeValidityRef;
DoubleVectorType curCoeff = ComputeCurrentCoeffs( static_cast<unsigned int>(index[1]) );
TOutput outRadBr = m_RadarBrightness( inIt.GetCenterPixel() );
TOutput outRadBr = m_RadarBrightness( inPix );
double NEBN = 0.;
for(int i=0; i<curCoeff.size(); i++)
......@@ -126,7 +126,112 @@ TerraSarCalibrationImageFunctor<TInputIt, TOutput>
return static_cast<TOutput>(sigma);
}
/** Constructor */
template <class TInput, class TOutput>
TerraSarCalibrationComplexImageFunctor<TInput, TOutput>
::TerraSarCalibrationComplexImageFunctor()
{
m_CalFactor = 1.;
m_NoiseRangeValidityMin = 0.;
m_NoiseRangeValidityMax = 0.;
m_NoiseRangeValidityRef = 0.;
m_LocalIncidentAngle = 0.;
m_NoisePolynomialCoefficientsList.clear();
m_ImageSize.Fill(0);
m_UseFastCalibrationMethod = true;
m_TimeUTC.clear();
m_PRF = 1.;
}
template <class TInput, class TOutput>
double
TerraSarCalibrationComplexImageFunctor<TInput, TOutput>
::ComputeCurrentNoise( unsigned int colId )
{
double curRange = 0.;
double width_2 = static_cast<double>(m_ImageSize[0])/2.;
// Use +1 because image start index is 0
if( colId < static_cast<unsigned int>(width_2) )
{
curRange = m_NoiseRangeValidityMin + ( m_NoiseRangeValidityRef-m_NoiseRangeValidityMin )/width_2 * static_cast<double>(colId+1);
}
else
{
curRange = m_NoiseRangeValidityRef + ( m_NoiseRangeValidityMax-m_NoiseRangeValidityRef )/width_2 * (static_cast<double>(colId+1) - width_2 );
}
return curRange;
}
template <class TInput, class TOutput>
typename TerraSarCalibrationComplexImageFunctor<TInput, TOutput>::DoubleVectorType
TerraSarCalibrationComplexImageFunctor<TInput, TOutput>
::ComputeCurrentCoeffs( unsigned int lineId )
{
DoubleVectorType curCoeffs;
if(m_UseFastCalibrationMethod)
{
curCoeffs = m_NoisePolynomialCoefficientsList[0];
}
else
{
// m_ImageSize[1]-(lineId+1) because the first acquisition line is the last image one.
// line+1 because image starts to 0.
double interval = static_cast<double>(m_ImageSize[1]) / static_cast<double>(m_NoisePolynomialCoefficientsList.size());
// compute utc time of the line
double currTimeUTC = m_TimeUTC[0] + static_cast<double>(m_ImageSize[1]-(lineId-1))*m_InvPRF;
unsigned int id = 0;
bool go = true;
// deduct the corresponding noise acquisition index
while( id<m_TimeUTC.size() && go)
{
if( currTimeUTC < m_TimeUTC[id] )
go = false;
id++;
}
id--;
double timeCoef = 1. / (m_TimeUTC[id]- m_TimeUTC[id-1]) * (currTimeUTC-m_TimeUTC[id-1]);
for(unsigned int j=0; j<m_NoisePolynomialCoefficientsList.size(); j++)
{
curCoeffs.push_back( m_NoisePolynomialCoefficientsList[id-1][j] + (m_NoisePolynomialCoefficientsList[id][j] - m_NoisePolynomialCoefficientsList[id-1][j]) * timeCoef );
}
}
return curCoeffs;
}
template <class TInput, class TOutput>
TOutput
TerraSarCalibrationComplexImageFunctor<TInput, TOutput>
::operator()(const TInput & inPix, IndexType index)
{
double diffCurRange = this->ComputeCurrentNoise( static_cast<unsigned int>(index[0]) ) - this->GetNoiseRangeValidityRef();
DoubleVectorType curCoeff = this->ComputeCurrentCoeffs( static_cast<unsigned int>(index[1]) );
double modulus = std::abs(inPix);
double outRadBr = static_cast<double>(m_RadarBrightness( modulus ));
double NEBN = 0.;
for(int i=0; i<curCoeff.size(); i++)
{
NEBN += curCoeff[i]*vcl_pow( diffCurRange, i);
}
double sigma = ( outRadBr - this->GetCalFactor()*NEBN ) * this->GetSinLocalIncidentAngle();
double phase = std::arg(inPix);
TOutput out(sigma*vcl_cos(phase), sigma*vcl_sin(phase));
return out;
}
}// namespace Functor
} // namespace otb
......
......@@ -23,10 +23,10 @@
#define __otbTerraSarCalibrationImageFilter_h
#include "otbUnaryFunctorNeighborhoodImageFilter.h"
#include "otbUnaryFunctorWithIndexImageFilter.h"
#include "otbRadarFunctors.h"
#include "itkMetaDataDictionary.h"
#include "itkConstNeighborhoodIterator.h"
//#include "itkConstNeighborhoodIterator.h"
#include "otbMath.h"
namespace otb
......@@ -46,10 +46,10 @@ namespace otb
template<class TInputImage, class TOutputImage >
class ITK_EXPORT TerraSarCalibrationImageFilter :
public UnaryFunctorNeighborhoodImageFilter<
public UnaryFunctorWithIndexImageFilter<