OTB  6.1.0
Orfeo Toolbox
otbStreamingShrinkImageFilter.txx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2017 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 otbStreamingShrinkImageFilter_txx
22 #define otbStreamingShrinkImageFilter_txx
23 
26 #include "otbMacro.h"
27 #include "itkProgressReporter.h"
28 
29 namespace otb
30 {
31 
32 template <class TImage>
34  : m_ShrinkFactor(10)
35 {
36 }
37 
38 template <class TImage>
40 {
41 }
42 
43 template <class TImage>
44 void
46 {
47  typedef otb::StreamingShrinkImageRegionSplitter TileSplitterType;
48  TileSplitterType::Pointer splitter = TileSplitterType::New();
49  splitter->SetShrinkFactor(m_ShrinkFactor);
50  this->m_Splitter = splitter;
51 
52  unsigned long nbDivisions = this->EstimateOptimalNumberOfDivisions(input, region, 0);
53  this->m_ComputedNumberOfSplits = this->m_Splitter->GetNumberOfSplits(region, nbDivisions);
54  otbMsgDevMacro(<< "Number of split : " << this->m_ComputedNumberOfSplits)
55 
56  // Save the region to generate the splits later
57  this->m_Region = region;
58 }
59 
60 
62 template <class TInputImage, class TOutputImage>
65  : m_ShrinkFactor(10)
66 {
67  this->SetNumberOfRequiredInputs(1);
68  this->SetNumberOfRequiredOutputs(1);
69 }
71 
73 template <class TInputImage, class TOutputImage>
76 {
77 
78 }
79 
80 template<class TInputImage, class TOutputImage>
81 void
84 {
85  Superclass::GenerateOutputInformation();
86 
87  const InputImageType* input = this->GetInput();
88 
89  OutputImageType* output = this->GetOutput();
90 
91  if (input)
92  {
93  output->CopyInformation(input);
94  output->SetLargestPossibleRegion(input->GetLargestPossibleRegion());
95 
96  if (output->GetRequestedRegion().GetNumberOfPixels() == 0)
97  {
98  output->SetRequestedRegion(output->GetLargestPossibleRegion());
99  }
100  }
101 }
102 
103 template<class TInputImage, class TOutputImage>
104 void
107 {
108  // This is commented to prevent the streaming of the whole image for the first stream strip
109  // It shall not cause any problem because the output image of this filter is not intended to be used.
110  //InputImagePointer image = const_cast< TInputImage * >( this->GetInput() );
111  //this->GraftOutput( image );
112  // Nothing that needs to be allocated for the remaining outputs
113 }
114 
115 
116 template<class TInputImage, class TOutputImage>
117 void
120 {
121  // Get pointers to the input and output
122  InputImageType* inputPtr = const_cast<InputImageType*>(this->GetInput());
123  inputPtr->UpdateOutputInformation();
124 
125  m_ShrunkOutput = OutputImageType::New();
126  m_ShrunkOutput->CopyInformation(inputPtr);
127 
128  const typename InputImageType::SpacingType&
129  inputSpacing = inputPtr->GetSpacing();
130  const typename InputImageType::SizeType& inputSize
131  = inputPtr->GetLargestPossibleRegion().GetSize();
132  const typename InputImageType::IndexType& inputIndex
133  = inputPtr->GetLargestPossibleRegion().GetIndex();
134  typename InputImageType::IndexType startIndex;
135 
136  typename OutputImageType::SpacingType shrunkOutputSpacing;
137  typename OutputImageType::RegionType shrunkOutputLargestPossibleRegion;
138  typename OutputImageType::SizeType shrunkOutputSize;
139  typename OutputImageType::IndexType shrunkOutputStartIndex;
140  typename OutputImageType::PointType shrunkOutputOrigin;
141 
142  for (unsigned int i = 0; i < OutputImageType::ImageDimension; ++i)
143  {
144  startIndex[i] = inputIndex[i] + (m_ShrinkFactor - 1) / 2;
145  if (m_ShrinkFactor > inputSize[i])
146  startIndex[i] = inputIndex[i] + (inputSize[i] - 1) / 2;
147  m_Offset[i] = startIndex[i] % m_ShrinkFactor;
148  shrunkOutputSpacing[i] = inputSpacing[i] * static_cast<double>(m_ShrinkFactor);
149  shrunkOutputSize[i] = inputSize[i] > m_ShrinkFactor ? inputSize[i] / m_ShrinkFactor : 1;
150 
151  shrunkOutputOrigin[i] = inputPtr->GetOrigin()[i] + inputSpacing[i] * startIndex[i];
152 
153  // we choose to output a region with a start index [0,0]
154  // the origin is set accordingly
155  shrunkOutputStartIndex[i] = 0;
156  }
157 
158  m_ShrunkOutput->SetSpacing(shrunkOutputSpacing);
159  m_ShrunkOutput->SetOrigin(shrunkOutputOrigin);
160 
161  shrunkOutputLargestPossibleRegion.SetSize(shrunkOutputSize);
162  shrunkOutputLargestPossibleRegion.SetIndex(shrunkOutputStartIndex);
163 
164  m_ShrunkOutput->SetRegions(shrunkOutputLargestPossibleRegion);
165  m_ShrunkOutput->Allocate();
166 }
167 
168 template<class TInputImage, class TOutputImage>
169 void
172 {
173 }
174 
175 template<class TInputImage, class TOutputImage>
176 void
179 {
180 }
181 
182 template<class TInputImage, class TOutputImage>
183 void
185 ::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType threadId)
186 {
187  //std::cout << "outputRegionForThread " << threadId << " " << outputRegionForThread << std::endl;
188  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
189  const InputImageType* inputPtr = this->GetInput();
190 
191  itk::ImageRegionConstIteratorWithIndex<InputImageType> inIt(inputPtr, outputRegionForThread);
192  for(inIt.GoToBegin(); !inIt.IsAtEnd(); ++inIt, progress.CompletedPixel())
193  {
194  const IndexType& inIndex = inIt.GetIndex();
195  // TODO the pixel value should be taken near the centre of the cell, not at the corners
196  if ((inIndex[0] - m_Offset[0]) % m_ShrinkFactor == 0
197  && (inIndex[1] - m_Offset[1]) % m_ShrinkFactor == 0 )
198  {
199  IndexType shrunkIndex;
200  shrunkIndex[0] = (inIndex[0] - m_Offset[0]) / m_ShrinkFactor;
201  shrunkIndex[1] = (inIndex[1] - m_Offset[1]) / m_ShrinkFactor;
202  if (m_ShrunkOutput->GetLargestPossibleRegion().IsInside(shrunkIndex))
203  m_ShrunkOutput->SetPixel(shrunkIndex, inIt.Get());
204  }
205  }
206 }
207 
208 template<class TInputImage, class TOutputImage>
209 void
212 {
213 }
214 
215 template <class TImage, class TOutputImage>
216 void
218 ::PrintSelf(std::ostream& os, itk::Indent indent) const
219 {
220  Superclass::PrintSelf(os, indent);
221  os << indent << "Shrink factor: " << m_ShrinkFactor << std::endl;
222 }
223 
224 } // End namespace otb
225 #endif
itk::Size< Monteverdi_DIMENSION > SizeType
Definition: mvdTypes.h:146
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) ITK_OVERRIDE
PixelType Get(void) const
const IndexType & GetIndex() const
void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE
itk::Index< Monteverdi_DIMENSION > IndexType
Definition: mvdTypes.h:142
TInputImage InputImageType
unsigned int ThreadIdType
VectorImageType::SpacingType SpacingType
Definition: mvdTypes.h:190
TOutputImage OutputImageType
void PrepareStreaming(itk::DataObject *input, const RegionType &region) ITK_OVERRIDE
VectorImageType::PointType PointType
Definition: mvdTypes.h:198
const SizeValueType * GetSize() const
#define otbMsgDevMacro(x)
Definition: otbMacro.h:98