OTB  7.1.0
Orfeo Toolbox
otbImageRegionNonUniformMultidimensionalSplitter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999-2011 Insight Software Consortium
3  * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
4  *
5  * This file is part of Orfeo Toolbox
6  *
7  * https://www.orfeo-toolbox.org/
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #ifndef otbImageRegionNonUniformMultidimensionalSplitter_hxx
23 #define otbImageRegionNonUniformMultidimensionalSplitter_hxx
25 
26 namespace otb
27 {
28 
32 template <unsigned int VImageDimension>
34 {
35  const SizeType& regionSize = region.GetSize();
36 
37  // requested number of splits per dimension
38  double splitsPerDimension[VImageDimension];
39  // ::ceil( std::pow((double) requestedNumber, 1.0/(double) VImageDimension));
40 
41  unsigned int numberOfPiecesLeft = requestedNumber;
42  unsigned int j, numPieces;
43  numPieces = 1;
44 
45  for (j = VImageDimension; j > 0; --j)
46  {
47  if (regionSize[j - 1] < numberOfPiecesLeft)
48  {
49  splitsPerDimension[j - 1] = regionSize[j - 1];
50  }
51  else
52  {
53  splitsPerDimension[j - 1] = numberOfPiecesLeft;
54  }
55  numberOfPiecesLeft = (unsigned int)::ceil(numberOfPiecesLeft / splitsPerDimension[j - 1]);
56  numPieces *= (unsigned int)splitsPerDimension[j - 1];
57  }
58 
59  // if a given dimension has fewer pixels that splitsPerDimension, then
60  // only split number of pixels times
61  // unsigned int i, numPieces;
62  // numPieces = 1;
63  // for (i=0; i < VImageDimension; ++i)
64  // {
65  // if (regionSize[i] < splitsPerDimension)
66  // {
67  // numPieces *= regionSize[i];
68  // }
69  // else
70  // {
71  // numPieces *= (unsigned int) splitsPerDimension;
72  // }
73  // }
74 
75  return numPieces;
76 }
77 
81 template <unsigned int VImageDimension>
82 itk::ImageRegion<VImageDimension> ImageRegionNonUniformMultidimensionalSplitter<VImageDimension>::GetSplit(unsigned int i, unsigned int numberOfPieces,
83  const RegionType& region)
84 {
85  RegionType splitRegion;
86  IndexType splitIndex;
87  SizeType splitSize, regionSize;
88 
89  // Initialize the splitRegion to the requested region
90  splitRegion = region;
91  splitIndex = splitRegion.GetIndex();
92  splitSize = splitRegion.GetSize();
93 
94  regionSize = region.GetSize();
95 
96  // requested number of splits per dimension
97  double splitsPerDimension[VImageDimension];
98  // ::ceil( std::pow((double) numberOfPieces, 1.0/(double) VImageDimension));
99 
100  unsigned int numberOfPiecesLeft = numberOfPieces;
101 
102  unsigned int j;
103  for (j = VImageDimension; j > 0; --j)
104  {
105  if (regionSize[j - 1] < numberOfPiecesLeft)
106  {
107  splitsPerDimension[j - 1] = regionSize[j - 1];
108  }
109  else
110  {
111  splitsPerDimension[j - 1] = numberOfPiecesLeft;
112  }
113  numberOfPiecesLeft = (unsigned int)::ceil(numberOfPiecesLeft / splitsPerDimension[j - 1]);
114  }
115 
116  // if a given dimension has fewer pixels that splitsPerDimension, then
117  // only split number of pixels times
118  unsigned int splits[VImageDimension], pixelsPerSplit[VImageDimension];
119  unsigned int numPieces;
120  unsigned int ijk[VImageDimension];
121  unsigned int offsetTable[VImageDimension];
122  numPieces = 1;
123  for (j = 0; j < VImageDimension; ++j)
124  {
125  offsetTable[j] = numPieces;
126  if (regionSize[j] < splitsPerDimension[j])
127  {
128  splits[j] = regionSize[j];
129  pixelsPerSplit[j] = 1;
130  numPieces *= regionSize[j];
131  }
132  else
133  {
134  splits[j] = (unsigned int)splitsPerDimension[j];
135  pixelsPerSplit[j] = (unsigned int)::ceil(regionSize[j] / (double)splits[j]);
136  numPieces *= (unsigned int)splitsPerDimension[j];
137  }
138  }
139 
140  // determine which split we are in
141  unsigned int offset = i;
142  for (j = VImageDimension - 1; j > 0; j--)
143  {
144  ijk[j] = offset / offsetTable[j];
145  offset -= (ijk[j] * offsetTable[j]);
146  }
147  ijk[0] = offset;
148 
149  // compute the split
150  for (j = 0; j < VImageDimension; ++j)
151  {
152  splitIndex[j] += ijk[j] * pixelsPerSplit[j];
153  if (ijk[j] < splits[j] - 1)
154  {
155  splitSize[j] = pixelsPerSplit[j];
156  }
157  else
158  {
159  // this dimension is falling off the edge of the image
160  splitSize[j] = splitSize[j] - ijk[j] * pixelsPerSplit[j];
161  }
162  }
163 
164  // set the split region ivars
165  splitRegion.SetIndex(splitIndex);
166  splitRegion.SetSize(splitSize);
167 
168  itkDebugMacro(" Split Piece: " << std::endl << splitRegion);
169 
170  return splitRegion;
171 }
172 
176 template <unsigned int VImageDimension>
178 {
179  Superclass::PrintSelf(os, indent);
180 }
181 
182 } // end namespace otb
183 
184 #endif
RegionType GetSplit(unsigned int i, unsigned int numberOfPieces, const RegionType &region) override
unsigned int GetNumberOfSplits(const RegionType &region, unsigned int requestedNumber) override
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
void PrintSelf(std::ostream &os, itk::Indent indent) const override