21 #ifndef otbGridResampleImageFilter_hxx
22 #define otbGridResampleImageFilter_hxx
29 #include "itkNumericTraits.h"
30 #include "itkProgressReporter.h"
31 #include "itkImageScanlineIterator.h"
32 #include "itkContinuousIndex.h"
37 template <
typename TInputImage,
typename TOutputImage,
typename TInterpolatorPrecision>
39 : m_OutputStartIndex(),
44 m_InterpolationMargin(0.0),
45 m_CheckOutputBounds(true),
47 m_ReachableOutputRegion()
60 this->DynamicMultiThreadingOn();
65 template <
typename TInputImage,
typename TOutputImage,
typename TInterpolatorPrecision>
68 this->SetOutputOrigin(image->GetOrigin());
70 this->SetOutputStartIndex(image->GetLargestPossibleRegion().GetIndex());
71 this->SetOutputSize(image->GetLargestPossibleRegion().GetSize());
75 template <
typename TInputImage,
typename TOutputImage,
typename TInterpolatorPrecision>
79 Superclass::GenerateOutputInformation();
89 typename TOutputImage::RegionType outputLargestPossibleRegion;
90 outputLargestPossibleRegion.SetSize(m_OutputSize);
91 outputLargestPossibleRegion.SetIndex(m_OutputStartIndex);
93 outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
94 outputPtr->SetSignedSpacing(m_OutputSpacing);
95 outputPtr->SetOrigin(m_OutputOrigin);
100 template <
typename TInputImage,
typename TOutputImage,
typename TInterpolatorPrecision>
104 Superclass::GenerateInputRequestedRegion();
107 if (!this->GetInput())
113 typename TInputImage::Pointer inputPtr =
const_cast<TInputImage*
>(this->GetInput());
122 typename TOutputImage::RegionType outputRequestedRegion = outputPtr->GetRequestedRegion();
126 typedef itk::ContinuousIndex<double, TInputImage::ImageDimension> ContinuousIndexType;
128 ContinuousIndexType inULCIndex, inLRCIndex;
131 outULIndex = outputRequestedRegion.GetIndex();
132 outLRIndex = outULIndex + outputRequestedRegion.GetSize();
138 outputPtr->TransformIndexToPhysicalPoint(outULIndex, outULPoint);
139 outputPtr->TransformIndexToPhysicalPoint(outLRIndex, outLRPoint);
142 inputPtr->TransformPhysicalPointToContinuousIndex(outULPoint, inULCIndex);
143 inputPtr->TransformPhysicalPointToContinuousIndex(outLRPoint, inLRCIndex);
149 for (
unsigned int dim = 0; dim < ImageDimension; ++dim)
151 if (inULCIndex[dim] > inLRCIndex[dim])
154 typename ContinuousIndexType::ValueType tmp(inULCIndex[dim]);
155 inULCIndex[dim] = inLRCIndex[dim];
156 inLRCIndex[dim] = tmp;
161 inULIndex[dim] = std::floor(inULCIndex[dim]);
162 inLRIndex[dim] = std::ceil(inLRCIndex[dim]);
164 inSize[dim] =
static_cast<typename SizeType::SizeValueType
>(inLRIndex[dim] - inULIndex[dim]) + 1;
168 typename TInputImage::RegionType inputRequestedRegion;
169 inputRequestedRegion.SetIndex(inULIndex);
170 inputRequestedRegion.SetSize(inSize);
174 inputRequestedRegion.PadByRadius(interpolatorRadius);
177 if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
179 inputPtr->SetRequestedRegion(inputRequestedRegion);
185 inputPtr->SetRequestedRegion(inputRequestedRegion);
188 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
189 e.SetLocation(ITK_LOCATION);
190 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
191 e.SetDataObject(inputPtr);
197 template <
typename TInputImage,
typename TOutputImage,
typename TInterpolatorPrecision>
202 itkExceptionMacro(<<
"Interpolator not set");
206 m_Interpolator->SetInputImage(this->GetInput());
211 if (nComponents == 0)
217 nComponents = this->GetInput()->GetNumberOfComponentsPerPixel();
219 itk::NumericTraits<OutputPixelType>::SetLength(m_EdgePaddingValue, nComponents);
220 for (
unsigned int n = 0; n < nComponents; n++)
222 OutputPixelConvertType::SetNthComponent(n, m_EdgePaddingValue, zeroComponent);
233 IndexType inUL = this->GetInput()->GetBufferedRegion().GetIndex();
234 IndexType inLR = this->GetInput()->GetBufferedRegion().GetIndex() + this->GetInput()->GetBufferedRegion().GetSize();
248 this->GetInput()->TransformIndexToPhysicalPoint(inUL, inULp);
249 this->GetInput()->TransformIndexToPhysicalPoint(inLR, inLRp);
251 inULp -= (0.5 - m_InterpolationMargin) * this->GetInput()->GetSignedSpacing();
252 inLRp += (0.5 - m_InterpolationMargin) * this->GetInput()->GetSignedSpacing();
256 this->GetOutput()->TransformPhysicalPointToContinuousIndex(inULp, outUL);
257 this->GetOutput()->TransformPhysicalPointToContinuousIndex(inLRp, outLR);
261 outputIndex[0] = std::ceil(std::min(outUL[0], outLR[0]));
262 outputIndex[1] = std::ceil(std::min(outUL[1], outLR[1]));
265 outputSize[0] = std::floor(std::max(outUL[0], outLR[0])) - outputIndex[0] + 1;
266 outputSize[1] = std::floor(std::max(outUL[1], outLR[1])) - outputIndex[1] + 1;
268 m_ReachableOutputRegion.SetIndex(outputIndex);
269 m_ReachableOutputRegion.SetSize(outputSize);
271 otbMsgDevMacro(<<
"ReachableOutputRegion: " << m_ReachableOutputRegion);
274 template <
typename TInputImage,
typename TOutputImage,
typename TInterpolatorPrecision>
293 bool cropSucceed = regionToCompute.Crop(m_ReachableOutputRegion);
296 itk::ImageScanlineIterator<OutputImageType> outItFull(outputPtr, outputRegionForThread);
297 outItFull.GoToBegin();
298 while (!outItFull.IsAtEnd())
300 while (!outItFull.IsAtEndOfLine())
302 outItFull.Set(m_EdgePaddingValue);
305 outItFull.NextLine();
311 itk::ImageScanlineIterator<OutputImageType> outIt(outputPtr, regionToCompute);
321 assert(outputPtr->GetSignedSpacing()[0] != 0 &&
"Null spacing will cause division by zero.");
322 const double delta = outputPtr->GetSignedSpacing()[0] / inputPtr->GetSignedSpacing()[0];
327 while (!outIt.IsAtEnd())
330 outputPtr->TransformIndexToPhysicalPoint(outIt.GetIndex(), outPoint);
331 inputPtr->TransformPhysicalPointToContinuousIndex(outPoint, inCIndex);
333 while (!outIt.IsAtEndOfLine())
336 interpolatorValue = m_Interpolator->EvaluateAtContinuousIndex(inCIndex);
339 this->CastPixelWithBoundsChecking(interpolatorValue, minOutputValue, maxOutputValue, outputValue);
342 outIt.Set(outputValue);
348 inCIndex[0] += delta;
356 template <
typename TInputImage,
typename TOutputImage,
typename TInterpolatorPrecision>
360 m_Interpolator->SetInputImage(
nullptr);
364 template <
typename TInputImage,
typename TOutputImage,
typename TInterpolatorPrecision>
367 itk::ModifiedTimeType latestTime = itk::Object::GetMTime();
371 if (latestTime < m_Interpolator->GetMTime())
373 latestTime = m_Interpolator->GetMTime();
381 template <
typename TInputImage,
typename TOutputImage,
typename TInterpolatorPrecision>
384 Superclass::PrintSelf(os, indent);
386 os << indent <<
"EdgePaddingValue: " <<
static_cast<typename itk::NumericTraits<OutputPixelType>::PrintType
>(m_EdgePaddingValue) << std::endl;
387 os << indent <<
"OutputStartIndex: " << m_OutputStartIndex << std::endl;
388 os << indent <<
"OutputSize: " << m_OutputSize << std::endl;
389 os << indent <<
"OutputOrigin: " << m_OutputOrigin << std::endl;
390 os << indent <<
"OutputSpacing: " << m_OutputSpacing << std::endl;
391 os << indent <<
"Interpolator: " << m_Interpolator.GetPointer() << std::endl;
392 os << indent <<
"CheckOutputBounds: " << (m_CheckOutputBounds ?
"On" :
"Off") << std::endl;
ImageBaseType::PointType PointType
ImageBaseType::SizeType SizeType
void SetOutputParametersFromImage(const ImageBaseType *image)
InterpolatorConvertType::ComponentType InterpolatorComponentType
SpacingType m_OutputSpacing
void PrintSelf(std::ostream &os, itk::Indent indent) const override
OutputImageType::RegionType OutputImageRegionType
void GenerateInputRequestedRegion() override
GridResampleImageFilter()
itk::InterpolateImageFunction< InputImageType, TInterpolatorPrecision > InterpolatorType
itk::ModifiedTimeType GetMTime(void) const override
itk::ImageBase< OutputImageType::ImageDimension > ImageBaseType
OutputPixelConvertType::ComponentType OutputPixelComponentType
InterpolatorPointerType m_Interpolator
void AfterThreadedGenerateData() override
ImageBaseType::IndexType IndexType
TOutputImage OutputImageType
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) override
void GenerateOutputInformation() override
itk::ContinuousIndex< double, InputImageDimension > ContinuousInputIndexType
IndexType m_OutputStartIndex
TInputImage InputImageType
InterpolatorType::OutputType InterpolatorOutputType
void BeforeThreadedGenerateData() override
OutputPixelType m_EdgePaddingValue
TOutputImage::PixelType OutputPixelType
static unsigned int CalculateNeededRadiusForInterpolator(const InterpolationType *interpolator)
ImageType::SpacingType GetSignedSpacing(const ImageType *input)
unsigned int GetNumberOfComponents(PixelType const &pix)
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
#define otbMsgDevMacro(x)