OTB  10.0.0
Orfeo Toolbox
otbSynthetizeFilter.h
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 otbSynthetizeFilter_h
22 #define otbSynthetizeFilter_h
23 
24 #include "otbZipIterator.h"
25 #include "itkImageToImageFilter.h"
26 #include "itkImageScanlineConstIterator.h"
27 #include "itkImageScanlineIterator.h"
28 #include "itkProgressReporter.h"
29 
30 namespace otb
31 {
46 template <typename TInputImage, typename TOutputImage, typename TFunctor>
47 class SynthetizeFilter : public itk::ImageToImageFilter<TInputImage, TOutputImage>
48 {
49 public:
50 
53  using InputImageType = TInputImage;
54  using OutputImageType = TOutputImage;
55  using FunctorType = TFunctor;
57 
60  itkStaticConstMacro(InputImageDimension, unsigned int, InputImageType::ImageDimension);
61  itkStaticConstMacro(OutputImageDimension, unsigned int, OutputImageType::ImageDimension);
63 
67  using Superclass = itk::ImageToImageFilter<InputImageType, OutputImageType>;
68  using Pointer = itk::SmartPointer<Self>;
69  using ConstPointer = itk::SmartPointer<const Self>;
71 
73  static Pointer New(FunctorType functor)
74  {
75  Pointer smartPtr = new Self(std::move(functor));
76  smartPtr->UnRegister();
77  return smartPtr;
78  }
80 
82  itkTypeMacro(SynthetizeFilter, ImageToImageFilter);
83 
86  using InputPixelType = typename InputImageType::PixelType;
87  using OutputPixelType = typename OutputImageType::PixelType;
88  using InputRealType = typename itk::NumericTraits<InputPixelType>::RealType;
89  using InputImageRegionType = typename InputImageType::RegionType;
90  using OutputImageRegionType = typename OutputImageType::RegionType;
91  using InputSizeType = typename InputImageType::SizeType;
92  using OutputIndexType = typename OutputImageType::IndexType;
93  using OutputSizeType = typename OutputImageType::SizeType;
94 
95  static_assert(InputImageDimension == OutputImageDimension, "Images have the same number of components");
96 
97  using DataObjectPointerArraySizeType = itk::ProcessObject::DataObjectPointerArraySizeType;
99 
106  using Superclass::SetNthInput;
107  using Superclass::GetInput;
108 
111  {
112  return const_cast<InputImageType*>(this->GetInput(idx));
113  }
114 
116  std::vector<InputImageType const*> GetInputs() const
117  {
118  std::vector<InputImageType const*> res;
119  auto const nbInputImages = this->GetNumberOfInputs();
120  res.reserve(nbInputImages);
121  for (std::size_t i = 0 ; i != nbInputImages ; ++i)
122  res.push_back(this->GetInput(i));
123  return res;
124  }
126 
127 
128 protected:
130  explicit SynthetizeFilter(FunctorType functor)
131  : m_functor(functor){}
132  ~SynthetizeFilter() = default;
133 
136  {
137  Superclass::GenerateOutputInformation();
139  }
141 
142  // void GenerateInputRequestedRegion() override;
143  // +-> TODO: detect neighborhood to apply pad radius
144 
151  OutputImageRegionType const& outputRegionForThread) override
152  {
153  using ImageScanlineConstIteratorType = itk::ImageScanlineConstIterator<InputImageType const>;
154  // using OutImageScanlineConstIteratorType = itk::ImageScanlineIterator<OutputImageType>;
155  using OutputIterator = itk::ImageScanlineIterator<OutputImageType>;
157 
158  InputIterator inputIterator(this->GetInputs(), outputRegionForThread);
159  OutputIterator outputIterator(this->GetOutput(), outputRegionForThread);
160 
161  inputIterator.GoToBegin();
162  outputIterator.GoToBegin();
163  for (
164  ; !inputIterator.IsAtEnd()
165  ; inputIterator.NextLine(), outputIterator.NextLine())
166  {
167  assert(! outputIterator.IsAtEnd());
168  // inputIterator.GoToBeginOfLine();
169  // outputIterator.GoToBeginOfLine();
170  for (
171  ; !inputIterator.IsAtEndOfLine()
172  ; ++inputIterator, ++outputIterator)
173  {
174  assert(!outputIterator.IsAtEndOfLine());
175 
176  outputIterator.Set(m_functor(inputIterator.Get()));
177  }
178  }
179  }
180 
181 private:
182 
184  {
185  // Check if input image dimensions match
186  auto const nbInputImages = this->GetNumberOfInputs();
187  auto const& inputSize = this->GetInput(0)->GetLargestPossibleRegion().GetSize();
188 
189  for (auto p = 1U; p < nbInputImages; ++p)
190  {
191  auto const& regionSize = this->GetInput(p)->GetLargestPossibleRegion().GetSize();
192  if (inputSize != regionSize)
193  {
194  itkExceptionMacro(<< "Input images must have the same dimensions.\n"
195  << "band #1 is [" << inputSize[0] << ";" << inputSize[1] << "]\n"
196  << "band #" << p + 1 << " is [" << this->GetInput(p)->GetLargestPossibleRegion().GetSize(0) << ";"
197  << regionSize << "]");
198  }
199  }
200  }
201 
206 
207 };
208 
224 template <typename TInputImage, typename TOutputImage, typename TFunctor>
225 auto MakeSynthetizeFilter(TFunctor functor)
226 {
227  auto filter = SynthetizeFilter<TInputImage, TOutputImage, TFunctor>::New(std::move(functor));
228  return filter;
229 }
231 
232 } // otb namespace
233 
234 #ifndef OTB_MANUAL_INSTANTIATION
235 // #include "otbSynthetizeFilter.hxx"
236 #endif
237 
238 #endif // otbSynthetizeFilter_h
typename OutputImageType::IndexType OutputIndexType
typename InputImageType::PixelType InputPixelType
itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType
std::vector< InputImageType const * > GetInputs() const
typename OutputImageType::PixelType OutputPixelType
static const unsigned int OutputImageDimension
InputImageType * GetNthInput(DataObjectPointerArraySizeType idx)
itk::SmartPointer< Self > Pointer
typename InputImageType::SizeType InputSizeType
void DynamicThreadedGenerateData(OutputImageRegionType const &outputRegionForThread) override
typename OutputImageType::SizeType OutputSizeType
typename OutputImageType::RegionType OutputImageRegionType
SynthetizeFilter(FunctorType functor)
typename InputImageType::RegionType InputImageRegionType
~SynthetizeFilter()=default
static Pointer New(FunctorType functor)
itk::ImageToImageFilter< InputImageType, OutputImageType > Superclass
void GenerateOutputInformation() override
static const unsigned int InputImageDimension
typename itk::NumericTraits< InputPixelType >::RealType InputRealType
itk::SmartPointer< const Self > ConstPointer
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
auto MakeSynthetizeFilter(TFunctor functor)