OTB  9.0.0
Orfeo Toolbox
otbUnaryFunctorNeighborhoodWithOffsetImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbUnaryFunctorNeighborhoodWithOffsetImageFilter_hxx
22 #define otbUnaryFunctorNeighborhoodWithOffsetImageFilter_hxx
23 
25 #include "itkImageRegionIterator.h"
26 #include "itkNeighborhoodAlgorithm.h"
27 #include "itkProgressReporter.h"
28 #include "itkZeroFluxNeumannBoundaryCondition.h"
29 #include "itkNeighborhoodAlgorithm.h"
30 
31 namespace otb
32 {
36 template <class TInputImage, class TOutputImage, class TFunction>
38 {
39  this->SetNumberOfRequiredInputs(1);
40  m_Radius.Fill(1);
41  m_Offset.Fill(1);
42  m_FunctorList.clear();
43 }
45 
46 template <class TInputImage, class TOutputImage, class TFunction>
48 {
49  Superclass::BeforeThreadedGenerateData();
50 
51  for (itk::ThreadIdType i = 0; i < this->GetNumberOfThreads(); ++i)
52  {
53  m_FunctorList.push_back(m_Functor);
54  }
55 }
56 
57 template <class TInputImage, class TOutputImage, class TFunction>
59 {
60  // call the superclass' implementation of this method
61  Superclass::GenerateInputRequestedRegion();
62 
63  // get pointers to the input and output
64  typename Superclass::InputImagePointer inputPtr = const_cast<TInputImage*>(this->GetInput());
65  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
66 
67  if (!inputPtr || !outputPtr)
68  {
69  return;
70  }
71  // get a copy of the input requested region (should equal the output
72  // requested region)
73  typename TInputImage::RegionType inputRequestedRegion;
74  inputRequestedRegion = inputPtr->GetRequestedRegion();
75 
76  // pad the input requested region by the operator radius
77  InputImageSizeType maxRad;
78  maxRad[0] = m_Radius[0] + std::abs(m_Offset[0]);
79  maxRad[1] = m_Radius[1] + std::abs(m_Offset[1]);
80  inputRequestedRegion.PadByRadius(maxRad);
81 
82  // crop the input requested region at the input's largest possible region
83  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
84  {
85  inputPtr->SetRequestedRegion(inputRequestedRegion);
86  return;
87  }
88  else
89  {
90  // Couldn't crop the region (requested region is outside the largest
91  // possible region). Throw an exception.
92 
93  // store what we tried to request (prior to trying to crop)
94  inputPtr->SetRequestedRegion(inputRequestedRegion);
95 
96  // build an exception
97  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
98  std::ostringstream msg;
99  msg << this->GetNameOfClass() << "::GenerateInputRequestedRegion()";
100  e.SetLocation(msg.str());
101  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
102  e.SetDataObject(inputPtr);
103  throw e;
104  }
105 }
106 
110 template <class TInputImage, class TOutputImage, class TFunction>
112  const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
113 {
114  itk::ZeroFluxNeumannBoundaryCondition<TInputImage> nbc;
115  itk::ZeroFluxNeumannBoundaryCondition<TInputImage> nbcOff;
116  // We use dynamic_cast since inputs are stored as DataObjects. The
117  // ImageToImageFilter::GetInput(int) always returns a pointer to a
118  // TInputImage so it cannot be used for the second input.
119  InputImagePointer inputPtr = dynamic_cast<const TInputImage*>(ProcessObjectType::GetInput(0));
120  OutputImagePointer outputPtr = this->GetOutput(0);
122 
123  itk::ImageRegionIterator<TOutputImage> outputIt;
124 
125  // Neighborhood+offset iterator
126  RadiusType rOff;
127  rOff[0] = m_Radius[0] + std::abs(m_Offset[0]);
128  rOff[1] = m_Radius[1] + std::abs(m_Offset[1]);
129  NeighborhoodIteratorType neighInputOffIt;
130  // Find the data-set boundary "faces"
131  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage>::FaceListType faceListOff;
132  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage> bCOff;
133  faceListOff = bCOff(inputPtr, outputRegionForThread, rOff);
134  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage>::FaceListType::iterator fitOff;
135 
136  // support progress methods/callbacks
137  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
138 
139  // Process each of the boundary faces. These are N-d regions which border
140  // the edge of the buffer.
141  fitOff = faceListOff.begin();
142 
143  while (fitOff != faceListOff.end())
144  {
145  // Neighborhood+offset iterator
146  neighInputOffIt = itk::ConstNeighborhoodIterator<TInputImage>(rOff, inputPtr, *fitOff);
147  neighInputOffIt.OverrideBoundaryCondition(&nbcOff);
148  neighInputOffIt.GoToBegin();
149 
150  outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, *fitOff);
151 
152  while (!outputIt.IsAtEnd())
153  {
154 
155  outputIt.Set(m_FunctorList[threadId](neighInputOffIt.GetNeighborhood()));
156 
157  ++neighInputOffIt;
158  ++outputIt;
159  progress.CompletedPixel();
160  }
161  ++fitOff;
162  }
163 }
164 
165 } // end namespace otb
166 
167 #endif
otb::UnaryFunctorNeighborhoodWithOffsetImageFilter::BeforeThreadedGenerateData
void BeforeThreadedGenerateData() override
Definition: otbUnaryFunctorNeighborhoodWithOffsetImageFilter.hxx:47
otb::UnaryFunctorNeighborhoodWithOffsetImageFilter::UnaryFunctorNeighborhoodWithOffsetImageFilter
UnaryFunctorNeighborhoodWithOffsetImageFilter()
Definition: otbUnaryFunctorNeighborhoodWithOffsetImageFilter.hxx:37
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::UnaryFunctorNeighborhoodWithOffsetImageFilter::RadiusType
NeighborhoodIteratorType::RadiusType RadiusType
Definition: otbUnaryFunctorNeighborhoodWithOffsetImageFilter.h:128
otb::UnaryFunctorNeighborhoodWithOffsetImageFilter::NeighborhoodIteratorType
itk::ConstNeighborhoodIterator< TInputImage > NeighborhoodIteratorType
Definition: otbUnaryFunctorNeighborhoodWithOffsetImageFilter.h:127
otb::UnaryFunctorNeighborhoodWithOffsetImageFilter::GenerateInputRequestedRegion
void GenerateInputRequestedRegion(void) override
Definition: otbUnaryFunctorNeighborhoodWithOffsetImageFilter.hxx:58
otb::UnaryFunctorNeighborhoodWithOffsetImageFilter::InputImagePointer
InputImageType::ConstPointer InputImagePointer
Definition: otbUnaryFunctorNeighborhoodWithOffsetImageFilter.h:61
otb::UnaryFunctorNeighborhoodWithOffsetImageFilter::ThreadedGenerateData
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId) override
Definition: otbUnaryFunctorNeighborhoodWithOffsetImageFilter.hxx:111
otbUnaryFunctorNeighborhoodWithOffsetImageFilter.h
otb::UnaryFunctorNeighborhoodWithOffsetImageFilter::OutputImageRegionType
OutputImageType::RegionType OutputImageRegionType
Definition: otbUnaryFunctorNeighborhoodWithOffsetImageFilter.h:68
otb::UnaryFunctorNeighborhoodWithOffsetImageFilter::OutputImagePointer
OutputImageType::Pointer OutputImagePointer
Definition: otbUnaryFunctorNeighborhoodWithOffsetImageFilter.h:67
otb::UnaryFunctorNeighborhoodWithOffsetImageFilter::InputImageSizeType
InputImageType::SizeType InputImageSizeType
Definition: otbUnaryFunctorNeighborhoodWithOffsetImageFilter.h:64