Commit 92721844 authored by Julien Michel's avatar Julien Michel
Browse files

Merge branch 'develop' of https://git.orfeo-toolbox.org/git/otb into develop

parents 38ba398b 3320d436
......@@ -87,6 +87,13 @@ SetParameterDescription("channel", "The selected channel index");
SetDefaultParameterInt("channel", 1);
SetMinimumParameterIntValue("channel", 1);
AddParameter(ParameterType_Int, "step", "Computation step");
SetParameterDescription("step", "Step (in pixels) to compute output texture values."
" The first computed pixel position is shifted by (step-1)/2 in both directions.");
SetDefaultParameterInt("step", 1);
SetMinimumParameterIntValue("step", 1);
MandatoryOff("step");
AddRAMParameter();
AddParameter(ParameterType_Group, "parameters", "Texture feature parameters");
......@@ -180,6 +187,12 @@ void DoExecute() ITK_OVERRIDE
offset[0] = GetParameterInt("parameters.xoff");
offset[1] = GetParameterInt("parameters.yoff");
RadiusType stepping;
stepping.Fill(GetParameterInt("step"));
OffsetType stepOffset;
stepOffset.Fill((GetParameterInt("step") - 1) / 2);
m_ExtractorFilter = ExtractorFilterType::New();
m_ExtractorFilter->SetInput(inImage);
m_ExtractorFilter->SetStartX(inImage->GetLargestPossibleRegion().GetIndex(0));
......@@ -214,6 +227,8 @@ void DoExecute() ITK_OVERRIDE
m_HarTexFilter->SetInputImageMinimum(GetParameterFloat("parameters.min"));
m_HarTexFilter->SetInputImageMaximum(GetParameterFloat("parameters.max"));
m_HarTexFilter->SetNumberOfBinsPerAxis(GetParameterInt("parameters.nbbin"));
m_HarTexFilter->SetSubsampleFactor(stepping);
m_HarTexFilter->SetSubsampleOffset(stepOffset);
m_HarTexFilter->UpdateOutputInformation();
m_HarImageList->PushBack(m_HarTexFilter->GetEnergyOutput());
m_HarImageList->PushBack(m_HarTexFilter->GetEntropyOutput());
......@@ -235,6 +250,8 @@ void DoExecute() ITK_OVERRIDE
m_AdvTexFilter->SetInputImageMinimum(GetParameterFloat("parameters.min"));
m_AdvTexFilter->SetInputImageMaximum(GetParameterFloat("parameters.max"));
m_AdvTexFilter->SetNumberOfBinsPerAxis(GetParameterInt("parameters.nbbin"));
m_AdvTexFilter->SetSubsampleFactor(stepping);
m_AdvTexFilter->SetSubsampleOffset(stepOffset);
m_AdvImageList->PushBack(m_AdvTexFilter->GetMeanOutput());
m_AdvImageList->PushBack(m_AdvTexFilter->GetVarianceOutput());
m_AdvImageList->PushBack(m_AdvTexFilter->GetDissimilarityOutput());
......@@ -257,6 +274,8 @@ void DoExecute() ITK_OVERRIDE
m_HigTexFilter->SetInputImageMinimum(GetParameterFloat("parameters.min"));
m_HigTexFilter->SetInputImageMaximum(GetParameterFloat("parameters.max"));
m_HigTexFilter->SetNumberOfBinsPerAxis(GetParameterInt("parameters.nbbin"));
m_HigTexFilter->SetSubsampleFactor(stepping);
m_HigTexFilter->SetSubsampleOffset(stepOffset);
m_HigImageList->PushBack(m_HigTexFilter->GetShortRunEmphasisOutput());
m_HigImageList->PushBack(m_HigTexFilter->GetLongRunEmphasisOutput());
m_HigImageList->PushBack(m_HigTexFilter->GetGreyLevelNonuniformityOutput());
......
......@@ -164,6 +164,18 @@ public:
/** Get the input image maximum */
itkGetMacro(InputImageMaximum, InputPixelType);
/** Set the sub-sampling factor */
itkSetMacro(SubsampleFactor, SizeType);
/** Get the sub-sampling factor */
itkGetMacro(SubsampleFactor, SizeType);
/** Set the sub-sampling offset */
itkSetMacro(SubsampleOffset, OffsetType);
/** Get the sub-sampling offset */
itkGetMacro(SubsampleOffset, OffsetType);
/** Get the mean output image */
OutputImageType * GetMeanOutput();
......@@ -199,6 +211,8 @@ protected:
ScalarImageToAdvancedTexturesFilter();
/** Destructor */
~ScalarImageToAdvancedTexturesFilter() ITK_OVERRIDE;
/** Generate the output informations */
void GenerateOutputInformation() ITK_OVERRIDE;
/** Generate the input requested region */
void GenerateInputRequestedRegion() ITK_OVERRIDE;
/** Before Parallel textures extraction */
......@@ -231,6 +245,11 @@ private:
/** Input image maximum */
InputPixelType m_InputImageMaximum;
/** Sub-sampling factor */
SizeType m_SubsampleFactor;
/** Sub-sampling offset */
OffsetType m_SubsampleOffset;
};
} // End namespace otb
......
......@@ -37,6 +37,8 @@ ScalarImageToAdvancedTexturesFilter<TInputImage, TOutputImage>
, m_NumberOfBinsPerAxis(8)
, m_InputImageMinimum(0)
, m_InputImageMaximum(255)
, m_SubsampleFactor()
, m_SubsampleOffset()
{
// There are 10 outputs corresponding to the 9 textures indices
this->SetNumberOfRequiredOutputs(10);
......@@ -52,6 +54,9 @@ ScalarImageToAdvancedTexturesFilter<TInputImage, TOutputImage>
this->SetNthOutput(7, OutputImageType::New());
this->SetNthOutput(8, OutputImageType::New());
this->SetNthOutput(9, OutputImageType::New());
this->m_SubsampleFactor.Fill(1);
this->m_SubsampleOffset.Fill(0);
}
template <class TInputImage, class TOutputImage>
......@@ -188,6 +193,38 @@ ScalarImageToAdvancedTexturesFilter<TInputImage, TOutputImage>
return static_cast<OutputImageType *>(this->GetOutput(9));
}
template <class TInputImage, class TOutputImage>
void
ScalarImageToAdvancedTexturesFilter<TInputImage, TOutputImage>
::GenerateOutputInformation()
{
// First, call superclass implementation
Superclass::GenerateOutputInformation();
// Compute output size, origin & spacing
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);
for (unsigned int i=0 ; i<this->GetNumberOfOutputs() ; i++)
{
OutputImagePointerType outputPtr = this->GetOutput(i);
outputPtr->SetLargestPossibleRegion(outputRegion);
outputPtr->SetOrigin(outOrigin);
outputPtr->SetSpacing(outSpacing);
}
}
template <class TInputImage, class TOutputImage>
void
ScalarImageToAdvancedTexturesFilter<TInputImage, TOutputImage>
......@@ -209,12 +246,19 @@ ScalarImageToAdvancedTexturesFilter<TInputImage, TOutputImage>
// We use only the first output since requested regions for all outputs are enforced to be equal
// by the default GenerateOutputRequestedRegiont() implementation
OutputRegionType outputRequestedRegion = outputPtr->GetRequestedRegion();
InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();
typename OutputRegionType::IndexType outputIndex = outputRequestedRegion.GetIndex();
typename OutputRegionType::SizeType outputSize = outputRequestedRegion.GetSize();
typename InputRegionType::IndexType inputIndex;
typename InputRegionType::SizeType inputSize;
// 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
for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
{
......@@ -311,6 +355,8 @@ ScalarImageToAdvancedTexturesFilter<TInputImage, TOutputImage>
const unsigned int histSize = m_NumberOfBinsPerAxis;
const long unsigned int twiceHistSize = 2 * m_NumberOfBinsPerAxis;
InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();
// Set-up progress reporting
itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
......@@ -330,11 +376,16 @@ ScalarImageToAdvancedTexturesFilter<TInputImage, TOutputImage>
typename InputRegionType::IndexType inputIndex;
typename InputRegionType::SizeType inputSize;
// Convert index to full grid
typename OutputImageType::IndexType outIndex;
// 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 (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
{
inputIndex[dim] = varianceIt.GetIndex()[dim] - m_Radius[dim];
outIndex[dim] = varianceIt.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;
}
......
......@@ -148,6 +148,18 @@ public:
itkSetMacro(FastCalculations, bool);
itkBooleanMacro(FastCalculations);
/** Set the sub-sampling factor */
itkSetMacro(SubsampleFactor, SizeType);
/** Get the sub-sampling factor */
itkGetMacro(SubsampleFactor, SizeType);
/** Set the sub-sampling offset */
itkSetMacro(SubsampleOffset, OffsetType);
/** Get the sub-sampling offset */
itkGetMacro(SubsampleOffset, OffsetType);
/** Get the Short Run Emphasis output image */
OutputImageType * GetShortRunEmphasisOutput();
......@@ -186,6 +198,8 @@ protected:
ScalarImageToHigherOrderTexturesFilter();
/** Destructor */
~ScalarImageToHigherOrderTexturesFilter() ITK_OVERRIDE;
/** Generate the output informations */
void GenerateOutputInformation() ITK_OVERRIDE;
/** Generate the input requested region */
void GenerateInputRequestedRegion() ITK_OVERRIDE;
/** Parallel textures extraction */
......@@ -215,6 +229,12 @@ private:
/** Fast calculation */
bool m_FastCalculations;
/** Sub-sampling factor */
SizeType m_SubsampleFactor;
/** Sub-sampling offset */
OffsetType m_SubsampleOffset;
};
} // End namespace otb
......
......@@ -32,7 +32,9 @@ ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
m_NumberOfBinsPerAxis(8),
m_InputImageMinimum(0),
m_InputImageMaximum(255),
m_FastCalculations(false)
m_FastCalculations(false),
m_SubsampleFactor(),
m_SubsampleOffset()
{
// There are 11 outputs corresponding to the 8 textures indices
this->SetNumberOfRequiredOutputs(10);
......@@ -71,6 +73,8 @@ ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
}
this->SetOffsets( offsets );
this->m_SubsampleFactor.Fill(1);
this->m_SubsampleOffset.Fill(0);
}
template <class TInputImage, class TOutputImage>
......@@ -231,6 +235,38 @@ ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
this->SetOffsets( offsetVector );
}
template <class TInputImage, class TOutputImage>
void
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GenerateOutputInformation()
{
// First, call superclass implementation
Superclass::GenerateOutputInformation();
// Compute output size, origin & spacing
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);
for (unsigned int i=0 ; i<this->GetNumberOfOutputs() ; i++)
{
OutputImagePointerType outputPtr = this->GetOutput(i);
outputPtr->SetLargestPossibleRegion(outputRegion);
outputPtr->SetOrigin(outOrigin);
outputPtr->SetSpacing(outSpacing);
}
}
template <class TInputImage, class TOutputImage>
void
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
......@@ -252,7 +288,17 @@ ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
// We use only the first output since requested regions for all outputs are enforced to be equal
// by the default GenerateOutputRequestedRegiont() implementation
OutputRegionType outputRequestedRegion = outputPtr->GetRequestedRegion();
InputRegionType inputRequestedRegion = outputRequestedRegion;
typename OutputRegionType::IndexType outputIndex = outputRequestedRegion.GetIndex();
typename OutputRegionType::SizeType outputSize = outputRequestedRegion.GetSize();
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];
InputRegionType inputRequestedRegion(outputIndex,outputSize);
// Apply the radius
inputRequestedRegion.PadByRadius(m_Radius);
......@@ -297,6 +343,8 @@ ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
inputPtr->TransformIndexToPhysicalPoint( outputImagesIterators[0].GetIndex() + m_Radius, bottomRightPoint );
double maxDistance = topLeftPoint.EuclideanDistanceTo(bottomRightPoint);
InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();
// Set-up progress reporting
itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
......@@ -304,12 +352,17 @@ ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
while ( !outputImagesIterators[0].IsAtEnd() )
{
// Compute the region on which run-length matrix will be estimated
typename InputRegionType::IndexType inputIndex = outputImagesIterators[0].GetIndex() - m_Radius;
typename InputRegionType::IndexType inputIndex;
typename InputRegionType::SizeType inputSize;
// First, apply offset
// Convert index to full grid
typename OutputImageType::IndexType outIndex;
for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
{
outIndex[dim] = outputImagesIterators[0].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;
}
......
......@@ -166,6 +166,18 @@ public:
/** Get the input image maximum */
itkGetMacro(InputImageMaximum, InputPixelType);
/** Set the sub-sampling factor */
itkSetMacro(SubsampleFactor, SizeType);
/** Get the sub-sampling factor */
itkGetMacro(SubsampleFactor, SizeType);
/** Set the sub-sampling offset */
itkSetMacro(SubsampleOffset, OffsetType);
/** Get the sub-sampling offset */
itkGetMacro(SubsampleOffset, OffsetType);
/** Get the energy output image */
OutputImageType * GetEnergyOutput();
......@@ -195,6 +207,8 @@ protected:
ScalarImageToTexturesFilter();
/** Destructor */
~ScalarImageToTexturesFilter() ITK_OVERRIDE;
/** Generate the output informations */
void GenerateOutputInformation() ITK_OVERRIDE;
/** Generate the input requested region */
void GenerateInputRequestedRegion() ITK_OVERRIDE;
/** Before Parallel textures extraction */
......@@ -230,6 +244,11 @@ private:
//TODO: should we use constexpr? only c++11 and problem for msvc
inline double GetPixelValueTolerance() const {return 0.0001; }
/** Sub-sampling factor */
SizeType m_SubsampleFactor;
/** Sub-sampling offset */
OffsetType m_SubsampleOffset;
};
} // End namespace otb
......
......@@ -39,6 +39,8 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
, m_NumberOfBinsPerAxis(8)
, m_InputImageMinimum(0)
, m_InputImageMaximum(255)
, m_SubsampleFactor()
, m_SubsampleOffset()
{
// There are 8 outputs corresponding to the 8 textures indices
this->SetNumberOfRequiredOutputs(8);
......@@ -52,6 +54,9 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
this->SetNthOutput(5, OutputImageType::New());
this->SetNthOutput(6, OutputImageType::New());
this->SetNthOutput(7, OutputImageType::New());
this->m_SubsampleFactor.Fill(1);
this->m_SubsampleOffset.Fill(0);
}
template <class TInputImage, class TOutputImage>
......@@ -163,6 +168,38 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
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
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);
for (unsigned int i=0 ; i<this->GetNumberOfOutputs() ; i++)
{
OutputImagePointerType outputPtr = this->GetOutput(i);
outputPtr->SetLargestPossibleRegion(outputRegion);
outputPtr->SetOrigin(outOrigin);
outputPtr->SetSpacing(outSpacing);
}
}
template <class TInputImage, class TOutputImage>
void
ScalarImageToTexturesFilter<TInputImage, TOutputImage>
......@@ -189,6 +226,13 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
typename OutputRegionType::SizeType outputSize = outputRequestedRegion.GetSize();
typename InputRegionType::IndexType inputIndex;
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
for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
......@@ -278,6 +322,8 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
const double log2 = vcl_log(2.0);
InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();
// Set-up progress reporting
itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
......@@ -295,11 +341,15 @@ ScalarImageToTexturesFilter<TInputImage, TOutputImage>
typename InputRegionType::IndexType inputIndex;
typename InputRegionType::SizeType inputSize;
// Convert index to full grid
typename OutputImageType::IndexType outIndex;
// 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 (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;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment