OTB  6.7.0
Orfeo Toolbox
otbFunctionWithNeighborhoodToImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999-2011 Insight Software Consortium
3  * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
4  *
5  * This file is part of Orfeo Toolbox
6  *
7  * https://www.orfeo-toolbox.org/
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #ifndef otbFunctionWithNeighborhoodToImageFilter_hxx
23 #define otbFunctionWithNeighborhoodToImageFilter_hxx
24 
26 #include "otbMacro.h"
27 
28 namespace otb
29 {
30 
34 template<class TInputImage, class TOutputImage, class TFunction>
37 {
38  this->InPlaceOff();
39  this->SetNumberOfRequiredInputs(1);
40  m_Radius.Fill(1);
41  m_Offset.Fill(1);
42  m_FunctionList.clear();
43  m_Function = FunctionType::New();
45 
46 }
47 
48 template <class TInputImage, class TOutputImage, class TFunction>
49 void
52 {
53  Superclass::BeforeThreadedGenerateData();
54 
55  InputImageConstPointer inputPtr = dynamic_cast<const TInputImage*>((itk::ProcessObject::GetInput(0)));
56  if (inputPtr.IsNull())
57  {
58  itkExceptionMacro(<< "At least one input is missing."
59  << " Input is missing :" << inputPtr.GetPointer(); )
60 
61  }
62  m_Function->SetInputImage(inputPtr);
63  for (unsigned int i = 0; i < static_cast<unsigned int>(this->GetNumberOfThreads()); ++i)
64  {
65  FunctionPointerType func = m_Function;
66  m_FunctionList.push_back(func);
67  }
68 }
69 
70 template <class TInputImage, class TOutputImage, class TFunction>
71 void
74 {
75  // call the superclass' implementation of this method
76  Superclass::GenerateInputRequestedRegion();
77 
78  // get pointers to the input and output
79  InputImagePointer inputPtr = const_cast<TInputImage *>(this->GetInput());
80  OutputImagePointer outputPtr = this->GetOutput();
81 
82  if (!inputPtr || !outputPtr)
83  {
84  return;
85  }
86  // get a copy of the input requested region (should equal the output
87  // requested region)
88  InputImageRegionType inputRequestedRegion = inputPtr->GetRequestedRegion();
89 
90  // pad the input requested region by the operator radius
91  InputImageSizeType maxRad;
92  maxRad[0] = m_Radius[0] + std::abs(m_Offset[0]);
93  maxRad[1] = m_Radius[0] + std::abs(m_Offset[1]);
94  inputRequestedRegion.PadByRadius(maxRad);
95 
96  // crop the input requested region at the input's largest possible region
97  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
98  {
99  inputPtr->SetRequestedRegion(inputRequestedRegion);
100  return;
101  }
102  else
103  {
104  // Couldn't crop the region (requested region is outside the largest
105  // possible region). Throw an exception.
106 
107  // store what we tried to request (prior to trying to crop)
108  inputPtr->SetRequestedRegion(inputRequestedRegion);
109 
110  // build an exception
111  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
112  std::ostringstream msg;
113  msg << this->GetNameOfClass()
114  << "::GenerateInputRequestedRegion()";
115  e.SetLocation(msg.str());
116  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
117  e.SetDataObject(inputPtr);
118  throw e;
119  }
120 }
121 
125 template<class TInputImage, class TOutputImage, class TFunction>
126 void
128 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
129  itk::ThreadIdType threadId)
130 {
131  // We use dynamic_cast since inputs are stored as DataObjects.
132  InputImageConstPointer inputPtr = dynamic_cast<const TInputImage*>((itk::ProcessObject::GetInput(0)));
133 
134  OutputImagePointer outputPtr = this->GetOutput(0);
135 
136  itk::ImageRegionConstIterator<TInputImage> inputIt(inputPtr, outputRegionForThread);
137  itk::ImageRegionIterator<TOutputImage> outputIt(outputPtr, outputRegionForThread);
138 
139  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
140 
141  inputIt.GoToBegin();
142  outputIt.GoToBegin();
143 
144  while (!inputIt.IsAtEnd())
145  {
146  outputIt.Set(static_cast<OutputImagePixelType>(m_FunctionList[threadId]->EvaluateAtIndex(inputIt.GetIndex())));
147  ++inputIt;
148  ++outputIt;
149 
150  progress.CompletedPixel(); // potential exception thrown here
151  }
152 }
153 } // end namespace otb
154 
155 #endif
void SetDataObject(DataObject *dobj)
InputImageType::ConstPointer InputImageConstPointer
virtual void SetDescription(const std::string &s)
virtual void SetLocation(const std::string &s)
void Set(const PixelType &value) const
InputImageType::Pointer InputImagePointer
const IndexType GetIndex() const
OutputImageType::Pointer OutputImagePointer
InputImageType::RegionType InputImageRegionType
unsigned int ThreadIdType
DataObject * GetInput(const DataObjectIdentifierType &key)
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId) override
OutputImageType::RegionType OutputImageRegionType
bool IsAtEnd(void) const