1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
/*=========================================================================
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 otbConvolutionImageFilter_h
#define otbConvolutionImageFilter_h
#include "itkImageToImageFilter.h"
#include "itkImage.h"
#include "itkNumericTraits.h"
#include "itkArray.h"
#include "itkZeroFluxNeumannBoundaryCondition.h"
namespace otb
{
/** \class ConvolutionImageFilter
* \brief Applies a convolution filter to a mono channel image
*
* Computes an image which is the convolution of the input image
* with a filter.
*
* The radius of the input filter is provided by the \code SetInput() \endcode
* method and the filters coefficients are given by an itk::Array passed to the
* \code SetFilter() \endcode method.
*
* By default, the input filter is not normalized but it can be using the
* NormalizeFilterOn() method.
*
* This filter allows the user to choose the boundary condtions in the template parameters.
Default boundary conditions are zero flux Neumann boundary conditions.
*
* An optimized version of this filter using FFTW is available in the Orfeo ToolBox and
* will significantly improves performances especially for large kernels
* (see OverlapSaveConvolutionImageFilter).
*
* \sa Image
* \sa Neighborhood
* \sa NeighborhoodOperator
* \sa NeighborhoodIterator
* \sa ImageBoundaryCondition
* \sa ZeroFluxNeumannBoundaryCondition
* \sa OverlapSaveConvolutionImageFilter
*
* \ingroup IntensityImageFilters
* \ingroup Streamed
* \ingroup MultiThreaded
*
* \ingroup OTBConvolution
*/
template <class TInputImage, class TOutputImage, class TBoundaryCondition =
itk::ZeroFluxNeumannBoundaryCondition<TInputImage>,
class TFilterPrecision = typename itk::NumericTraits<typename TInputImage::InternalPixelType>::RealType>
class ITK_EXPORT ConvolutionImageFilter :
public itk::ImageToImageFilter<TInputImage, TOutputImage>
{
public:
/** Extract dimension from input and output image. */
itkStaticConstMacro(InputImageDimension, unsigned int,
TInputImage::ImageDimension);
itkStaticConstMacro(OutputImageDimension, unsigned int,
TOutputImage::ImageDimension);
/** Convenient typedefs for simplifying declarations. */
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
/** Standard class typedefs. */
typedef ConvolutionImageFilter Self;
typedef itk::ImageToImageFilter<InputImageType, OutputImageType> 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(ConvolutionImageFilter, ImageToImageFilter);
/** Image typedef support. */
typedef typename InputImageType::PixelType InputPixelType;
typedef typename OutputImageType::PixelType OutputPixelType;
typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType;
typedef typename InputImageType::RegionType InputImageRegionType;
typedef typename OutputImageType::RegionType OutputImageRegionType;
typedef typename InputImageType::SizeType InputSizeType;
typedef TFilterPrecision FilterPrecisionType;
typedef typename itk::Array<FilterPrecisionType> ArrayType;
typedef TBoundaryCondition BoundaryConditionType;
/** Set the radius of the neighborhood of the filter */
virtual void SetRadius(const InputSizeType rad)
{
itkDebugMacro("setting radius to " << rad);
if (this->m_Radius != rad)
{
this->m_Radius = rad;
unsigned int arraySize = 1;
for (unsigned int i = 0; i < m_Radius.GetSizeDimension(); ++i)
{
arraySize *= 2 * this->m_Radius[i] + 1;
}
this->m_Filter.SetSize(arraySize);
this->m_Filter.Fill(1);
this->Modified();
}
}
/** Get the radius of the neighborhood of the filter*/
itkGetConstReferenceMacro(Radius, InputSizeType);
/** Set the input filter */
virtual void SetFilter(ArrayType filter)
{
if (filter.Size() != m_Filter.Size())
{
itkExceptionMacro(
"Error in SetFilter, invalid filter size:" << filter.Size() <<
" instead of (2*m_Radius[0]+1)*(2*m_Radius[1]+1): " << m_Filter.Size());
}
else
{
m_Filter = filter;
}
this->Modified();
}
itkGetConstReferenceMacro(Filter, ArrayType);
/**
* Set/Get methods for the normalization of the filter
*/
itkSetMacro(NormalizeFilter, bool);
itkGetMacro(NormalizeFilter, bool);
itkBooleanMacro(NormalizeFilter);
#ifdef ITK_USE_CONCEPT_CHECKING
/** Begin concept checking */
itkConceptMacro(InputHasNumericTraitsCheck,
(itk::Concept::HasNumericTraits<InputPixelType>));
/** End concept checking */
#endif
protected:
ConvolutionImageFilter();
~ConvolutionImageFilter() ITK_OVERRIDE {}
void PrintSelf(std::ostream& os, itk::Indent indent) const ITK_OVERRIDE;
/** ConvolutionImageFilter 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() */
void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
itk::ThreadIdType threadId) ITK_OVERRIDE;
/** ConvolutionImageFilter needs a larger input requested region than
* the output requested region. As such, ConvolutionImageFilter needs
* to provide an implementation for GenerateInputRequestedRegion()
* in order to inform the pipeline execution model.
*
* \sa ImageToImageFilter::GenerateInputRequestedRegion() */
void GenerateInputRequestedRegion()
throw(itk::InvalidRequestedRegionError) ITK_OVERRIDE;
private:
ConvolutionImageFilter(const Self &); //purposely not implemented
void operator =(const Self&); //purposely not implemented
/** Radius of the filter */
InputSizeType m_Radius;
/** Array containing the filter values */
ArrayType m_Filter;
/** Flag for filter coefficients normalization */
bool m_NormalizeFilter;
};
} // end namespace itk
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbConvolutionImageFilter.txx"
#endif
#endif
|