OTB  9.0.0
Orfeo Toolbox
otbBinaryFunctorNeighborhoodImageFilter.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 otbBinaryFunctorNeighborhoodImageFilter_hxx
22 #define otbBinaryFunctorNeighborhoodImageFilter_hxx
23 
25 #include "itkImageRegionIterator.h"
26 #include "itkNeighborhoodAlgorithm.h"
27 #include "itkProgressReporter.h"
28 
29 namespace otb
30 {
31 
35 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
37 {
38  this->SetNumberOfRequiredInputs(2);
39  m_Radius.Fill(3);
40 }
42 
46 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
48 {
49  // Process object is not const-correct so the const casting is required.
50  this->SetNthInput(0, const_cast<TInputImage1*>(image1));
51 }
52 
56 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
58 {
59  // Process object is not const-correct so the const casting is required.
60  this->SetNthInput(1, const_cast<TInputImage2*>(image2));
61 }
62 
63 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
65 {
66  if (this->GetNumberOfInputs() < 1)
67  {
68  return nullptr;
69  }
70  return static_cast<const TInputImage1*>(this->itk::ProcessObject::GetInput(0));
71 }
72 
73 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
75 {
76  if (this->GetNumberOfInputs() < 2)
77  {
78  return nullptr;
79  }
80  return static_cast<const TInputImage2*>(this->itk::ProcessObject::GetInput(1));
81 }
82 
83 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
85 {
86  // call the superclass' implementation of this method
87  Superclass::GenerateInputRequestedRegion();
88 
89  // get pointers to the input and output
90  Input1ImagePointer inputPtr1 = const_cast<TInputImage1*>(this->GetInput1());
91  Input2ImagePointer inputPtr2 = const_cast<TInputImage2*>(this->GetInput2());
92  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
93 
94  if (!inputPtr1 || !inputPtr2 || !outputPtr)
95  {
96  return;
97  }
98  // get a copy of the input requested region (should equal the output
99  // requested region)
100  typename TInputImage1::RegionType inputRequestedRegion1, inputRequestedRegion2;
101  inputRequestedRegion1 = inputPtr1->GetRequestedRegion();
102 
103  // pad the input requested region by the operator radius
104  inputRequestedRegion1.PadByRadius(m_Radius);
105  inputRequestedRegion2 = inputRequestedRegion1;
106 
107  // crop the input requested region at the input's largest possible region
108  if (inputRequestedRegion1.Crop(inputPtr1->GetLargestPossibleRegion()))
109  {
110  inputPtr1->SetRequestedRegion(inputRequestedRegion1);
111  }
112  else
113  {
114  // Couldn't crop the region (requested region is outside the largest
115  // possible region). Throw an exception.
116 
117  // store what we tried to request (prior to trying to crop)
118  inputPtr1->SetRequestedRegion(inputRequestedRegion1);
119 
120  // build an exception
121  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
122  std::ostringstream msg;
123  msg << this->GetNameOfClass() << "::GenerateInputRequestedRegion()";
124  e.SetLocation(msg.str());
125  e.SetDescription("Requested region is (at least partially) outside the largest possible region of image 1.");
126  e.SetDataObject(inputPtr1);
127  throw e;
128  }
129  if (inputRequestedRegion2.Crop(inputPtr2->GetLargestPossibleRegion()))
130  {
131  inputPtr2->SetRequestedRegion(inputRequestedRegion2);
132  }
133  else
134  {
135  // Couldn't crop the region (requested region is outside the largest
136  // possible region). Throw an exception.
137 
138  // store what we tried to request (prior to trying to crop)
139  inputPtr2->SetRequestedRegion(inputRequestedRegion2);
140 
141  // build an exception
142  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
143  std::ostringstream msg;
144  msg << this->GetNameOfClass() << "::GenerateInputRequestedRegion()";
145  e.SetLocation(msg.str());
146  e.SetDescription("Requested region is (at least partially) outside the largest possible region of image 1.");
147  e.SetDataObject(inputPtr2);
148  throw e;
149  }
150  return;
151 }
152 
156 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
158  const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
159 {
160 
161  // unsigned int i;
162  itk::ZeroFluxNeumannBoundaryCondition<TInputImage1> nbc1;
163  itk::ZeroFluxNeumannBoundaryCondition<TInputImage2> nbc2;
164 
165  // We use dynamic_cast since inputs are stored as DataObjects. The
166  // ImageToImageFilter::GetInput(int) always returns a pointer to a
167  // TInputImage1 so it cannot be used for the second input.
168  Input1ImageConstPointer inputPtr1 = dynamic_cast<const TInputImage1*>(ProcessObjectType::GetInput(0));
169  Input2ImageConstPointer inputPtr2 = dynamic_cast<const TInputImage2*>(ProcessObjectType::GetInput(1));
170  OutputImagePointer outputPtr = this->GetOutput(0);
171 
172  RadiusType1 r1;
173  r1[0] = m_Radius[0];
174  r1[1] = m_Radius[1];
175  NeighborhoodIteratorType1 neighInputIt1;
176 
177  RadiusType2 r2;
178  r2[0] = m_Radius[0];
179  r2[1] = m_Radius[1];
180  NeighborhoodIteratorType2 neighInputIt2;
181 
182  itk::ImageRegionIterator<TOutputImage> outputIt;
183 
184  // Find the data-set boundary "faces"
185  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage1>::FaceListType faceList1;
186  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage1> bC1;
187  faceList1 = bC1(inputPtr1, outputRegionForThread, r1);
188 
189  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage2>::FaceListType faceList2;
190  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage2> bC2;
191  faceList2 = bC2(inputPtr2, outputRegionForThread, r2);
192 
193  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage1>::FaceListType::iterator fit1;
194  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage2>::FaceListType::iterator fit2;
195 
196  // support progress methods/callbacks
197  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
198 
199  // Process each of the boundary faces. These are N-d regions which border
200  // the edge of the buffer.
201  for (fit1 = faceList1.begin(), fit2 = faceList2.begin(); fit1 != faceList1.end() && fit2 != faceList2.end(); ++fit1, ++fit2)
202  {
203  neighInputIt1 = itk::ConstNeighborhoodIterator<TInputImage1>(r1, inputPtr1, *fit1);
204  neighInputIt2 = itk::ConstNeighborhoodIterator<TInputImage2>(r2, inputPtr2, *fit2);
205  // outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, outputRegionForThread);
206 
207  outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, *fit1);
208  neighInputIt1.OverrideBoundaryCondition(&nbc1);
209  neighInputIt1.GoToBegin();
210  neighInputIt2.OverrideBoundaryCondition(&nbc2);
211  neighInputIt2.GoToBegin();
212 
213  while (!outputIt.IsAtEnd())
214  {
215 
216  outputIt.Set(m_Functor(neighInputIt1, neighInputIt2));
217 
218  ++neighInputIt1;
219  ++neighInputIt2;
220  ++outputIt;
221  progress.CompletedPixel();
222  }
223  }
224 }
225 
226 } // end namespace otb
227 
228 #endif
otb::BinaryFunctorNeighborhoodImageFilter< TInputImage1, TInputImage2, TOutputImage, Functor::CBAMI< itk::ConstNeighborhoodIterator< TInputImage1 >, itk::ConstNeighborhoodIterator< TInputImage2 >, TOutputImage::PixelType > >::Input1ImagePointer
Input1ImageType::Pointer Input1ImagePointer
Definition: otbBinaryFunctorNeighborhoodImageFilter.h:66
otb::BinaryFunctorNeighborhoodImageFilter< TInputImage1, TInputImage2, TOutputImage, Functor::CBAMI< itk::ConstNeighborhoodIterator< TInputImage1 >, itk::ConstNeighborhoodIterator< TInputImage2 >, TOutputImage::PixelType > >::OutputImageRegionType
OutputImageType::RegionType OutputImageRegionType
Definition: otbBinaryFunctorNeighborhoodImageFilter.h:76
otb::BinaryFunctorNeighborhoodImageFilter< TInputImage1, TInputImage2, TOutputImage, Functor::CBAMI< itk::ConstNeighborhoodIterator< TInputImage1 >, itk::ConstNeighborhoodIterator< TInputImage2 >, TOutputImage::PixelType > >::NeighborhoodIteratorType1
itk::ConstNeighborhoodIterator< TInputImage1 > NeighborhoodIteratorType1
Definition: otbBinaryFunctorNeighborhoodImageFilter.h:114
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::BinaryFunctorNeighborhoodImageFilter< TInputImage1, TInputImage2, TOutputImage, Functor::CBAMI< itk::ConstNeighborhoodIterator< TInputImage1 >, itk::ConstNeighborhoodIterator< TInputImage2 >, TOutputImage::PixelType > >::Input1ImageConstPointer
Input1ImageType::ConstPointer Input1ImageConstPointer
Definition: otbBinaryFunctorNeighborhoodImageFilter.h:65
otbBinaryFunctorNeighborhoodImageFilter.h
otb::BinaryFunctorNeighborhoodImageFilter::ThreadedGenerateData
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId) override
Definition: otbBinaryFunctorNeighborhoodImageFilter.hxx:157
otb::BinaryFunctorNeighborhoodImageFilter< TInputImage1, TInputImage2, TOutputImage, Functor::CBAMI< itk::ConstNeighborhoodIterator< TInputImage1 >, itk::ConstNeighborhoodIterator< TInputImage2 >, TOutputImage::PixelType > >::RadiusType1
NeighborhoodIteratorType1::RadiusType RadiusType1
Definition: otbBinaryFunctorNeighborhoodImageFilter.h:117
otb::BinaryFunctorNeighborhoodImageFilter::BinaryFunctorNeighborhoodImageFilter
BinaryFunctorNeighborhoodImageFilter()
Definition: otbBinaryFunctorNeighborhoodImageFilter.hxx:36
otb::BinaryFunctorNeighborhoodImageFilter< TInputImage1, TInputImage2, TOutputImage, Functor::CBAMI< itk::ConstNeighborhoodIterator< TInputImage1 >, itk::ConstNeighborhoodIterator< TInputImage2 >, TOutputImage::PixelType > >::RadiusType2
NeighborhoodIteratorType2::RadiusType RadiusType2
Definition: otbBinaryFunctorNeighborhoodImageFilter.h:118
otb::BinaryFunctorNeighborhoodImageFilter::GenerateInputRequestedRegion
void GenerateInputRequestedRegion(void) override
Definition: otbBinaryFunctorNeighborhoodImageFilter.hxx:84
otb::BinaryFunctorNeighborhoodImageFilter< TInputImage1, TInputImage2, TOutputImage, Functor::CBAMI< itk::ConstNeighborhoodIterator< TInputImage1 >, itk::ConstNeighborhoodIterator< TInputImage2 >, TOutputImage::PixelType > >::Input2ImagePointer
Input2ImageType::Pointer Input2ImagePointer
Definition: otbBinaryFunctorNeighborhoodImageFilter.h:71
otb::BinaryFunctorNeighborhoodImageFilter::SetInput2
void SetInput2(const TInputImage2 *image2)
Definition: otbBinaryFunctorNeighborhoodImageFilter.hxx:57
otb::BinaryFunctorNeighborhoodImageFilter< TInputImage1, TInputImage2, TOutputImage, Functor::CBAMI< itk::ConstNeighborhoodIterator< TInputImage1 >, itk::ConstNeighborhoodIterator< TInputImage2 >, TOutputImage::PixelType > >::OutputImagePointer
OutputImageType::Pointer OutputImagePointer
Definition: otbBinaryFunctorNeighborhoodImageFilter.h:75
otb::BinaryFunctorNeighborhoodImageFilter< TInputImage1, TInputImage2, TOutputImage, Functor::CBAMI< itk::ConstNeighborhoodIterator< TInputImage1 >, itk::ConstNeighborhoodIterator< TInputImage2 >, TOutputImage::PixelType > >::Input2ImageConstPointer
Input2ImageType::ConstPointer Input2ImageConstPointer
Definition: otbBinaryFunctorNeighborhoodImageFilter.h:70
otb::BinaryFunctorNeighborhoodImageFilter::GetInput2
const TInputImage2 * GetInput2()
Definition: otbBinaryFunctorNeighborhoodImageFilter.hxx:74
otb::BinaryFunctorNeighborhoodImageFilter::SetInput1
void SetInput1(const TInputImage1 *image1)
Definition: otbBinaryFunctorNeighborhoodImageFilter.hxx:47
otb::BinaryFunctorNeighborhoodImageFilter< TInputImage1, TInputImage2, TOutputImage, Functor::CBAMI< itk::ConstNeighborhoodIterator< TInputImage1 >, itk::ConstNeighborhoodIterator< TInputImage2 >, TOutputImage::PixelType > >::NeighborhoodIteratorType2
itk::ConstNeighborhoodIterator< TInputImage2 > NeighborhoodIteratorType2
Definition: otbBinaryFunctorNeighborhoodImageFilter.h:115
otb::BinaryFunctorNeighborhoodImageFilter::GetInput1
const TInputImage1 * GetInput1()
Definition: otbBinaryFunctorNeighborhoodImageFilter.hxx:64