21 #ifndef otbScalarImageToHigherOrderTexturesFilter_hxx
22 #define otbScalarImageToHigherOrderTexturesFilter_hxx
26 #include "itkImageRegionIteratorWithIndex.h"
27 #include "itkImageRegionIterator.h"
28 #include "itkProgressReporter.h"
32 template <
class TInputImage,
class TOutputImage>
34 : m_Radius(), m_NumberOfBinsPerAxis(8), m_InputImageMinimum(0), m_InputImageMaximum(255), m_FastCalculations(false), m_SubsampleFactor(), m_SubsampleOffset()
36 this->DynamicMultiThreadingOn();
38 this->SetNumberOfRequiredOutputs(10);
41 this->SetNthOutput(0, OutputImageType::New());
42 this->SetNthOutput(1, OutputImageType::New());
43 this->SetNthOutput(2, OutputImageType::New());
44 this->SetNthOutput(3, OutputImageType::New());
45 this->SetNthOutput(4, OutputImageType::New());
46 this->SetNthOutput(5, OutputImageType::New());
47 this->SetNthOutput(6, OutputImageType::New());
48 this->SetNthOutput(7, OutputImageType::New());
49 this->SetNthOutput(8, OutputImageType::New());
50 this->SetNthOutput(9, OutputImageType::New());
57 typedef itk::Neighborhood<typename InputImageType::PixelType, InputImageType::ImageDimension> NeighborhoodType;
58 NeighborhoodType hood;
63 unsigned int centerIndex = hood.GetCenterNeighborhoodIndex();
65 for (
unsigned int d = 0; d < centerIndex; d++)
68 offsets->push_back(offset);
76 template <
class TInputImage,
class TOutputImage>
81 template <
class TInputImage,
class TOutputImage>
85 return this->GetOutput(0);
88 template <
class TInputImage,
class TOutputImage>
92 return this->GetOutput(1);
95 template <
class TInputImage,
class TOutputImage>
99 return this->GetOutput(2);
102 template <
class TInputImage,
class TOutputImage>
106 return this->GetOutput(3);
109 template <
class TInputImage,
class TOutputImage>
113 return this->GetOutput(4);
116 template <
class TInputImage,
class TOutputImage>
120 return this->GetOutput(5);
123 template <
class TInputImage,
class TOutputImage>
127 return this->GetOutput(6);
130 template <
class TInputImage,
class TOutputImage>
134 return this->GetOutput(7);
137 template <
class TInputImage,
class TOutputImage>
141 return this->GetOutput(8);
144 template <
class TInputImage,
class TOutputImage>
148 return this->GetOutput(9);
151 template <
class TInputImage,
class TOutputImage>
155 offsetVector->push_back(offset);
156 this->SetOffsets(offsetVector);
159 template <
class TInputImage,
class TOutputImage>
166 outputRegion.SetIndex(0, 0);
167 outputRegion.SetIndex(1, 0);
168 outputRegion.SetSize(0, 1 + (inputRegion.GetSize(0) - 1 - m_SubsampleOffset[0]) / m_SubsampleFactor[0]);
169 outputRegion.SetSize(1, 1 + (inputRegion.GetSize(1) - 1 - m_SubsampleOffset[1]) / m_SubsampleFactor[1]);
171 typename OutputImageType::SpacingType outSpacing = inputPtr->GetSignedSpacing();
172 outSpacing[0] *= m_SubsampleFactor[0];
173 outSpacing[1] *= m_SubsampleFactor[1];
175 typename OutputImageType::PointType outOrigin;
176 inputPtr->TransformIndexToPhysicalPoint(inputRegion.GetIndex() + m_SubsampleOffset, outOrigin);
178 for (
unsigned int i = 0; i < this->GetNumberOfOutputs(); i++)
181 outputPtr->CopyInformation(inputPtr);
182 outputPtr->SetLargestPossibleRegion(outputRegion);
183 outputPtr->SetOrigin(outOrigin);
184 outputPtr->SetSignedSpacing(outSpacing);
189 template <
class TInputImage,
class TOutputImage>
193 Superclass::GenerateInputRequestedRegion();
199 if (!inputPtr || !outputPtr)
208 typename OutputRegionType::IndexType outputIndex = outputRequestedRegion.GetIndex();
209 typename OutputRegionType::SizeType outputSize = outputRequestedRegion.GetSize();
213 outputIndex[0] = outputIndex[0] * m_SubsampleFactor[0] + m_SubsampleOffset[0] + inputLargest.GetIndex(0);
214 outputIndex[1] = outputIndex[1] * m_SubsampleFactor[1] + m_SubsampleOffset[1] + inputLargest.GetIndex(1);
215 outputSize[0] = 1 + (outputSize[0] - 1) * m_SubsampleFactor[0];
216 outputSize[1] = 1 + (outputSize[1] - 1) * m_SubsampleFactor[1];
221 inputRequestedRegion.PadByRadius(m_Radius);
224 if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
226 inputPtr->SetRequestedRegion(inputRequestedRegion);
231 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
232 e.SetLocation(ITK_LOCATION);
233 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
234 e.SetDataObject(inputPtr);
239 template <
class TInputImage,
class TOutputImage>
245 typedef typename itk::ImageRegionIterator<OutputImageType> IteratorType;
246 std::vector<IteratorType> outputImagesIterators;
248 for (
unsigned int i = 0; i < this->GetNumberOfOutputs(); ++i)
250 outputImagesIterators.push_back(IteratorType(this->GetOutput(i), outputRegionForThread));
251 outputImagesIterators[i].GoToBegin();
255 typename InputImageType::PointType topLeftPoint;
256 typename InputImageType::PointType bottomRightPoint;
257 inputPtr->TransformIndexToPhysicalPoint(outputImagesIterators[0].GetIndex() - m_Radius, topLeftPoint);
258 inputPtr->TransformIndexToPhysicalPoint(outputImagesIterators[0].GetIndex() + m_Radius, bottomRightPoint);
259 double maxDistance = topLeftPoint.EuclideanDistanceTo(bottomRightPoint);
264 while (!outputImagesIterators[0].IsAtEnd())
267 typename InputRegionType::IndexType inputIndex;
268 typename InputRegionType::SizeType inputSize;
271 typename OutputImageType::IndexType outIndex;
273 for (
unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
275 outIndex[dim] = outputImagesIterators[0].GetIndex()[dim] * m_SubsampleFactor[dim] + m_SubsampleOffset[dim] + inputLargest.GetIndex(dim);
276 inputIndex[dim] = outIndex[dim] - m_Radius[dim];
277 inputSize[dim] = 2 * m_Radius[dim] + 1;
282 inputRegion.SetIndex(inputIndex);
283 inputRegion.SetSize(inputSize);
285 inputRegion.Crop(inputPtr->GetBufferedRegion());
289 localInputImage->SetRegions(inputRegion);
290 localInputImage->Allocate();
291 typedef itk::ImageRegionIteratorWithIndex<InputImageType> ImageRegionIteratorType;
292 typedef itk::ImageRegionConstIteratorWithIndex<InputImageType> ImageRegionConstIteratorType;
293 ImageRegionConstIteratorType itInputPtr(inputPtr, inputRegion);
294 ImageRegionIteratorType itLocalInputImage(localInputImage, inputRegion);
295 for (itInputPtr.GoToBegin(), itLocalInputImage.GoToBegin(); !itInputPtr.IsAtEnd(); ++itInputPtr, ++itLocalInputImage)
297 itLocalInputImage.Set(itInputPtr.Get());
300 typename ScalarImageToRunLengthFeaturesFilterType::Pointer runLengthFeatureCalculator = ScalarImageToRunLengthFeaturesFilterType::New();
301 runLengthFeatureCalculator->SetInput(localInputImage);
302 runLengthFeatureCalculator->SetOffsets(m_Offsets);
303 runLengthFeatureCalculator->SetNumberOfBinsPerAxis(m_NumberOfBinsPerAxis);
304 runLengthFeatureCalculator->SetPixelValueMinMax(m_InputImageMinimum, m_InputImageMaximum);
305 runLengthFeatureCalculator->SetDistanceValueMinMax(0, maxDistance);
307 runLengthFeatureCalculator->Update();
309 typename ScalarImageToRunLengthFeaturesFilterType::FeatureValueVector& featuresMeans = *(runLengthFeatureCalculator->GetFeatureMeans().GetPointer());
312 for (
unsigned int i = 0; i < this->GetNumberOfOutputs(); ++i)
315 outputImagesIterators[i].Set(featuresMeans[i]);
317 ++outputImagesIterators[i];
OutputImageType * GetShortRunLowGreyLevelEmphasisOutput()
void GenerateInputRequestedRegion() override
InputImageType::Pointer InputImagePointerType
OffsetType m_SubsampleOffset
OutputImageType * GetHighGreyLevelRunEmphasisOutput()
~ScalarImageToHigherOrderTexturesFilter() override
InputImageType::OffsetType OffsetType
OutputImageType * GetShortRunHighGreyLevelEmphasisOutput()
TOutputImage OutputImageType
OutputImageType * GetShortRunEmphasisOutput()
void GenerateOutputInformation() override
OutputImageType * GetLongRunEmphasisOutput()
InputImageType::RegionType InputRegionType
virtual void SetOffsets(const OffsetVector *_arg)
OutputImageType::Pointer OutputImagePointerType
SizeType m_SubsampleFactor
OutputImageType * GetGreyLevelNonuniformityOutput()
OutputImageType * GetRunLengthNonuniformityOutput()
OffsetVector::Pointer OffsetVectorPointer
OutputImageType * GetLowGreyLevelRunEmphasisOutput()
void DynamicThreadedGenerateData(const OutputRegionType &outputRegion) override
OutputImageType::RegionType OutputRegionType
OutputImageType * GetLongRunLowGreyLevelEmphasisOutput()
ScalarImageToHigherOrderTexturesFilter()
TInpuImage InputImageType
void SetOffset(const OffsetType offset)
OutputImageType * GetLongRunHighGreyLevelEmphasisOutput()
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.