Skip to content
Snippets Groups Projects
Commit 580f3bc6 authored by Guillaume Pasero's avatar Guillaume Pasero
Browse files

ENH: implement sub-sampled texture haralick computation

parent b915a664
No related branches found
No related tags found
No related merge requests found
...@@ -173,10 +173,10 @@ public: ...@@ -173,10 +173,10 @@ public:
itkGetMacro(SubsampleFactor, SizeType); itkGetMacro(SubsampleFactor, SizeType);
/** Set the sub-sampling offset */ /** Set the sub-sampling offset */
itkSetMacro(SubsampleOffset, IndexType); itkSetMacro(SubsampleOffset, OffsetType);
/** Get the sub-sampling offset */ /** Get the sub-sampling offset */
itkGetMacro(SubsampleOffset, IndexType); itkGetMacro(SubsampleOffset, OffsetType);
/** Get the energy output image */ /** Get the energy output image */
OutputImageType * GetEnergyOutput(); OutputImageType * GetEnergyOutput();
...@@ -207,6 +207,8 @@ protected: ...@@ -207,6 +207,8 @@ protected:
ScalarImageToTexturesFilter(); ScalarImageToTexturesFilter();
/** Destructor */ /** Destructor */
~ScalarImageToTexturesFilter() ITK_OVERRIDE; ~ScalarImageToTexturesFilter() ITK_OVERRIDE;
/** Generate the output informations */
void GenerateOutputInformation() ITK_OVERRIDE;
/** Generate the input requested region */ /** Generate the input requested region */
void GenerateInputRequestedRegion() ITK_OVERRIDE; void GenerateInputRequestedRegion() ITK_OVERRIDE;
/** Before Parallel textures extraction */ /** Before Parallel textures extraction */
...@@ -246,7 +248,7 @@ private: ...@@ -246,7 +248,7 @@ private:
SizeType m_SubsampleFactor; SizeType m_SubsampleFactor;
/** Sub-sampling offset */ /** Sub-sampling offset */
IndexType m_SubsampleOffset; OffsetType m_SubsampleOffset;
}; };
} // End namespace otb } // End namespace otb
......
...@@ -39,6 +39,8 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage> ...@@ -39,6 +39,8 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
, m_NumberOfBinsPerAxis(8) , m_NumberOfBinsPerAxis(8)
, m_InputImageMinimum(0) , m_InputImageMinimum(0)
, m_InputImageMaximum(255) , m_InputImageMaximum(255)
, m_SubsampleFactor()
, m_SubsampleOffset()
{ {
// There are 8 outputs corresponding to the 8 textures indices // There are 8 outputs corresponding to the 8 textures indices
this->SetNumberOfRequiredOutputs(8); this->SetNumberOfRequiredOutputs(8);
...@@ -52,6 +54,9 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage> ...@@ -52,6 +54,9 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
this->SetNthOutput(5, OutputImageType::New()); this->SetNthOutput(5, OutputImageType::New());
this->SetNthOutput(6, OutputImageType::New()); this->SetNthOutput(6, OutputImageType::New());
this->SetNthOutput(7, OutputImageType::New()); this->SetNthOutput(7, OutputImageType::New());
this->m_SubsampleFactor.Fill(1);
this->m_SubsampleOffset.Fill(0);
} }
template <class TInputImage, class TOutputImage> template <class TInputImage, class TOutputImage>
...@@ -163,6 +168,36 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage> ...@@ -163,6 +168,36 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
return static_cast<OutputImageType *>(this->GetOutput(7)); return static_cast<OutputImageType *>(this->GetOutput(7));
} }
template <class TInputImage, class TOutputImage>
void
ScalarImageToTexturesFilter<TInputImage, TOutputImage>
::GenerateOutputInformation()
{
// First, call superclass implementation
Superclass::GenerateOutputInformation();
// Compute output size, origin & spacing
OutputImagePointerType outputPtr = this->GetOutput();
InputRegionType inputRegion = this->GetInput()->GetLargestPossibleRegion();
OutputRegionType outputRegion;
outputRegion.SetIndex(0,0);
outputRegion.SetIndex(1,0);
outputRegion.SetSize(0, 1 + (inputRegion.GetSize(0) - 1 - m_SubsampleOffset[0]) / m_SubsampleFactor[0]);
outputRegion.SetSize(1, 1 + (inputRegion.GetSize(1) - 1 - m_SubsampleOffset[1]) / m_SubsampleFactor[1]);
typename OutputImageType::SpacingType outSpacing = this->GetInput()->GetSpacing();
outSpacing[0] *= m_SubsampleFactor[0];
outSpacing[1] *= m_SubsampleFactor[1];
typename OutputImageType::PointType outOrigin;
this->GetInput()->TransformIndexToPhysicalPoint(inputRegion.GetIndex()+m_SubsampleOffset,outOrigin);
outputPtr->SetLargestPossibleRegion(outputRegion);
outputPtr->SetOrigin(outOrigin);
outputPtr->SetSpacing(outSpacing);
}
template <class TInputImage, class TOutputImage> template <class TInputImage, class TOutputImage>
void void
ScalarImageToTexturesFilter<TInputImage, TOutputImage> ScalarImageToTexturesFilter<TInputImage, TOutputImage>
...@@ -189,6 +224,13 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage> ...@@ -189,6 +224,13 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
typename OutputRegionType::SizeType outputSize = outputRequestedRegion.GetSize(); typename OutputRegionType::SizeType outputSize = outputRequestedRegion.GetSize();
typename InputRegionType::IndexType inputIndex; typename InputRegionType::IndexType inputIndex;
typename InputRegionType::SizeType inputSize; typename InputRegionType::SizeType inputSize;
InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();
// Convert index and size to full grid
outputIndex[0] = outputIndex[0] * m_SubsampleFactor[0] + m_SubsampleOffset[0] + inputLargest.GetIndex(0);
outputIndex[1] = outputIndex[1] * m_SubsampleFactor[1] + m_SubsampleOffset[1] + inputLargest.GetIndex(1);
outputSize[0] = 1 + (outputSize[0] - 1) * m_SubsampleFactor[0];
outputSize[1] = 1 + (outputSize[1] - 1) * m_SubsampleFactor[1];
// First, apply offset // First, apply offset
for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim) for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
...@@ -278,6 +320,8 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage> ...@@ -278,6 +320,8 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
const double log2 = vcl_log(2.0); const double log2 = vcl_log(2.0);
InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();
// Set-up progress reporting // Set-up progress reporting
itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
...@@ -295,11 +339,15 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage> ...@@ -295,11 +339,15 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
typename InputRegionType::IndexType inputIndex; typename InputRegionType::IndexType inputIndex;
typename InputRegionType::SizeType inputSize; typename InputRegionType::SizeType inputSize;
// Convert index to full grid
typename OutputImageType::IndexType outIndex;
// First, create an window for neighborhood iterator based on m_Radius // First, create an window for neighborhood iterator based on m_Radius
// For example, if xradius and yradius is 2. window size is 5x5 (2 * radius + 1). // For example, if xradius and yradius is 2. window size is 5x5 (2 * radius + 1).
for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim) for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
{ {
inputIndex[dim] = energyIt.GetIndex()[dim] - m_Radius[dim]; outIndex[dim] = energyIt.GetIndex()[dim] * m_SubsampleFactor[dim] + m_SubsampleOffset[dim] + inputLargest.GetIndex(dim);
inputIndex[dim] = outIndex[dim] - m_Radius[dim];
inputSize[dim] = 2 * m_Radius[dim] + 1; inputSize[dim] = 2 * m_Radius[dim] + 1;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment