OTB  9.0.0
Orfeo Toolbox
otbTileImageFilter.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 otbTileImageFilter_hxx
22 #define otbTileImageFilter_hxx
23 
24 #include "otbTileImageFilter.h"
25 #include "itkImageRegionIterator.h"
26 
27 namespace otb
28 {
29 template <class TImage>
31 {
32 }
33 
34 template <class TImage>
36 {
37 }
38 
39 template <class TImage>
40 void TileImageFilter<TImage>::PrintSelf(std::ostream& os, itk::Indent indent) const
41 {
42  Superclass::PrintSelf(os, indent);
43  os << indent << "Layout: " << m_Layout << std::endl;
44 }
45 
46 template <class TImage>
48 {
49  // First, call superclass implementation
50  Superclass::GenerateOutputInformation();
51 
52  // Get the number of images
53  unsigned int numberOfImages = m_Layout[0] * m_Layout[1];
54 
55  // Check we have enough inputs
56  if (numberOfImages != this->GetNumberOfInputs())
57  {
58  itkExceptionMacro(<< "Layout has " << numberOfImages << " tiles, but only " << this->GetNumberOfInputs() << " inputs are found.");
59  }
60 
61  typename ImageType::SpacingType spacing = this->GetInput()->GetSignedSpacing();
62  unsigned int nbComp = this->GetInput()->GetNumberOfComponentsPerPixel();
63 
64  m_ColumnsSizes.clear();
65  m_RowsSizes.clear();
66 
67  // Loop on the layout
68  for (unsigned int col = 0; col < m_Layout[0]; ++col)
69  {
70  for (unsigned int row = 0; row < m_Layout[1]; ++row)
71  {
72  // First, get current tile
73  const ImageType* currentTile = this->GetInput(col + row * m_Layout[0]);
74  typename ImageType::SizeType currentSize = currentTile->GetLargestPossibleRegion().GetSize();
75 
76  // Retrieve row and column sizes
77  if (col == 0)
78  {
79  m_RowsSizes.push_back(currentSize[1]);
80  }
81  if (row == 0)
82  {
83  m_ColumnsSizes.push_back(currentSize[0]);
84  }
85 
86  // Check for consistent layout
87  if (currentSize[1] != m_RowsSizes[row] || currentSize[0] != m_ColumnsSizes[col])
88  {
89  itkExceptionMacro(<< "Inconsistent sizes in layout detected!");
90  }
91 
92  if (spacing != currentTile->GetSignedSpacing())
93  {
94  itkExceptionMacro(<< "Inconsistent spacings in layout detected!");
95  }
96 
97  if (nbComp != currentTile->GetNumberOfComponentsPerPixel())
98  {
99  itkExceptionMacro(<< "Inconsistent number of components in layout detected!");
100  }
101  }
102  }
103 
104  // Compute total size
105  typename ImageType::SizeType totalSize;
106  totalSize.Fill(0);
107 
108  for (unsigned int i = 0; i < m_Layout[0]; ++i)
109  {
110  totalSize[0] += m_ColumnsSizes[i];
111  }
112 
113  for (unsigned int i = 0; i < m_Layout[1]; ++i)
114  {
115  totalSize[1] += m_RowsSizes[i];
116  }
117 
118  // Fill out output image settings
119  typename ImageType::RegionType outRegion;
120  outRegion.SetSize(totalSize);
121 
122  // std::cout<<"Output largest region: "<<outRegion<<std::endl;
123 
124  ImageType* outputPtr = this->GetOutput();
125 
126  // Copy information from first tile
127  outputPtr->CopyInformation(this->GetInput());
128 
129  // Set region
130  outputPtr->SetLargestPossibleRegion(outRegion);
131 }
132 
133 template <class TImage>
135 {
136  // Get output requested region
137  RegionType outRegion = this->GetOutput()->GetRequestedRegion();
138 
139  // Loop on al input images
140  unsigned int numberOfImages = m_Layout[0] * m_Layout[1];
141 
142  // std::cout<<"Number of input images: "<<this->GetNumberOfInputs()<<std::endl;
143 
144  // std::cout<<"Out region: "<<outRegion<<std::endl;
145 
146  for (unsigned int i = 0; i < numberOfImages; ++i)
147  {
148  ImageType* inputTile = const_cast<ImageType*>(this->GetInput(i));
149 
150  RegionType inRegion = OutputRegionToInputRegion(i, outRegion);
151 
152  // std::cout<<"In region: "<<i<<", "<<inRegion<<std::endl;
153  // std::cout<<"tile pointer: "<<inputTile<<std::endl;
154 
155  inputTile->SetRequestedRegion(inRegion);
156  }
157 }
158 
159 template <class TImage>
160 void TileImageFilter<TImage>::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType itkNotUsed(threadId))
161 {
162  // Retrieve output image pointer
163  ImageType* outputPtr = this->GetOutput();
164 
165  // Loop on all input tiles
166  unsigned int numberOfImages = m_Layout[0] * m_Layout[1];
167 
168  for (unsigned int i = 0; i < numberOfImages; ++i)
169  {
170  const ImageType* inputTile = this->GetInput(i);
171 
172  RegionType inRegion = OutputRegionToInputRegion(i, outputRegionForThread);
173  RegionType outRegion = InputRegionToOutputRegion(i, inRegion);
174 
175  // std::cout<<"[thread] outRegion: "<<outRegion<<std::endl;
176 
177  if (inRegion.GetNumberOfPixels() > 0)
178  {
179  // std::cout<<"[thread] "<<i<<" inRegion: "<<inRegion<<std::endl;
180 
181  // std::cout<<"[thread] "<<i<< inputTile->GetBufferedRegion()<<std::endl;
182 
183  itk::ImageRegionConstIterator<ImageType> inIt(inputTile, inRegion);
184  itk::ImageRegionIterator<ImageType> outIt(outputPtr, outRegion);
185 
186  inIt.GoToBegin();
187  outIt.GoToBegin();
188 
189  while (!inIt.IsAtEnd() && !outIt.IsAtEnd())
190  {
191  outIt.Set(inIt.Get());
192  ++inIt;
193  ++outIt;
194  }
195  }
196  }
197 }
198 
199 template <class TImage>
201 {
202  // Retrieve the nth tile pointer
203  const ImageType* tile = this->GetInput(tileIndex);
204 
205  unsigned int tileYIndex = tileIndex / m_Layout[0];
206  unsigned int tileXIndex = tileIndex % m_Layout[0];
207 
208  RegionType out2inRegion = requestedRegion;
209  typename RegionType::IndexType regionIndex = out2inRegion.GetIndex();
210 
211  // Compute tile offsets
212  for (unsigned int i = 0; i < tileXIndex; ++i)
213  {
214  regionIndex[0] -= m_ColumnsSizes.at(i);
215  }
216 
217  for (unsigned int i = 0; i < tileYIndex; ++i)
218  {
219  regionIndex[1] -= m_RowsSizes.at(i);
220  }
221 
222  out2inRegion.SetIndex(regionIndex);
223 
224 
225  // Crop input region
226  if (!out2inRegion.Crop(tile->GetLargestPossibleRegion()))
227  {
228  typename RegionType::IndexType nullIndex;
229  nullIndex.Fill(0);
230  out2inRegion.SetIndex(nullIndex);
231 
232  SizeType nullSize;
233  nullSize.Fill(0);
234  out2inRegion.SetSize(nullSize);
235  }
236 
237  return out2inRegion;
238 }
239 
240 template <class TImage>
242 {
243  // Retrieve the nth tile pointer
244  // const ImageType * tile = this->GetInput(tileIndex);
245 
246  unsigned int tileYIndex = tileIndex / m_Layout[0];
247  unsigned int tileXIndex = tileIndex % m_Layout[0];
248 
249  RegionType out2inRegion = requestedRegion;
250  typename RegionType::IndexType regionIndex = out2inRegion.GetIndex();
251 
252 
253  // Compute tile offsets
254  for (unsigned int i = 0; i < tileXIndex; ++i)
255  {
256  regionIndex[0] += m_ColumnsSizes.at(i);
257  }
258 
259  for (unsigned int i = 0; i < tileYIndex; ++i)
260  {
261  regionIndex[1] += m_RowsSizes.at(i);
262  }
263 
264  out2inRegion.SetIndex(regionIndex);
265 
266  // Crop input region
267  if (!out2inRegion.Crop(this->GetOutput()->GetLargestPossibleRegion()))
268  {
269  SizeType nullSize;
270  nullSize.Fill(0);
271  out2inRegion.SetSize(nullSize);
272  }
273 
274  return out2inRegion;
275 }
276 
277 
278 } // end namespace otb
279 
280 #endif
otb::TileImageFilter::ImageType
TImage ImageType
Definition: otbTileImageFilter.h:63
otb::TileImageFilter::GenerateInputRequestedRegion
void GenerateInputRequestedRegion() override
Definition: otbTileImageFilter.hxx:134
otb::TileImageFilter::~TileImageFilter
~TileImageFilter() override
Definition: otbTileImageFilter.hxx:35
otb::TileImageFilter::OutputRegionToInputRegion
RegionType OutputRegionToInputRegion(unsigned int tileIndex, const RegionType &requestedRegion)
Definition: otbTileImageFilter.hxx:200
otb::TileImageFilter::SizeType
ImageType::SizeType SizeType
Definition: otbTileImageFilter.h:65
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::TileImageFilter::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbTileImageFilter.hxx:40
otb::TileImageFilter::ThreadedGenerateData
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) override
Definition: otbTileImageFilter.hxx:160
otb::TileImageFilter::GenerateOutputInformation
void GenerateOutputInformation() override
Definition: otbTileImageFilter.hxx:47
otb::TileImageFilter::InputRegionToOutputRegion
RegionType InputRegionToOutputRegion(unsigned int tileIndex, const RegionType &requestedRegion)
Definition: otbTileImageFilter.hxx:241
otb::TileImageFilter::RegionType
ImageType::RegionType RegionType
Definition: otbTileImageFilter.h:66
otb::TileImageFilter::TileImageFilter
TileImageFilter()
Definition: otbTileImageFilter.hxx:30
otbTileImageFilter.h