OTB  7.1.0
Orfeo Toolbox
otbSubsampledImageRegionConstIterator.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
3  * Copyright (C) 2007-2012 Institut Mines Telecom / Telecom Bretagne
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 
23 #ifndef otbSubsampledImageRegionConstIterator_hxx
24 #define otbSubsampledImageRegionConstIterator_hxx
25 
27 
28 namespace otb
29 {
30 
31 template <class TImage>
33 {
34  m_SubsampleFactor.Fill(1);
35  m_SubSampledEndOffset = this->m_EndOffset;
36 
37  const IndexType& startIndex = this->m_Region.GetIndex();
38  const SizeType& size = this->m_Region.GetSize();
39 
40  for (unsigned int i = 0; i < ImageIteratorDimension; ++i)
41  {
42  m_FirstUsableIndex[i] = startIndex[i];
43  m_LastUsableIndex[i] = startIndex[i] + static_cast<IndexValueType>(size[i] - 1);
44  }
45 }
46 
47 template <class TImage>
49  : itk::ImageRegionConstIterator<TImage>(ptr, region)
50 {
51  m_SubsampleFactor.Fill(1);
52  m_SubSampledEndOffset = this->m_EndOffset;
53 
54  const IndexType& startIndex = this->m_Region.GetIndex();
55  const SizeType& size = this->m_Region.GetSize();
56 
57  for (unsigned int i = 0; i < ImageIteratorDimension; ++i)
58  {
59  m_FirstUsableIndex[i] = startIndex[i];
60  m_LastUsableIndex[i] = startIndex[i] + static_cast<IndexValueType>(size[i] - 1);
61  }
62 }
63 
64 template <class TImage>
65 SubsampledImageRegionConstIterator<TImage>::SubsampledImageRegionConstIterator(const itk::ImageIterator<TImage>& it) : itk::ImageRegionConstIterator<TImage>(it)
66 {
67  m_SubsampleFactor.Fill(1);
68  m_SubSampledEndOffset = this->m_EndOffset;
69 
70  const IndexType& startIndex = this->m_Region.GetIndex();
71  const SizeType& size = this->m_Region.GetSize();
72 
73  for (unsigned int i = 0; i < ImageIteratorDimension; ++i)
74  {
75  m_FirstUsableIndex[i] = startIndex[i];
76  m_LastUsableIndex[i] = startIndex[i] + static_cast<IndexValueType>(size[i] - 1);
77  }
78 }
79 
80 template <class TImage>
82  : itk::ImageRegionConstIterator<TImage>(it)
83 {
84  m_SubsampleFactor.Fill(1);
85 
86  const IndexType& startIndex = this->m_Region.GetIndex();
87  const SizeType& size = this->m_Region.GetSize();
88 
89  for (unsigned int i = 0; i < ImageIteratorDimension; ++i)
90  {
91  m_FirstUsableIndex[i] = startIndex[i];
92  m_LastUsableIndex[i] = startIndex[i] + static_cast<IndexValueType>(size[i] - 1);
93  }
94 
95  m_SubSampledEndOffset = this->m_Image->ComputeOffset(m_LastUsableIndex) + 1;
96 }
97 
98 template <class TImage>
99 void SubsampledImageRegionConstIterator<TImage>::SetSubsampleFactor(typename IndexType::IndexValueType factor)
100 {
101  IndexType index;
102  index.Fill(factor);
103  SetSubsampleFactor(index);
104 }
105 
106 template <class TImage>
108 {
109  this->m_SubsampleFactor = factor;
110 
111  // Evaluate the last possible pixel.
112  const IndexType& startIndex = this->m_Region.GetIndex();
113  const SizeType& size = this->m_Region.GetSize();
114 
115  for (unsigned int i = 0; i < ImageIteratorDimension; ++i)
116  {
117  m_FirstUsableIndex[i] = startIndex[i];
119  {
120  ++m_FirstUsableIndex[i];
121  }
122  m_LastUsableIndex[i] = startIndex[i] + static_cast<IndexValueType>(m_SubsampleFactor[i] * ((size[i] - 1) / m_SubsampleFactor[i]));
123  }
124 
125  m_SubSampledBeginOffset = this->m_Image->ComputeOffset(m_FirstUsableIndex);
126 
127  // m_SubSampledReverseEndOffset = m_SubSampledBeginOffset - 1;
128  m_SubSampledEndOffset = this->m_Image->ComputeOffset(m_LastUsableIndex) + 1;
129 }
130 
131 template <class TImage>
133 {
134  this->m_Offset = m_SubSampledBeginOffset;
135 
136  const SizeType& size = this->m_Region.GetSize();
137 
138  this->m_SpanBeginOffset = this->m_Offset;
139  this->m_SpanEndOffset = this->m_Offset + static_cast<IndexValueType>(m_SubsampleFactor[0] * ((size[0] - 1) / m_SubsampleFactor[0])) + 1;
140 }
141 
142 template <class TImage>
144 {
145  this->m_Offset = m_SubSampledEndOffset - 1;
146  this->m_SpanEndOffset = this->m_Offset + 1;
147  this->m_SpanBeginOffset = this->m_Offset - m_LastUsableIndex[0];
148 }
149 
150 template <class TImage>
152 {
153  IndexType theIndex = ind;
154 
155  for (unsigned int i = 0; i < ImageIteratorDimension; ++i)
156  {
157  while (theIndex[i] != (m_SubsampleFactor[i] * (theIndex[i] / m_SubsampleFactor[i])))
158  {
159  ++theIndex[i];
160  }
161 
162  if (theIndex[i] > static_cast<IndexValueType>(this->m_Region.GetIndex()[i] + this->m_Region.GetSize()[i]))
163  {
164  theIndex[i] = ind[i];
165  while (theIndex[i] != (m_SubsampleFactor[i] * (theIndex[i] / m_SubsampleFactor[i])))
166  {
167  --theIndex[i];
168  }
169 
170  if (theIndex[i] < this->m_Region.GetIndex()[i])
171  theIndex[i] = ind[i];
172  }
173  }
174  // Superclass::SetIndex( theIndex );
175 
176  OffsetType theOffset = this->m_Image->ComputeOffset(theIndex);
177  SetOffset(theOffset);
178 }
179 
180 template <class TImage>
182 {
183  this->m_Offset = offset;
184 
185  const SizeType& size = this->m_Region.GetSize();
186 
187  this->m_SpanBeginOffset = this->m_Offset;
188  this->m_SpanEndOffset = this->m_Offset + static_cast<IndexValueType>(m_SubsampleFactor[0] * ((size[0] - 1) / m_SubsampleFactor[0])) + 1;
189 }
190 
191 template <class TImage>
193 {
194  IndexType startIndex = this->m_Region.GetIndex();
195  SizeType size = this->m_Region.GetSize();
196 
197  for (unsigned int i = 0; i < ImageIteratorDimension; ++i)
198  {
199  startIndex[i] /= m_SubsampleFactor[i];
200  --size[i];
201  size[i] /= m_SubsampleFactor[i];
202  ++size[i];
203  }
204 
205  RegionType newRegion;
206  newRegion.SetIndex(startIndex);
207  newRegion.SetSize(size);
208 
209 #if 0
210 // #ifndef NDEBUG
211  std::cerr << "InitialImageSize (";
212  for (unsigned int i = 0; i < ImageIteratorDimension - 1; ++i)
213  std::cerr << this->m_Region.GetSize()[i] << ", ";
214  std::cerr << this->m_Region.GetSize()[ImageIteratorDimension - 1] << ") with index (";
215  for (unsigned int i = 0; i < ImageIteratorDimension - 1; ++i)
216  std::cerr << this->m_Region.GetIndex()[i] << ", ";
217  std::cerr << this->m_Region.GetIndex()[ImageIteratorDimension - 1] << ")\n";
218 
219  std::cerr << "NewRegionSize (";
220  for (unsigned int i = 0; i < ImageIteratorDimension - 1; ++i)
221  std::cerr << size[i] << ", ";
222  std::cerr << size[ImageIteratorDimension - 1] << ") with index (";
223  for (unsigned int i = 0; i < ImageIteratorDimension - 1; ++i)
224  std::cerr << startIndex[i] << ", ";
225  std::cerr << startIndex[ImageIteratorDimension - 1] << ")\n";
226 
227  std::cerr << "FirstIndex (";
228  for (unsigned int i = 0; i < ImageIteratorDimension - 1; ++i)
229  std::cerr << m_FirstUsableIndex[i] << ", ";
230  std::cerr << m_FirstUsableIndex[ImageIteratorDimension - 1] << ") offset=";
231  std::cerr << m_SubSampledBeginOffset << "\n";
232 
233  std::cerr << "LastIndex (";
234  for (unsigned int i = 0; i < ImageIteratorDimension - 1; ++i)
235  std::cerr << m_LastUsableIndex[i] << ", ";
236  std::cerr << m_LastUsableIndex[ImageIteratorDimension - 1] << ") offset=";
237  std::cerr << m_SubSampledEndOffset << "\n";
238 #endif
239 
240  return newRegion;
241 }
242 
243 template <class TImage>
245 {
246  // Get the index of the last pixel on the span (row)
247  IndexType ind = this->m_Image->ComputeIndex(static_cast<typename TImage::OffsetValueType>(this->m_Offset));
248 
249  const IndexType& startIndex = this->m_Region.GetIndex();
250  const SizeType& size = this->m_Region.GetSize();
251 
252  // Increment along a row, then wrap at the end of the region row.
253  unsigned int dim;
254 
255  // Check to see if we are past the last pixel in the region
256  // Note that ++ind[0] moves to the next pixel along the row.
257  ind[0] += m_SubsampleFactor[0];
258  bool done = (ind[0] > m_LastUsableIndex[0]);
259  for (unsigned int i = 1; done && i < ImageIteratorDimension; ++i)
260  {
261  done = (ind[i] >= m_LastUsableIndex[i]);
262  }
263 
264  // if the iterator is outside the region (but not past region end) then
265  // we need to wrap around the region
266  dim = 0;
267  if (!done)
268  {
269  while ((dim + 1 < ImageIteratorDimension) && (ind[dim] > m_LastUsableIndex[dim]))
270  {
271  ind[dim] = startIndex[dim];
272  ++dim;
273  ind[dim] += m_SubsampleFactor[dim];
274  }
275  }
276  this->m_Offset = this->m_Image->ComputeOffset(ind);
277  this->m_SpanEndOffset = this->m_Offset + static_cast<IndexValueType>(m_SubsampleFactor[0] * ((size[0] - 1) / m_SubsampleFactor[0])) + 1;
278  this->m_SpanBeginOffset = this->m_Offset;
279 }
280 
281 template <class TImage>
283 {
284  // Get the index of the first pixel on the span (row)
285  IndexType ind = this->m_Image->ComputeIndex(static_cast<IndexValueType>(this->m_Offset));
286  const IndexType& startIndex = this->m_Region.GetIndex();
287 
288  // Deccrement along a row, then wrap at the beginning of the region row.
289  bool done;
290  unsigned int dim;
291 
292  // Check to see if we are past the first pixel in the region
293  // Note that --ind[0] moves to the previous pixel along the row.
294  ind[0] -= m_SubsampleFactor[0];
295  done = (ind[0] <= startIndex[0] - 1);
296  for (unsigned int i = 1; done && i < ImageIteratorDimension; ++i)
297  {
298  done = (ind[i] <= startIndex[i]);
299  }
300 
301  // if the iterator is outside the region (but not past region begin) then
302  // we need to wrap around the region
303  dim = 0;
304  if (!done)
305  {
306  while ((dim < ImageIteratorDimension - 1) && (ind[dim] < startIndex[dim]))
307  {
308  ind[dim] = m_LastUsableIndex[dim];
309  ++dim;
310  ind[dim] -= m_SubsampleFactor[dim];
311  }
312  }
313  this->m_Offset = this->m_Image->ComputeOffset(ind);
314  this->m_SpanEndOffset = this->m_Offset + 1;
315  this->m_SpanBeginOffset = this->m_Offset - m_LastUsableIndex[0];
316 }
317 
318 } // end of namespace otb
319 
320 #endif
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.