Commit eda0b065 authored by Ludovic Hussonnois's avatar Ludovic Hussonnois

ENH: Update Morphological applications According to RFC-81 comments.

Change typedef to use otbWrapperTypes ones.
AddProcess for the applications.
Add progress Report for otbGeodesicMorphology* filters
Add documentation limits.
Remove unnecessary include and Update* call.
parent d3c5f8b7
......@@ -16,8 +16,6 @@
=========================================================================*/
#include <geos_c.h>
#include "otbGeodesicMorphologyDecompositionImageFilter.h"
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
......@@ -50,15 +48,15 @@ public:
typedef itk::SmartPointer<const Self> ConstPointer;
typedef FloatVectorImageType::InternalPixelType InputPixelType;
typedef unsigned char OutputPixelType;
typedef otb::Image<InputPixelType, 2> FloatImageType;
typedef otb::Image<InputPixelType, 2> InputImageType;
typedef otb::Image<OutputPixelType, 2> OutputImageType;
typedef unsigned short LabeledPixelType;
typedef otb::Image<LabeledPixelType, 2> LabeledImageType;
typedef otb::MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType, InputPixelType>
ExtractorFilterType;
typedef otb::ConvexOrConcaveClassificationFilter<InputImageType, OutputImageType> ClassificationFilterType;
typedef otb::ConvexOrConcaveClassificationFilter<FloatImageType, LabeledImageType> ClassificationFilterType;
typedef itk::BinaryBallStructuringElement<InputPixelType, 2> BallStructuringElementType;
typedef itk::BinaryCrossStructuringElement<InputPixelType, 2> CrossStructuringElementType;
......@@ -95,7 +93,7 @@ private:
":math:`f(n) = \\begin{cases} \\stackrel{\\smile}{k} &:& f-\\psi_{N}(f)>\\sigma \\\\ \\stackrel{\\frown}{k} &:& \\psi_{N}(f)-f>\\sigma\\\\ \\bar{k}&:&\\mid f - \\psi_{N}(f) \\mid \\leq \\sigma \\end{cases}`"
"\n\n"
"This output is a labeled image (0 : Flat, 1 : Convex, 2 : Concave)" );
SetDocLimitations( "None" );
SetDocLimitations( "Generation of the morphological classification is not streamable, pay attention to this fact when setting the radius size of the structuring element." );
SetDocAuthors( "OTB-Team" );
SetDocSeeAlso( "otbConvexOrConcaveClassificationFilter class" );
......@@ -115,14 +113,12 @@ private:
AddRAMParameter();
// Strucring Element (Ball | Cross)
// Structuring Element (Ball | Cross)
AddParameter( ParameterType_Choice, "structype", "Structuring Element Type" );
SetParameterDescription( "structype", "Choice of the structuring element type" );
AddChoice( "structype.ball", "Ball" );
AddChoice( "structype.cross", "Cross" );
AddParameter( ParameterType_Int, "radius", "Radius" );
SetParameterDescription( "radius", "Radius of the structuring element (in pixels)" );
SetDefaultParameterInt( "radius", 5 );
......@@ -150,7 +146,7 @@ private:
void DoExecute() ITK_OVERRIDE
{
FloatVectorImageType::Pointer inImage = GetParameterImage( "in" );
inImage->UpdateOutputInformation();
int nBComp = inImage->GetNumberOfComponentsPerPixel();
int selectedChannel = GetParameterInt( "channel" );
......@@ -166,7 +162,6 @@ private:
m_ExtractorFilter->SetSizeX( inImage->GetLargestPossibleRegion().GetSize( 0 ) );
m_ExtractorFilter->SetSizeY( inImage->GetLargestPossibleRegion().GetSize( 1 ) );
m_ExtractorFilter->SetChannel( static_cast<unsigned int>(selectedChannel) );
m_ExtractorFilter->UpdateOutputInformation();
unsigned int sigma = static_cast<unsigned int>(GetParameterInt( "sigma" ));
unsigned int radius = static_cast<unsigned int>(GetParameterInt( "radius" ));
......@@ -178,7 +173,6 @@ private:
m_ClassificationFilter->SetConvexLabel( 1 );
m_ClassificationFilter->SetConcaveLabel( 2 );
if ( GetParameterString( "structype" ) == "ball" )
{
performClassification<BallStructuringElementType>( radius );
......@@ -187,13 +181,14 @@ private:
performClassification<CrossStructuringElementType>( radius );
}
SetParameterOutputImage( "out", m_ClassificationFilter->GetOutput() );
}
template<typename TStructuringElement>
void performClassification(unsigned int radius_size) {
typedef otb::GeodesicMorphologyDecompositionImageFilter<InputImageType, InputImageType, TStructuringElement> TDecompositionImageFilter;
typedef otb::GeodesicMorphologyDecompositionImageFilter<FloatImageType, FloatImageType, TStructuringElement> TDecompositionImageFilter;
typename TDecompositionImageFilter::Pointer decompositionImageFilter;
decompositionImageFilter = TDecompositionImageFilter::New();
......@@ -202,10 +197,10 @@ private:
typename TStructuringElement::RadiusType radius;
radius.Fill( radius_size );
decompositionImageFilter->SetRadius( radius );
AddProcess(decompositionImageFilter, "Image Decomposition");
decompositionImageFilter->Update();
m_ClassificationFilter->SetInputLeveling( decompositionImageFilter->GetOutput() );
SetParameterOutputImage( "out", m_ClassificationFilter->GetOutput() );
}
ExtractorFilterType::Pointer m_ExtractorFilter;
......
......@@ -16,9 +16,7 @@
=========================================================================*/
#include <geos_c.h>
#include <itkComposeImageFilter.h>
#include "itkComposeImageFilter.h"
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
......@@ -50,17 +48,13 @@ public:
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef FloatVectorImageType::InternalPixelType InputPixelType;
typedef float OutputPixelType;
typedef otb::Image<InputPixelType, 2> InputImageType;
typedef otb::VectorImage<OutputPixelType, 2> TOutputVectorImage;
typedef FloatVectorImageType::InternalPixelType InputVectorPixelType;
typedef otb::MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType, InputPixelType>
typedef otb::MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType, InputVectorPixelType>
ExtractorFilterType;
typedef itk::BinaryBallStructuringElement<InputPixelType, 2> BallStructuringElementType;
typedef itk::BinaryCrossStructuringElement<InputPixelType, 2> CrossStructuringElementType;
typedef itk::BinaryBallStructuringElement<InputVectorPixelType, 2> BallStructuringElementType;
typedef itk::BinaryCrossStructuringElement<InputVectorPixelType, 2> CrossStructuringElementType;
/** Standard macro */
itkNewMacro( Self );
......@@ -101,7 +95,7 @@ private:
"\n"
"Output convex, concave and leveling images with N bands, where N is the number of levels." );
SetDocLimitations( "None" );
SetDocLimitations( "Generation of the multi scale decomposition is not streamable, pay attention to this fact when setting the number of iterating levels." );
SetDocAuthors( "OTB-Team" );
SetDocSeeAlso( "otbGeodesicMorphologyDecompositionImageFilter class" );
......@@ -166,7 +160,6 @@ private:
void DoExecute() ITK_OVERRIDE
{
FloatVectorImageType::Pointer inImage = GetParameterImage( "in" );
inImage->UpdateOutputInformation();
int nBComp = inImage->GetNumberOfComponentsPerPixel();
int selectedChannel = GetParameterInt( "channel" );
......@@ -182,8 +175,6 @@ private:
m_ExtractorFilter->SetSizeX( inImage->GetLargestPossibleRegion().GetSize( 0 ) );
m_ExtractorFilter->SetSizeY( inImage->GetLargestPossibleRegion().GetSize( 1 ) );
m_ExtractorFilter->SetChannel( static_cast<unsigned int>(GetParameterInt( "channel" )) );
m_ExtractorFilter->UpdateOutputInformation();
unsigned int numberOfLevels = static_cast<unsigned int>(GetParameterInt( "levels" ));
unsigned int initValue = static_cast<unsigned int>(GetParameterInt( "radius" ));
......@@ -202,9 +193,9 @@ private:
template<typename StructuringElement>
void performDecomposition(unsigned int numberOfLevels, unsigned int step, unsigned int initValue) {
typedef otb::GeodesicMorphologyIterativeDecompositionImageFilter<InputImageType, StructuringElement> TDecompositionImageFilter;
typedef otb::GeodesicMorphologyIterativeDecompositionImageFilter<FloatImageType, StructuringElement> TDecompositionImageFilter;
typedef typename TDecompositionImageFilter::OutputImageListType TImageList;
typedef otb::ImageListToVectorImageFilter<TImageList, TOutputVectorImage> TListToVectorImageFilter;
typedef otb::ImageListToVectorImageFilter<TImageList, FloatVectorImageType> TListToVectorImageFilter;
typename TDecompositionImageFilter::Pointer decompositionImageFilter;
decompositionImageFilter = TDecompositionImageFilter::New();
......@@ -212,6 +203,7 @@ private:
decompositionImageFilter->SetNumberOfIterations( numberOfLevels );
decompositionImageFilter->SetInitialValue( initValue );
decompositionImageFilter->SetStep( step );
AddProcess(decompositionImageFilter, "Image Decomposition");
decompositionImageFilter->Update();
typename TListToVectorImageFilter::Pointer levelingListToVectorImageFilter = TListToVectorImageFilter::New();
......
......@@ -17,7 +17,6 @@
=========================================================================*/
#include <geos_c.h>
#include <itkComposeImageFilter.h>
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
......@@ -39,10 +38,13 @@
#include "otbMorphologicalProfilesSegmentationFilter.h"
#include "otbGeodesicMorphologyIterativeDecompositionImageFilter.h"
namespace otb {
namespace Wrapper {
namespace otb
{
namespace Wrapper
{
class MorphologicalProfilesAnalysis : public Application {
class MorphologicalProfilesAnalysis : public Application
{
public:
/** Standard class typedefs. */
typedef MorphologicalProfilesAnalysis Self;
......@@ -51,16 +53,11 @@ public:
typedef itk::SmartPointer<const Self> ConstPointer;
typedef FloatVectorImageType::InternalPixelType InputPixelType;
typedef float OutputPixelType;
typedef unsigned short LabeledPixelType;
typedef otb::Image<InputPixelType, 2> InputImageType;
typedef otb::Image<OutputPixelType, 2> OutputImageType;
typedef unsigned short LabeledPixelType;
typedef otb::Image<LabeledPixelType, 2> LabeledImageType;
typedef otb::VectorImage<OutputPixelType, 2> TOutputVectorImage;
typedef otb::MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType, InputPixelType>
ExtractorFilterType;
typedef otb::MultiToMonoChannelExtractROI<InputPixelType, InputPixelType> ExtractorFilterType;
typedef itk::BinaryBallStructuringElement<InputPixelType, 2> BallStructuringElementType;
typedef itk::BinaryCrossStructuringElement<InputPixelType, 2> CrossStructuringElementType;
......@@ -104,7 +101,7 @@ private:
"- A :math:`N` multi band image for the opening/closing normal or derivative profiles.\n"
"- A mono band image for the opening/closing characteristics.\n"
"- A labeled image for the classification\n" );
SetDocLimitations( "None" );
SetDocLimitations( "Generation of the morphological profile is not streamable, pay attention to this fact when setting the radius initial size and step of the structuring element." );
SetDocAuthors( "OTB-Team" );
SetDocSeeAlso( "otbMorphologicalOpeningProfileFilter, otbMorphologicalClosingProfileFilter, otbProfileToProfileDerivativeFilter, otbProfileDerivativeToMultiScaleCharacteristicsFilter, otbMultiScaleConvexOrConcaveClassificationFilter, classes" );
......@@ -123,7 +120,7 @@ private:
AddRAMParameter();
// Strucring Element (Ball | Cross)
// Structuring Element (Ball | Cross)
AddParameter( ParameterType_Choice, "structype", "Structuring Element Type" );
SetParameterDescription( "structype", "Choice of the structuring element type" );
AddChoice( "structype.ball", "Ball" );
......@@ -179,18 +176,16 @@ private:
void DoExecute() ITK_OVERRIDE
{
FloatVectorImageType::Pointer inImage = GetParameterImage( "in" );
inImage->UpdateOutputInformation();
int nBComp = inImage->GetNumberOfComponentsPerPixel();
int selectedChannel = GetParameterInt( "channel" );
if ( selectedChannel > nBComp )
if( selectedChannel > nBComp )
{
itkExceptionMacro( << "The specified channel index for input image is invalid." );
}
m_ExtractorFilter = ExtractorFilterType::New();
m_ExtractorFilter->SetInput( inImage );
m_ExtractorFilter->SetStartX( static_cast<unsigned int>(inImage->GetLargestPossibleRegion().GetIndex( 0 )) );
......@@ -198,7 +193,6 @@ private:
m_ExtractorFilter->SetSizeX( inImage->GetLargestPossibleRegion().GetSize( 0 ) );
m_ExtractorFilter->SetSizeY( inImage->GetLargestPossibleRegion().GetSize( 1 ) );
m_ExtractorFilter->SetChannel( static_cast<unsigned int>(GetParameterInt( "channel" )) );
m_ExtractorFilter->UpdateOutputInformation();
unsigned int profileSize = static_cast<unsigned int>(GetParameterInt( "size" ));
unsigned short initValue = static_cast<unsigned short>(GetParameterInt( "radius" ));
......@@ -210,7 +204,8 @@ private:
if ( GetParameterString( "structype" ) == "ball" )
{
performProfileAnalysis<BallStructuringElementType>( profile, profileSize, initValue, step, sigma );
} else // Cross
}
else // Cross
{
performProfileAnalysis<CrossStructuringElementType>( profile, profileSize, initValue, step, sigma );
}
......@@ -221,16 +216,12 @@ private:
performProfileAnalysis(std::string profile, unsigned int profileSize, unsigned short initValue,
unsigned short step, float sigma) {
typedef otb::MorphologicalOpeningProfileFilter<InputImageType, InputImageType, StructuringElementType>
OpeningProfileFilterType;
typedef otb::MorphologicalClosingProfileFilter<InputImageType, InputImageType, StructuringElementType>
ClosingProfileFilterType;
typedef otb::ProfileToProfileDerivativeFilter<InputImageType, InputImageType> DerivativeFilterType;
typedef otb::MorphologicalOpeningProfileFilter<FloatImageType, FloatImageType, StructuringElementType> OpeningProfileFilterType;
typedef otb::MorphologicalClosingProfileFilter<FloatImageType, FloatImageType, StructuringElementType> ClosingProfileFilterType;
typedef otb::ProfileToProfileDerivativeFilter<FloatImageType, FloatImageType> DerivativeFilterType;
typedef otb::MultiScaleConvexOrConcaveClassificationFilter<InputImageType, LabeledImageType>
MultiScaleClassificationFilterType;
typedef otb::ProfileDerivativeToMultiScaleCharacteristicsFilter<InputImageType, OutputImageType, LabeledImageType>
MultiScaleCharacteristicsFilterType;
typedef otb::MultiScaleConvexOrConcaveClassificationFilter<FloatImageType, LabeledImageType> MultiScaleClassificationFilterType;
typedef otb::ProfileDerivativeToMultiScaleCharacteristicsFilter<FloatImageType, FloatImageType, LabeledImageType> MultiScaleCharacteristicsFilterType;
// Instantiation
typename OpeningProfileFilterType::Pointer oprofileFilter;
......@@ -279,6 +270,7 @@ private:
classificationFilter->SetClosingProfileCharacteristics( cmsCharFilter->GetOutputCharacteristics() );
classificationFilter->SetSigma( sigma );
classificationFilter->SetLabelSeparator( static_cast<unsigned short>(initValue + profileSize * step) );
AddProcess(classificationFilter, "Classification");
classificationFilter->Update();
SetParameterOutputImage( "out", classificationFilter->GetOutput() );
}
......@@ -292,8 +284,8 @@ private:
bool profile, bool derivative, bool characteristics,
unsigned int profileSize, unsigned short initValue, unsigned short step) {
typedef ImageList<InputImageType> TImageList;
typedef otb::ImageListToVectorImageFilter<TImageList, TOutputVectorImage> TListToVectorImageFilter;
typedef ImageList<FloatImageType> TImageList;
typedef otb::ImageListToVectorImageFilter<TImageList, FloatVectorImageType> TListToVectorImageFilter;
profileFilter = TProfileFilter::New();
profileFilter->SetInput( m_ExtractorFilter->GetOutput() );
......@@ -305,6 +297,7 @@ private:
{
TListToVectorImageFilter::Pointer listToVectorImageFilter = TListToVectorImageFilter::New();
listToVectorImageFilter->SetInput( profileFilter->GetOutput() );
AddProcess(listToVectorImageFilter, "Profile");
listToVectorImageFilter->Update();
SetParameterOutputImage( "out", listToVectorImageFilter->GetOutput() );
return;
......@@ -317,6 +310,7 @@ private:
{
TListToVectorImageFilter::Pointer listToVectorImageFilter = TListToVectorImageFilter::New();
listToVectorImageFilter->SetInput( derivativeFilter->GetOutput() );
AddProcess(listToVectorImageFilter, "Derivative");
listToVectorImageFilter->Update();
SetParameterOutputImage( "out", listToVectorImageFilter->GetOutput() );
return;
......@@ -329,6 +323,7 @@ private:
if ( characteristics )
{
AddProcess(msCharFilter, "Characteristics");
msCharFilter->Update();
SetParameterOutputImage( "out", msCharFilter->GetOutputCharacteristics() );
}
......
......@@ -174,6 +174,8 @@ private:
bool m_PreserveIntensities;
/** Use fully connected morphological operators */
bool m_FullyConnected;
/** Progress accumulator to report internal filter progress */
itk::ProgressAccumulator::Pointer m_Progress;
};
} // End namespace otb
......
......@@ -36,12 +36,24 @@ GeodesicMorphologyDecompositionImageFilter<TInputImage, TOutputImage, TStructuri
m_Radius.Fill(1);
// Create a process accumulator for tracking the progress of minipipeline
m_Progress = itk::ProgressAccumulator::New();
m_Progress->SetMiniPipelineFilter(this);
m_OpeningFilter = OpeningFilterType::New();
m_ClosingFilter = ClosingFilterType::New();
m_LevelingFilter = LevelingFilterType::New();
m_ConvexFilter = ConvexFilterType::New();
m_ConcaveFilter = ConcaveFilterType::New();
// Register Internal Filter for progress
m_Progress->RegisterInternalFilter(m_OpeningFilter, 0.2);
m_Progress->RegisterInternalFilter(m_ClosingFilter, 0.2);
m_Progress->RegisterInternalFilter(m_LevelingFilter, 0.2);
m_Progress->RegisterInternalFilter(m_ConvexFilter, 0.2);
m_Progress->RegisterInternalFilter(m_ConcaveFilter, 0.2);
m_FullyConnected = true;
m_PreserveIntensities = true;
}
......
......@@ -146,6 +146,8 @@ private:
unsigned int m_InitialValue;
/** The number of iterations */
unsigned int m_NumberOfIterations;
/** Progress accumulator to report internal filter progress */
itk::ProgressAccumulator::Pointer m_Progress;
};
} // End namespace otb
......
......@@ -32,6 +32,10 @@ template <class TImage, class TStructuringElement>
GeodesicMorphologyIterativeDecompositionImageFilter<TImage, TStructuringElement>
::GeodesicMorphologyIterativeDecompositionImageFilter()
{
// Create a process accumulator for tracking the progress of minipipeline
m_Progress = itk::ProgressAccumulator::New();
m_Progress->SetMiniPipelineFilter(this);
this->SetNumberOfRequiredInputs(1);
this->SetNumberOfRequiredOutputs(3);
m_NumberOfIterations = 2;
......@@ -185,6 +189,10 @@ GeodesicMorphologyIterativeDecompositionImageFilter<TImage, TStructuringElement>
while (i < m_NumberOfIterations)
{
filter = DecompositionFilterType::New();
// Register Internal Filter for progress
m_Progress->RegisterInternalFilter(filter, 1./m_NumberOfIterations);
typename StructuringElementType::RadiusType radius;
radius.Fill(m_InitialValue + i * m_Step);
filter->SetRadius(radius);
......
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