OTB  9.0.0
Orfeo Toolbox
otbScalarImageToHigherOrderTexturesFilter.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 otbScalarImageToHigherOrderTexturesFilter_hxx
22 #define otbScalarImageToHigherOrderTexturesFilter_hxx
23 
25 #include "itkImageRegionIteratorWithIndex.h"
26 #include "itkImageRegionIterator.h"
27 #include "itkProgressReporter.h"
28 
29 namespace otb
30 {
31 template <class TInputImage, class TOutputImage>
33  : m_Radius(), m_NumberOfBinsPerAxis(8), m_InputImageMinimum(0), m_InputImageMaximum(255), m_FastCalculations(false), m_SubsampleFactor(), m_SubsampleOffset()
34 {
35  // There are 10 outputs corresponding to the 8 textures indices
36  this->SetNumberOfRequiredOutputs(10);
37 
38  // Create the 11 outputs
39  this->SetNthOutput(0, OutputImageType::New());
40  this->SetNthOutput(1, OutputImageType::New());
41  this->SetNthOutput(2, OutputImageType::New());
42  this->SetNthOutput(3, OutputImageType::New());
43  this->SetNthOutput(4, OutputImageType::New());
44  this->SetNthOutput(5, OutputImageType::New());
45  this->SetNthOutput(6, OutputImageType::New());
46  this->SetNthOutput(7, OutputImageType::New());
47  this->SetNthOutput(8, OutputImageType::New());
48  this->SetNthOutput(9, OutputImageType::New());
49 
50  m_Radius.Fill(10);
51 
52  // Set the offset directions to their defaults: half of all the possible
53  // directions 1 pixel away. (The other half is included by symmetry.)
54  // We use a neighborhood iterator to calculate the appropriate offsets.
55  typedef itk::Neighborhood<typename InputImageType::PixelType, InputImageType::ImageDimension> NeighborhoodType;
56  NeighborhoodType hood;
57  hood.SetRadius(1);
58 
59  // select all "previous" neighbors that are face+edge+vertex
60  // connected to the current pixel. do not include the center pixel.
61  unsigned int centerIndex = hood.GetCenterNeighborhoodIndex();
62  OffsetVectorPointer offsets = OffsetVector::New();
63  for (unsigned int d = 0; d < centerIndex; d++)
64  {
65  OffsetType offset = hood.GetOffset(d);
66  offsets->push_back(offset);
67  }
68  this->SetOffsets(offsets);
69 
70  this->m_SubsampleFactor.Fill(1);
71  this->m_SubsampleOffset.Fill(0);
72 }
73 
74 template <class TInputImage, class TOutputImage>
76 {
77 }
78 
79 template <class TInputImage, class TOutputImage>
82 {
83  return this->GetOutput(0);
84 }
85 
86 template <class TInputImage, class TOutputImage>
89 {
90  return this->GetOutput(1);
91 }
92 
93 template <class TInputImage, class TOutputImage>
96 {
97  return this->GetOutput(2);
98 }
99 
100 template <class TInputImage, class TOutputImage>
103 {
104  return this->GetOutput(3);
105 }
106 
107 template <class TInputImage, class TOutputImage>
110 {
111  return this->GetOutput(4);
112 }
113 
114 template <class TInputImage, class TOutputImage>
117 {
118  return this->GetOutput(5);
119 }
120 
121 template <class TInputImage, class TOutputImage>
124 {
125  return this->GetOutput(6);
126 }
127 
128 template <class TInputImage, class TOutputImage>
131 {
132  return this->GetOutput(7);
133 }
134 
135 template <class TInputImage, class TOutputImage>
138 {
139  return this->GetOutput(8);
140 }
141 
142 template <class TInputImage, class TOutputImage>
145 {
146  return this->GetOutput(9);
147 }
148 
149 template <class TInputImage, class TOutputImage>
151 {
152  OffsetVectorPointer offsetVector = OffsetVector::New();
153  offsetVector->push_back(offset);
154  this->SetOffsets(offsetVector);
155 }
156 
157 template <class TInputImage, class TOutputImage>
159 {
160  // Compute output size, origin & spacing
161  const InputImageType* inputPtr = this->GetInput();
162  InputRegionType inputRegion = inputPtr->GetLargestPossibleRegion();
163  OutputRegionType outputRegion;
164  outputRegion.SetIndex(0, 0);
165  outputRegion.SetIndex(1, 0);
166  outputRegion.SetSize(0, 1 + (inputRegion.GetSize(0) - 1 - m_SubsampleOffset[0]) / m_SubsampleFactor[0]);
167  outputRegion.SetSize(1, 1 + (inputRegion.GetSize(1) - 1 - m_SubsampleOffset[1]) / m_SubsampleFactor[1]);
168 
169  typename OutputImageType::SpacingType outSpacing = inputPtr->GetSignedSpacing();
170  outSpacing[0] *= m_SubsampleFactor[0];
171  outSpacing[1] *= m_SubsampleFactor[1];
172 
173  typename OutputImageType::PointType outOrigin;
174  inputPtr->TransformIndexToPhysicalPoint(inputRegion.GetIndex() + m_SubsampleOffset, outOrigin);
175 
176  for (unsigned int i = 0; i < this->GetNumberOfOutputs(); i++)
177  {
178  OutputImagePointerType outputPtr = this->GetOutput(i);
179  outputPtr->CopyInformation(inputPtr);
180  outputPtr->SetLargestPossibleRegion(outputRegion);
181  outputPtr->SetOrigin(outOrigin);
182  outputPtr->SetSignedSpacing(outSpacing);
183  }
184 }
185 
186 
187 template <class TInputImage, class TOutputImage>
189 {
190  // First, call superclass implementation
191  Superclass::GenerateInputRequestedRegion();
192 
193  // Retrieve the input and output pointers
194  InputImagePointerType inputPtr = const_cast<InputImageType*>(this->GetInput());
195  OutputImagePointerType outputPtr = this->GetOutput();
196 
197  if (!inputPtr || !outputPtr)
198  {
199  return;
200  }
201 
202  // Retrieve the output requested region
203  // We use only the first output since requested regions for all outputs are enforced to be equal
204  // by the default GenerateOutputRequestedRegiont() implementation
205  OutputRegionType outputRequestedRegion = outputPtr->GetRequestedRegion();
206  typename OutputRegionType::IndexType outputIndex = outputRequestedRegion.GetIndex();
207  typename OutputRegionType::SizeType outputSize = outputRequestedRegion.GetSize();
208  InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();
209 
210  // Convert index and size to full grid
211  outputIndex[0] = outputIndex[0] * m_SubsampleFactor[0] + m_SubsampleOffset[0] + inputLargest.GetIndex(0);
212  outputIndex[1] = outputIndex[1] * m_SubsampleFactor[1] + m_SubsampleOffset[1] + inputLargest.GetIndex(1);
213  outputSize[0] = 1 + (outputSize[0] - 1) * m_SubsampleFactor[0];
214  outputSize[1] = 1 + (outputSize[1] - 1) * m_SubsampleFactor[1];
215 
216  InputRegionType inputRequestedRegion(outputIndex, outputSize);
217 
218  // Apply the radius
219  inputRequestedRegion.PadByRadius(m_Radius);
220 
221  // Try to apply the requested region to the input image
222  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
223  {
224  inputPtr->SetRequestedRegion(inputRequestedRegion);
225  }
226  else
227  {
228  // Build an exception
229  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
230  e.SetLocation(ITK_LOCATION);
231  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
232  e.SetDataObject(inputPtr);
233  throw e;
234  }
235 }
236 
237 template <class TInputImage, class TOutputImage>
239  itk::ThreadIdType threadId)
240 {
241  // Retrieve the input and output pointers
242  const InputImageType* inputPtr = this->GetInput();
243 
244  typedef typename itk::ImageRegionIterator<OutputImageType> IteratorType;
245  std::vector<IteratorType> outputImagesIterators;
246 
247  for (unsigned int i = 0; i < this->GetNumberOfOutputs(); ++i)
248  {
249  outputImagesIterators.push_back(IteratorType(this->GetOutput(i), outputRegionForThread));
250  outputImagesIterators[i].GoToBegin();
251  }
252 
253  // Compute the max possible run length (in physical unit)
254  typename InputImageType::PointType topLeftPoint;
255  typename InputImageType::PointType bottomRightPoint;
256  inputPtr->TransformIndexToPhysicalPoint(outputImagesIterators[0].GetIndex() - m_Radius, topLeftPoint);
257  inputPtr->TransformIndexToPhysicalPoint(outputImagesIterators[0].GetIndex() + m_Radius, bottomRightPoint);
258  double maxDistance = topLeftPoint.EuclideanDistanceTo(bottomRightPoint);
259 
260  InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();
261 
262  // Set-up progress reporting
263  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
264 
265  // Iterate on outputs to compute textures
266  while (!outputImagesIterators[0].IsAtEnd())
267  {
268  // Compute the region on which run-length matrix will be estimated
269  typename InputRegionType::IndexType inputIndex;
270  typename InputRegionType::SizeType inputSize;
271 
272  // Convert index to full grid
273  typename OutputImageType::IndexType outIndex;
274 
275  for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
276  {
277  outIndex[dim] = outputImagesIterators[0].GetIndex()[dim] * m_SubsampleFactor[dim] + m_SubsampleOffset[dim] + inputLargest.GetIndex(dim);
278  inputIndex[dim] = outIndex[dim] - m_Radius[dim];
279  inputSize[dim] = 2 * m_Radius[dim] + 1;
280  }
281 
282  // Build the input region
283  InputRegionType inputRegion;
284  inputRegion.SetIndex(inputIndex);
285  inputRegion.SetSize(inputSize);
286 
287  inputRegion.Crop(inputPtr->GetBufferedRegion());
288 
289  // Create a local image corresponding to the input region
290  InputImagePointerType localInputImage = InputImageType::New();
291  localInputImage->SetRegions(inputRegion);
292  localInputImage->Allocate();
293  typedef itk::ImageRegionIteratorWithIndex<InputImageType> ImageRegionIteratorType;
294  typedef itk::ImageRegionConstIteratorWithIndex<InputImageType> ImageRegionConstIteratorType;
295  ImageRegionConstIteratorType itInputPtr(inputPtr, inputRegion);
296  ImageRegionIteratorType itLocalInputImage(localInputImage, inputRegion);
297  for (itInputPtr.GoToBegin(), itLocalInputImage.GoToBegin(); !itInputPtr.IsAtEnd(); ++itInputPtr, ++itLocalInputImage)
298  {
299  itLocalInputImage.Set(itInputPtr.Get());
300  }
301 
302  typename ScalarImageToRunLengthFeaturesFilterType::Pointer runLengthFeatureCalculator = ScalarImageToRunLengthFeaturesFilterType::New();
303  runLengthFeatureCalculator->SetInput(localInputImage);
304  runLengthFeatureCalculator->SetOffsets(m_Offsets);
305  runLengthFeatureCalculator->SetNumberOfBinsPerAxis(m_NumberOfBinsPerAxis);
306  runLengthFeatureCalculator->SetPixelValueMinMax(m_InputImageMinimum, m_InputImageMaximum);
307  runLengthFeatureCalculator->SetDistanceValueMinMax(0, maxDistance);
308 
309  runLengthFeatureCalculator->Update();
310 
311  typename ScalarImageToRunLengthFeaturesFilterType::FeatureValueVector& featuresMeans = *(runLengthFeatureCalculator->GetFeatureMeans().GetPointer());
312 
313  // Fill output
314  for (unsigned int i = 0; i < this->GetNumberOfOutputs(); ++i)
315  {
316  // Fill output
317  outputImagesIterators[i].Set(featuresMeans[i]);
318  // Increment iterators
319  ++outputImagesIterators[i];
320  }
321  // Update progress
322  progress.CompletedPixel();
323  }
324 }
325 
326 } // End namespace otb
327 
328 #endif
otb::ScalarImageToHigherOrderTexturesFilter::~ScalarImageToHigherOrderTexturesFilter
~ScalarImageToHigherOrderTexturesFilter() override
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:75
otb::ScalarImageToHigherOrderTexturesFilter::GenerateOutputInformation
void GenerateOutputInformation() override
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:158
otb::ScalarImageToHigherOrderTexturesFilter::ThreadedGenerateData
void ThreadedGenerateData(const OutputRegionType &outputRegion, itk::ThreadIdType threadId) override
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:238
otb::ScalarImageToHigherOrderTexturesFilter::GetShortRunHighGreyLevelEmphasisOutput
OutputImageType * GetShortRunHighGreyLevelEmphasisOutput()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:130
otb::ScalarImageToHigherOrderTexturesFilter::SetOffsets
virtual void SetOffsets(const OffsetVector *_arg)
otb::ScalarImageToHigherOrderTexturesFilter::m_Radius
SizeType m_Radius
Definition: otbScalarImageToHigherOrderTexturesFilter.h:208
otb::ScalarImageToHigherOrderTexturesFilter::OutputImagePointerType
OutputImageType::Pointer OutputImagePointerType
Definition: otbScalarImageToHigherOrderTexturesFilter.h:95
otb::ScalarImageToHigherOrderTexturesFilter::OffsetVectorPointer
OffsetVector::Pointer OffsetVectorPointer
Definition: otbScalarImageToHigherOrderTexturesFilter.h:101
otb::ScalarImageToHigherOrderTexturesFilter::GetShortRunEmphasisOutput
OutputImageType * GetShortRunEmphasisOutput()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:81
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::ScalarImageToHigherOrderTexturesFilter::GetGreyLevelNonuniformityOutput
OutputImageType * GetGreyLevelNonuniformityOutput()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:95
otbScalarImageToHigherOrderTexturesFilter.h
otb::ScalarImageToHigherOrderTexturesFilter::OutputRegionType
OutputImageType::RegionType OutputRegionType
Definition: otbScalarImageToHigherOrderTexturesFilter.h:96
otb::ScalarImageToHigherOrderTexturesFilter::SetOffset
void SetOffset(const OffsetType offset)
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:150
otb::ScalarImageToHigherOrderTexturesFilter::InputImageType
TInpuImage InputImageType
Definition: otbScalarImageToHigherOrderTexturesFilter.h:86
otb::ScalarImageToHigherOrderTexturesFilter::GetLowGreyLevelRunEmphasisOutput
OutputImageType * GetLowGreyLevelRunEmphasisOutput()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:109
otb::ScalarImageToHigherOrderTexturesFilter::InputRegionType
InputImageType::RegionType InputRegionType
Definition: otbScalarImageToHigherOrderTexturesFilter.h:92
otb::ScalarImageToHigherOrderTexturesFilter::GetShortRunLowGreyLevelEmphasisOutput
OutputImageType * GetShortRunLowGreyLevelEmphasisOutput()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:123
otb::ScalarImageToHigherOrderTexturesFilter::InputImagePointerType
InputImageType::Pointer InputImagePointerType
Definition: otbScalarImageToHigherOrderTexturesFilter.h:90
otb::ScalarImageToHigherOrderTexturesFilter::GetLongRunHighGreyLevelEmphasisOutput
OutputImageType * GetLongRunHighGreyLevelEmphasisOutput()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:144
otb::ScalarImageToHigherOrderTexturesFilter::OffsetType
InputImageType::OffsetType OffsetType
Definition: otbScalarImageToHigherOrderTexturesFilter.h:99
otb::ScalarImageToHigherOrderTexturesFilter::GetHighGreyLevelRunEmphasisOutput
OutputImageType * GetHighGreyLevelRunEmphasisOutput()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:116
otb::ScalarImageToHigherOrderTexturesFilter::GetLongRunEmphasisOutput
OutputImageType * GetLongRunEmphasisOutput()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:88
otb::ScalarImageToHigherOrderTexturesFilter::m_SubsampleOffset
OffsetType m_SubsampleOffset
Definition: otbScalarImageToHigherOrderTexturesFilter.h:229
otb::ScalarImageToHigherOrderTexturesFilter::ScalarImageToHigherOrderTexturesFilter
ScalarImageToHigherOrderTexturesFilter()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:32
otb::ScalarImageToHigherOrderTexturesFilter::GetLongRunLowGreyLevelEmphasisOutput
OutputImageType * GetLongRunLowGreyLevelEmphasisOutput()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:137
otb::ScalarImageToHigherOrderTexturesFilter::m_SubsampleFactor
SizeType m_SubsampleFactor
Definition: otbScalarImageToHigherOrderTexturesFilter.h:226
otb::ScalarImageToHigherOrderTexturesFilter::GetRunLengthNonuniformityOutput
OutputImageType * GetRunLengthNonuniformityOutput()
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:102
otb::ScalarImageToHigherOrderTexturesFilter::GenerateInputRequestedRegion
void GenerateInputRequestedRegion() override
Definition: otbScalarImageToHigherOrderTexturesFilter.hxx:188
otb::ScalarImageToHigherOrderTexturesFilter::OutputImageType
TOutputImage OutputImageType
Definition: otbScalarImageToHigherOrderTexturesFilter.h:94