OTB  6.7.0
Orfeo Toolbox
otbExtractROIBase.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2019 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 otbExtractROIBase_hxx
22 #define otbExtractROIBase_hxx
23 
24 #include "otbExtractROIBase.h"
25 #include "itkImageRegionIterator.h"
26 #include "itkObjectFactory.h"
27 #include "itkProgressReporter.h"
28 #include "otbMacro.h"
29 
30 namespace otb
31 {
32 
36 template <class TInputImage, class TOutputImage>
38 ::ExtractROIBase() : itk::ImageToImageFilter<TInputImage, TOutputImage>(),
39  m_StartX(0),
40  m_StartY(0),
41  m_SizeX(0),
42  m_SizeY(0)
43 {
44 }
45 
49 template <class TInputImage, class TOutputImage>
50 void
52 ::PrintSelf(std::ostream& os, itk::Indent indent) const
53 {
54  Superclass::PrintSelf(os, indent);
55 
56  os << indent << "ExtractionRegion: " << m_ExtractionRegion << std::endl;
57  os << indent << "OutputImageRegion: " << m_OutputImageRegion << std::endl;
58 }
59 
60 template<class TInputImage, class TOutputImage>
61 void
64  const OutputImageRegionType& srcRegion)
65 {
66  destRegion = srcRegion;
67 
68  OutputImageIndexType index = destRegion.GetIndex();
69 
70  for (unsigned int i = 0; i < InputImageDimension; ++i)
71  {
72  index[i] += m_ExtractionRegion.GetIndex()[i];
73  }
74  destRegion.SetIndex(index);
75 }
76 
77 template <class TInputImage, class TOutputImage>
78 void
81 {
82  m_ExtractionRegion = extractRegion;
83 
84  unsigned int nonzeroSizeCount = 0;
85  InputImageSizeType inputSize = extractRegion.GetSize();
86  OutputImageSizeType outputSize;
87  OutputImageIndexType outputIndex;
88 
93  for (unsigned int i = 0; i < InputImageDimension; ++i)
94  {
95  if (inputSize[i])
96  {
97  outputSize[nonzeroSizeCount] = inputSize[i];
98  outputIndex[nonzeroSizeCount] = 0;
99  nonzeroSizeCount++;
100  }
101  }
103 
104  if (nonzeroSizeCount != OutputImageDimension)
105  {
106  itkExceptionMacro("Extraction Region not consistent with output image");
107  }
108 
109  m_OutputImageRegion.SetSize(outputSize);
110  m_OutputImageRegion.SetIndex(outputIndex);
111 
112  this->Modified();
113 }
114 
115 template <class TInputImage, class TOutputImage>
116 void
119 {
120  m_SizeX = roi.GetSize()[0];
121  m_SizeY = roi.GetSize()[1];
122  m_StartX = roi.GetIndex()[0];
123  m_StartY = roi.GetIndex()[1];
124 
125  this->Modified();
126 }
127 
128 template <class TInputImage, class TOutputImage>
129 void
132 {
133  Superclass::GenerateInputRequestedRegion();
134 
135  typename Superclass::InputImagePointer inputPtr = const_cast<InputImageType*>(this->GetInput());
136  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
137 
138  if (!inputPtr)
139  {
140  return;
141  }
142  if (!outputPtr)
143  {
144  return;
145  }
146  InputImageRegionType requestedRegion = outputPtr->GetRequestedRegion();
147  InputImageIndexType index = requestedRegion.GetIndex();
148  InputImageIndexType offset = m_ExtractionRegion.GetIndex();
149 
150  for (unsigned int i = 0; i < InputImageDimension; ++i)
151  {
152  index[i] += offset[i];
153  }
154  requestedRegion.SetIndex(index);
155  inputPtr->SetRequestedRegion(requestedRegion);
156 }
157 
167 template <class TInputImage, class TOutputImage>
168 void
171 {
172  Superclass::GenerateOutputInformation();
173 
174  // Compute the area to extract
175  // If SizeX/Y == 0, then set SizeX/Y to image size
176  typename Superclass::InputImageConstPointer inputPtr = this->GetInput();
177 
178  // Check if input exists or not before doing anything
179  if (!inputPtr)
180  {
181  return;
182  }
183 
184  // Get the input image
185  //const InputImageRegionType& inputRegion = inputPtr->GetRequestedRegion();
186  const InputImageRegionType& inputRegion = inputPtr->GetLargestPossibleRegion();
187 
188  if ((m_SizeX == 0) || (m_SizeX > (inputRegion.GetSize()[0] - m_StartX)))
189  {
190  m_SizeX = inputRegion.GetSize()[0] - m_StartX;
191  }
192  if ((m_SizeY == 0) || (m_SizeY > (inputRegion.GetSize()[1] - m_StartY)))
193  {
194  m_SizeY = inputRegion.GetSize()[1] - m_StartY;
195  }
196 
197  InputImageIndexType start;
198  start[0] = m_StartX;
199  start[1] = m_StartY;
200  InputImageSizeType size;
201  size[0] = m_SizeX;
202  size[1] = m_SizeY;
203  InputImageRegionType desiredRegion;
204  desiredRegion.SetSize(size);
205  desiredRegion.SetIndex(start);
206  // Call to the base class method for region initialization
207  this->SetInternalExtractionRegion(desiredRegion);
208 
209  // do not call the superclass' implementation of this method since
210  // this filter allows the input the output to be of different dimensions
211 
212  // get pointers to the input and output
213  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
214 // typename Superclass::InputImageConstPointer inputPtr = this->GetInput();
215 
216  if (!inputPtr)
217  {
218  return;
219  }
220  if (!outputPtr)
221  {
222  return;
223  }
224 
225  // Set the output image size to the same value as the extraction region.
226  outputPtr->SetLargestPossibleRegion(m_OutputImageRegion);
227 
228  // Set the output spacing and origin
230 
231  phyData
232  = dynamic_cast<const itk::ImageBase<InputImageDimension>*>(this->GetInput());
233 
234  if (!phyData)
235  {
236  // pointer could not be cast back down
237  itkExceptionMacro(<< "otb::ExtractROIBase::GenerateOutputInformation "
238  << "cannot cast input to "
239  << typeid(itk::ImageBase<InputImageDimension>*).name());
240  }
241 
242  // Copy what we can from the image from spacing and origin of the input
243  // This logic needs to be augmented with logic that select which
244  // dimensions to copy
245  const typename InputImageType::SpacingType&
246  inputSpacing = inputPtr->GetSignedSpacing();
247  const typename InputImageType::DirectionType&
248  inputDirection = inputPtr->GetDirection();
249  const typename InputImageType::PointType&
250  inputOrigin = inputPtr->GetOrigin();
251 
252  typename OutputImageType::SpacingType outputSpacing;
253  typename OutputImageType::DirectionType outputDirection;
254  typename OutputImageType::PointType outputOrigin;
255 
256  if (static_cast<unsigned int>(OutputImageDimension) >
257  static_cast<unsigned int>(InputImageDimension))
258  {
259  unsigned int i;
260  // copy the input to the output and fill the rest of the
261  // output with zeros.
262  for (i = 0; i < InputImageDimension; ++i)
263  {
264  outputSpacing[i] = inputSpacing[i];
265  outputOrigin[i] = inputOrigin[i] + static_cast<double>(m_ExtractionRegion.GetIndex()[i]) * outputSpacing[i];
266  for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
267  {
268  outputDirection[i][dim] = inputDirection[i][dim];
269  }
270  }
271  for (; i < OutputImageDimension; ++i)
272  {
273  outputSpacing[i] = 1.0;
274  outputOrigin[i] = 0.0;
275  for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
276  {
277  outputDirection[i][dim] = 0.0;
278  }
279  outputDirection[i][i] = 1.0;
280  }
281  }
282  else
283  {
284  // copy the non-collapsed part of the input spacing and origing to the output
285  int nonZeroCount = 0;
286  for (unsigned int i = 0; i < InputImageDimension; ++i)
287  {
288  if (m_ExtractionRegion.GetSize()[i] == 0) continue;
289 
290  outputSpacing[nonZeroCount] = inputSpacing[i];
291  outputOrigin[nonZeroCount] = inputOrigin[i] + static_cast<double>(m_ExtractionRegion.GetIndex()[i]) *
292  outputSpacing[i];
293  for (unsigned int dim = 0; dim < OutputImageDimension; ++dim)
294  {
295  outputDirection[nonZeroCount][dim] =
296  inputDirection[nonZeroCount][dim];
297  }
298  nonZeroCount++;
299  }
300  }
301 
302  // set the spacing and origin
303  outputPtr->SetSignedSpacing(outputSpacing);
304  outputPtr->SetDirection(outputDirection);
305  outputPtr->SetOrigin(outputOrigin);
306 
307 // Thomas Feuvrier:
308 // ITK has this code. But not in our case, because the number of component per pixel depends on the bands selected by the user.
309 // This parameter is given in the underlying classes.
310 // outputPtr->SetNumberOfComponentsPerPixel(
311 // inputPtr->GetNumberOfComponentsPerPixel() );
312 //
313 }
314 
315 } // end namespace otb
316 
317 #endif
void SetExtractionRegion(InputImageRegionType roi)
void GenerateOutputInformation() override
InputImageType::RegionType InputImageRegionType
TInputImage InputImageType
TInputImage::SizeType InputImageSizeType
TOutputImage::SizeType OutputImageSizeType
void CallCopyOutputRegionToInputRegion(InputImageRegionType &destRegion, const OutputImageRegionType &srcRegion) override
void GenerateInputRequestedRegion() override
OutputImageType::RegionType OutputImageRegionType
void SetInternalExtractionRegion(InputImageRegionType extractRegion)
TOutputImage::IndexType OutputImageIndexType
VectorImageType::SpacingType SpacingType
Definition: mvdTypes.h:181
void PrintSelf(std::ostream &os, itk::Indent indent) const override
VectorImageType::PointType PointType
Definition: mvdTypes.h:189
TInputImage::IndexType InputImageIndexType