OTB  10.0.0
Orfeo Toolbox
otbBinaryFunctorNeighborhoodVectorImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2024 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 otbBinaryFunctorNeighborhoodVectorImageFilter_hxx
22 #define otbBinaryFunctorNeighborhoodVectorImageFilter_hxx
23 
24 #include "otbMath.h"
25 #include "otbMacro.h" //for
27 #include "itkImageRegionIterator.h"
28 #include "itkNeighborhoodAlgorithm.h"
29 #include "itkProgressReporter.h"
30 
31 namespace otb
32 {
33 
37 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
39 {
40  this->SetNumberOfRequiredInputs(2);
41  this->InPlaceOff();
42  m_Radius = 3;
43 }
45 
49 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
51 {
52  // Process object is not const-correct so the const casting is required.
53  this->SetNthInput(0, const_cast<TInputImage1*>(image1));
54 }
55 
59 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
61 {
62  // Process object is not const-correct so the const casting is required.
63  this->SetNthInput(1, const_cast<TInputImage2*>(image2));
64 }
65 
69 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
71  const unsigned char& max)
72 {
73  this->SetRadius(max);
74  GetFunctor().SetRadius(min, max);
75 }
77 
81 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
83 {
84  Superclass::GenerateOutputInformation();
85 
86  int nbComponents = static_cast<int>(m_Functor.GetRadiusMax()) + 1 - static_cast<int>(m_Functor.GetRadiusMin());
87 
88  this->GetOutput()->SetNumberOfComponentsPerPixel(nbComponents);
89 }
90 
94 template <class TInputImage1, class TInputImage2, class TOutputImage, class TFunction>
96  const OutputImageRegionType& outputRegionForThread)
97 {
98 
99  itk::ZeroFluxNeumannBoundaryCondition<TInputImage1> nbc1;
100  itk::ZeroFluxNeumannBoundaryCondition<TInputImage2> nbc2;
101 
102  Input1ImagePointer inputPtr1 = dynamic_cast<const TInputImage1*>(ProcessObjectType::GetInput(0));
103  Input2ImagePointer inputPtr2 = dynamic_cast<const TInputImage2*>(ProcessObjectType::GetInput(1));
104 
105  RadiusType1 r1;
106  r1.Fill(m_Radius);
107  NeighborhoodIteratorType1 neighInputIt1;
108 
109  RadiusType2 r2;
110  r2.Fill(m_Radius);
111  NeighborhoodIteratorType2 neighInputIt2;
112 
113  // This is the main difference from BinaryFunctorNeighborhoodImageFilter<TInputImage1, TInputImage2, TOutputImage, TFunction>::ThreadedGenerateData( const
114  // OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId)
115  OutputImagePointer outputPtr = this->GetOutput();
116  outputPtr->SetNumberOfComponentsPerPixel(m_Functor.GetNumberOfComponentsPerPixel());
117  outputPtr->Allocate();
118 
119  itk::ImageRegionIterator<TOutputImage> outputIt;
120 
121  // Find the data-set boundary "faces"
122  typedef typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage1> TypeFace1;
123  typename TypeFace1::FaceListType::iterator fit1;
124  typename TypeFace1::FaceListType faceList1;
125  TypeFace1 bC1;
126  faceList1 = bC1(inputPtr1, outputRegionForThread, r1);
127 
128  typedef typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage2> TypeFace2;
129  typename TypeFace2::FaceListType::iterator fit2;
130  typename TypeFace2::FaceListType faceList2;
131  TypeFace2 bC2;
132  faceList2 = bC2(inputPtr2, outputRegionForThread, r2);
133 
134  // Process each of the boundary faces.
135  // Center first and then left, right, up, down borders
136  for (fit1 = faceList1.begin(), fit2 = faceList2.begin(); fit1 != faceList1.end() && fit2 != faceList2.end(); ++fit1, ++fit2)
137  {
138  neighInputIt1 = itk::ConstNeighborhoodIterator<TInputImage1>(r1, inputPtr1, *fit1);
139  neighInputIt1.OverrideBoundaryCondition(&nbc1);
140  neighInputIt1.GoToBegin();
141 
142  neighInputIt2 = itk::ConstNeighborhoodIterator<TInputImage2>(r2, inputPtr2, *fit2);
143  neighInputIt2.OverrideBoundaryCondition(&nbc2);
144  neighInputIt2.GoToBegin();
145 
146  outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, *fit1);
147  outputIt.GoToBegin();
148 
149  while (!outputIt.IsAtEnd())
150  {
151  outputIt.Set(m_Functor(neighInputIt1, neighInputIt2));
152 
153  ++neighInputIt1;
154  ++neighInputIt2;
155  ++outputIt;
156 
157  }
158  }
159 }
160 
161 } // end namespace otb
162 
163 #endif
itk::ConstNeighborhoodIterator< TInputImage1 > NeighborhoodIteratorType1
itk::ConstNeighborhoodIterator< TInputImage2 > NeighborhoodIteratorType2
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) override
void SetRadius(const unsigned char &min, const unsigned char &max)
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.