Commit b369932e authored by Julien Michel's avatar Julien Michel

Merge branch 'use_functor_filter_morphologicalprofiles' into 'develop'

Use FunctorImageFilter to refactor filters in MorphologicalProfiles module

See merge request !321
parents 83c6e649 ec20df78
......@@ -270,12 +270,13 @@ private:
}
classificationFilter = MultiScaleClassificationFilterType::New();
classificationFilter->SetOpeningProfileDerivativeMaxima( omsCharFilter->GetOutput() );
classificationFilter->SetOpeningProfileCharacteristics( omsCharFilter->GetOutputCharacteristics() );
classificationFilter->SetClosingProfileDerivativeMaxima( cmsCharFilter->GetOutput() );
classificationFilter->SetClosingProfileCharacteristics( cmsCharFilter->GetOutputCharacteristics() );
classificationFilter->SetSigma( sigma );
classificationFilter->SetLabelSeparator( static_cast<unsigned short>(initValue + profileSize * step) );
using namespace Functor::MultiScaleConvexOrConcaveDecisionRule_tags;
classificationFilter->SetVariadicNamedInput<max_opening_profile_derivative>( omsCharFilter->GetOutput() );
classificationFilter->SetVariadicNamedInput<opening_profile_characteristics>( omsCharFilter->GetOutputCharacteristics() );
classificationFilter->SetVariadicNamedInput<max_closing_profile_derivative>( cmsCharFilter->GetOutput() );
classificationFilter->SetVariadicNamedInput<closing_profile_characteristics>( cmsCharFilter->GetOutputCharacteristics() );
classificationFilter->GetModifiableFunctor().SetSigma( sigma );
classificationFilter->GetModifiableFunctor().SetLabelSeparator( static_cast<unsigned short>(initValue + profileSize * step) );
AddProcess(classificationFilter, "Classification");
classificationFilter->Update();
SetParameterOutputImage( "out", classificationFilter->GetOutput() );
......
......@@ -22,7 +22,6 @@
#define otbClosingOpeningMorphologicalFilter_hxx
#include "otbClosingOpeningMorphologicalFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkGrayscaleMorphologicalOpeningImageFilter.h"
#include "itkGrayscaleMorphologicalClosingImageFilter.h"
#include "itkProgressAccumulator.h"
......
......@@ -22,7 +22,6 @@
#define otbGeodesicMorphologyDecompositionImageFilter_h
#include "otbGeodesicMorphologyLevelingFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkSubtractImageFilter.h"
#include "itkOpeningByReconstructionImageFilter.h"
#include "itkClosingByReconstructionImageFilter.h"
......
......@@ -88,9 +88,12 @@ GeodesicMorphologyDecompositionImageFilter<TInputImage, TOutputImage, TStructuri
m_ConcaveFilter->SetInput1(m_ClosingFilter->GetOutput());
m_ConcaveFilter->SetInput2(this->GetInput());
m_LevelingFilter->SetInput(this->GetInput());
m_LevelingFilter->SetInputConvexMap(m_ConvexFilter->GetOutput());
m_LevelingFilter->SetInputConcaveMap(m_ConcaveFilter->GetOutput());
using namespace otb::Functor::LevelingFunctor_tags;
// Template keyword mandatory to avoid parsing error when using
// template methods within template code
m_LevelingFilter->template SetVariadicNamedInput<pixel>(this->GetInput());
m_LevelingFilter->template SetVariadicNamedInput<convex_pixel>(m_ConvexFilter->GetOutput());
m_LevelingFilter->template SetVariadicNamedInput<concave_pixel>(m_ConcaveFilter->GetOutput());
m_ConvexFilter->GraftOutput(this->GetConvexMap());
m_ConvexFilter->Update();
......
......@@ -21,16 +21,25 @@
#ifndef otbGeodesicMorphologyLevelingFilter_h
#define otbGeodesicMorphologyLevelingFilter_h
#include "itkTernaryFunctorImageFilter.h"
#include "otbFunctorImageFilter.h"
namespace otb
{
namespace Functor
{
namespace LevelingFunctor_tags
{
struct pixel {};
struct convex_pixel {};
struct concave_pixel {};
}
/** \class LevelingFunctor
* \brief This functor performs the pixel-wise leveling operation needed in the
* geodesic morphology decomposition filter. For more details, please refer to
* the documentation of this filter.
*
* Use otb::GeodesicMorphologyLevelingFilter to apply it image-wise.
*
* \sa GeodesicMorphologyDecompositionImageFilter
*
* \ingroup OTBMorphologicalProfiles
......@@ -44,7 +53,7 @@ public:
/// Destructor
virtual ~LevelingFunctor() {}
inline TOutput operator ()(const TInput& pixel, const TInputMap& convexPixel, const TInputMap& concavePixel)
inline TOutput operator ()(const TInput& pixel, const TInputMap& convexPixel, const TInputMap& concavePixel) const
{
TOutput result;
......@@ -65,77 +74,25 @@ public:
};
} // end namespace Functor
/** \class GeodesicMorphologyLevelingFilter
/** \typedef GeodesicMorphologyLevelingFilter
* \brief This filter performs the leveling operation defined in the documentation of
* the geodesic decomposition image filter, given the original image, convex and concave membership
* functions. Please refer to the documentation of this filter for more details.
*
* It applies the Functor::LevelingFunctor image-wise.
*
* \sa GeodesicMorphologyDecompositionImageFilter
*
*
* \ingroup OTBMorphologicalProfiles
*/
template <class TInputImage, class TInputMaps, class TOutputImage>
class ITK_EXPORT GeodesicMorphologyLevelingFilter
: public itk::TernaryFunctorImageFilter<TInputImage, TInputImage,
TInputImage, TOutputImage,
Functor::LevelingFunctor<typename TInputImage::PixelType,
typename TInputMaps::PixelType,
typename TOutputImage::PixelType> >
{
public:
/** Standard typedefs */
typedef GeodesicMorphologyLevelingFilter Self;
typedef itk::TernaryFunctorImageFilter<TInputImage, TInputImage,
TInputImage, TOutputImage,
Functor::LevelingFunctor<typename TInputImage::PixelType,
typename TInputMaps::PixelType,
typename TOutputImage::PixelType> > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Type macro */
itkNewMacro(Self);
/** Creation through object factory macro */
itkTypeMacro(GeodesicMorphologyLevelingFilter, TernaryFunctorImageFilter);
/**
* Set the convex membership image.
*/
void SetInputConvexMap(const TInputMaps * convexMap)
{
this->SetInput2(convexMap);
}
/**
* Set the concave membership image.
*/
void SetInputConcaveMap(const TInputMaps * concaveMap)
{
this->SetInput3(concaveMap);
}
/**
* Set the original input image
*/
using Superclass::SetInput;
void SetInput(const TInputImage * input) override
{
this->SetInput1(input);
}
protected:
/** Constructor */
GeodesicMorphologyLevelingFilter() {};
/** Destructor */
~GeodesicMorphologyLevelingFilter() override {}
/**PrintSelf method */
void PrintSelf(std::ostream& os, itk::Indent indent) const override
{
Superclass::PrintSelf(os, indent);
}
private:
GeodesicMorphologyLevelingFilter(const Self &) = delete;
void operator =(const Self&) = delete;
};
template <class TInputImage, class TInputMaps, class TOutputImage>
using GeodesicMorphologyLevelingFilter = FunctorImageFilter
< Functor::LevelingFunctor<typename TInputImage::PixelType,
typename TInputMaps::PixelType,
typename TOutputImage::PixelType>,
std::tuple<typename Functor::LevelingFunctor_tags::pixel,
typename Functor::LevelingFunctor_tags::convex_pixel,
typename Functor::LevelingFunctor_tags::concave_pixel > >;
} // End namespace otb
#endif
......@@ -22,7 +22,6 @@
#define otbMorphologicalClosingProfileFilter_h
#include "otbImageToProfileFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkClosingByReconstructionImageFilter.h"
namespace otb
......
......@@ -22,7 +22,6 @@
#define otbMorphologicalOpeningProfileFilter_h
#include "otbImageToProfileFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkOpeningByReconstructionImageFilter.h"
namespace otb
......
......@@ -49,10 +49,13 @@ MorphologicalProfilesSegmentationFilter<TInputImage,TOutputImage,TInternalPrecis
m_OpeningCharacteristicsFilter->SetInput(m_OpeningDerivativeProfile->GetOutput());
m_ClosingCharacteristicsFilter->SetInput(m_ClosingDerivativeProfile->GetOutput());
m_ClassificationFilter->SetOpeningProfileDerivativeMaxima(m_OpeningCharacteristicsFilter->GetOutput());
m_ClassificationFilter->SetOpeningProfileCharacteristics(m_OpeningCharacteristicsFilter->GetOutputCharacteristics());
m_ClassificationFilter->SetClosingProfileDerivativeMaxima(m_ClosingCharacteristicsFilter->GetOutput());
m_ClassificationFilter->SetClosingProfileCharacteristics(m_ClosingCharacteristicsFilter->GetOutputCharacteristics());
using namespace Functor::MultiScaleConvexOrConcaveDecisionRule_tags;
// Template keyword mandatory to avoid parsing error when using
// template methods within template code
m_ClassificationFilter->template SetVariadicNamedInput<max_opening_profile_derivative>(m_OpeningCharacteristicsFilter->GetOutput());
m_ClassificationFilter->template SetVariadicNamedInput<opening_profile_characteristics>(m_OpeningCharacteristicsFilter->GetOutputCharacteristics());
m_ClassificationFilter->template SetVariadicNamedInput<max_closing_profile_derivative>(m_ClosingCharacteristicsFilter->GetOutput());
m_ClassificationFilter->template SetVariadicNamedInput<closing_profile_characteristics>(m_ClosingCharacteristicsFilter->GetOutputCharacteristics());
m_ConnectedComponentsFilter->SetInput(m_ClassificationFilter->GetOutput());
......@@ -85,8 +88,8 @@ MorphologicalProfilesSegmentationFilter<TInputImage,TOutputImage,TInternalPrecis
m_ClosingCharacteristicsFilter->SetInitialValue(m_ProfileStart);
m_ClosingCharacteristicsFilter->SetStep(m_ProfileStep);
m_ClassificationFilter->SetSigma(m_Sigma);
m_ClassificationFilter->SetLabelSeparator(m_ProfileStart + m_ProfileSize * m_ProfileStep);
m_ClassificationFilter->GetModifiableFunctor().SetSigma(m_Sigma);
m_ClassificationFilter->GetModifiableFunctor().SetLabelSeparator(m_ProfileStart + m_ProfileSize * m_ProfileStep);
m_ConnectedComponentsFilter->GraftOutput(this->GetOutput());
m_ConnectedComponentsFilter->Update();
......
......@@ -21,14 +21,26 @@
#ifndef otbMultiScaleConvexOrConcaveClassificationFilter_h
#define otbMultiScaleConvexOrConcaveClassificationFilter_h
#include "otbQuaternaryFunctorImageFilter.h"
#include "otbFunctorImageFilter.h"
namespace otb
{
namespace Functor
{
namespace MultiScaleConvexOrConcaveDecisionRule_tags
{
struct max_opening_profile_derivative {};
struct max_closing_profile_derivative {};
struct opening_profile_characteristics {};
struct closing_profile_characteristics {};
} // End namespace MultiScaleConvexOrConcaveDecisionRule_tags
/** \class MultiScaleConvexOrConcaveDecisionRule
* \brief This Functor apply a classification rule on two membership value along with two labels.
*
* Use otb::MultiScaleConvexOrConcaveClassificationFilter to apply it image-wise.
*
* \par
* This algorithm is based on the following publication:
* \par
......@@ -82,10 +94,10 @@ public:
* \param opDeChar The characteristic of the opening profile
* \param cloDeChar The characteristic of the closing profile
*/
inline TLabeled operator ()(const TInput& opDeMax,
const TInput& cloDeMax,
const TLabeled& opDeChar,
const TLabeled& cloDeChar)
TLabeled operator ()(const TInput& opDeMax,
const TInput& cloDeMax,
const TLabeled& opDeChar,
const TLabeled& cloDeChar) const
{
TLabeled resp = 0;
......@@ -141,118 +153,29 @@ private:
};
} //end namespace Functor
/** \class MultiScaleConvexOrConcaveClassificationFilter
* \brief Apply the MultiScaleConvexOrConcaveDecisionRule to whole images.
/** \typedef MultiScaleConvexOrConcaveClassificationFilter
* \brief Apply the otb::Functor::MultiScaleConvexOrConcaveDecisionRule to whole images.
*
* See MultiScaleConvexOrConcaveDecisionRule functor documentation for more details.
* See otb::Functor::MultiScaleConvexOrConcaveDecisionRule functor documentation for more details.
*
* Set inputs with:
* \code
*
* SetVariadicNamedInput<MultiScaleConvexOrConcaveDecisionRule_tags::max_opening_profile_derivative>(in1);
* SetVariadicNamedInput<MultiScaleConvexOrConcaveDecisionRule_tags::max_closing_profile_derivative>(in2);
* SetVariadicNamedInput<MultiScaleConvexOrConcaveDecisionRule_tags::opening_profile_characteristics>(in3);
* SetVariadicNamedInput<MultiScaleConvexOrConcaveDecisionRule_tags::closing_profile_characteristics>(in4);
*
* \endcode
*
* \ingroup OTBMorphologicalProfiles
*/
template <class TInputImage, class TOutputImage>
class ITK_EXPORT MultiScaleConvexOrConcaveClassificationFilter
: public QuaternaryFunctorImageFilter<TInputImage, TInputImage, TOutputImage, TOutputImage, TOutputImage,
Functor::MultiScaleConvexOrConcaveDecisionRule<typename TInputImage::PixelType,
typename TOutputImage::PixelType> >
{
public:
/** Standard typedefs */
typedef MultiScaleConvexOrConcaveClassificationFilter Self;
typedef QuaternaryFunctorImageFilter<TInputImage, TInputImage, TOutputImage, TOutputImage, TOutputImage,
Functor::MultiScaleConvexOrConcaveDecisionRule<typename TInputImage::PixelType,
typename TOutputImage::PixelType> >
Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Type macro */
itkNewMacro(Self);
/** Creation through object factory macro */
itkTypeMacro(MultiScaleConvexOrConcaveClassificationFilter, QuaternaryFunctorImageFilter);
/** Template class typedef */
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
typedef typename OutputImageType::PixelType LabelType;
typedef Functor::MultiScaleConvexOrConcaveDecisionRule<typename TInputImage::PixelType,
typename TOutputImage::PixelType> DecisionFunctorType;
/**
* Set the opening profile derivative maxima image
* \param derivativeMaxima the opening profile derivative maxima image
*
*/
void SetOpeningProfileDerivativeMaxima(const TInputImage * derivativeMaxima)
{
this->SetInput1(derivativeMaxima);
}
/**
* Set the opening profile characteristics image
* \param characteristics the opening profile characteristics image
*
*/
void SetOpeningProfileCharacteristics(const TOutputImage * characteristics)
{
this->SetInput3(characteristics);
}
/**
* Set the closing profile derivative maxima image
* \param derivativeMaxima the closing profile derivative maxima image
*
*/
void SetClosingProfileDerivativeMaxima(const TInputImage * derivativeMaxima)
{
this->SetInput2(derivativeMaxima);
}
/**
* Set the closing profile characteristics image
* \param characteristics the closing profile characteristics image
*
*/
void SetClosingProfileCharacteristics(const TOutputImage * characteristics)
{
this->SetInput4(characteristics);
}
/** Set/Get the tolerance value */
itkSetMacro(Sigma, double);
itkGetMacro(Sigma, double);
/** Set/Get the label separator */
itkSetMacro(LabelSeparator, LabelType);
itkGetMacro(LabelSeparator, LabelType);
/** Set the functor parameters before calling the ThreadedGenerateData() */
void BeforeThreadedGenerateData(void) override
{
this->GetFunctor().SetLabelSeparator(m_LabelSeparator);
this->GetFunctor().SetSigma(m_Sigma);
}
protected:
/** Constructor */
MultiScaleConvexOrConcaveClassificationFilter()
{
m_LabelSeparator = 10;
m_Sigma = 0.0;
};
/** Destructor */
~MultiScaleConvexOrConcaveClassificationFilter() override {}
/**PrintSelf method */
void PrintSelf(std::ostream& os, itk::Indent indent) const override
{
Superclass::PrintSelf(os, indent);
os << indent << "LabelSeparator: " << m_LabelSeparator << std::endl;
os << indent << "Sigma: " << m_Sigma << std::endl;
}
private:
MultiScaleConvexOrConcaveClassificationFilter(const Self &) = delete;
void operator =(const Self&) = delete;
/** Label separator between convex and concave labels */
LabelType m_LabelSeparator;
/** Tolerance value */
double m_Sigma;
};
using MultiScaleConvexOrConcaveClassificationFilter
= FunctorImageFilter<Functor::MultiScaleConvexOrConcaveDecisionRule<typename TInputImage::PixelType, typename TOutputImage::PixelType>,
std::tuple<Functor::MultiScaleConvexOrConcaveDecisionRule_tags::max_opening_profile_derivative,
Functor::MultiScaleConvexOrConcaveDecisionRule_tags::max_closing_profile_derivative,
Functor::MultiScaleConvexOrConcaveDecisionRule_tags::opening_profile_characteristics,
Functor::MultiScaleConvexOrConcaveDecisionRule_tags::closing_profile_characteristics> >;
} // End namespace otb
#endif
......@@ -22,7 +22,6 @@
#define otbOpeningClosingMorphologicalFilter_hxx
#include "otbOpeningClosingMorphologicalFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkGrayscaleMorphologicalOpeningImageFilter.h"
#include "itkGrayscaleMorphologicalClosingImageFilter.h"
#include "itkProgressAccumulator.h"
......
......@@ -22,7 +22,6 @@
#define otbProfileToProfileDerivativeFilter_h
#include "otbImageListToImageListFilter.h"
#include "itkUnaryFunctorImageFilter.h"
#include "itkSubtractImageFilter.h"
#include "itkAbsImageFilter.h"
......
......@@ -27,6 +27,7 @@ otb_module(OTBMorphologicalProfiles
OTBITK
OTBImageBase
OTBObjectList
OTBFunctor
TEST_DEPENDS
OTBImageIO
......
......@@ -46,9 +46,10 @@ int otbGeodesicMorphologyLevelingFilter(int itkNotUsed(argc), char * argv[])
FilterType::Pointer filter = FilterType::New();
filter->SetInput(reader->GetOutput());
filter->SetInputConvexMap(convreader->GetOutput());
filter->SetInputConcaveMap(concreader->GetOutput());
using namespace otb::Functor::LevelingFunctor_tags;
filter->SetVariadicNamedInput<pixel>(reader->GetOutput());
filter->SetVariadicNamedInput<convex_pixel>(convreader->GetOutput());
filter->SetVariadicNamedInput<concave_pixel>(concreader->GetOutput());
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(outfname);
......
......@@ -96,12 +96,13 @@ int otbMultiScaleConvexOrConcaveClassificationFilter(int itkNotUsed(argc), char
cmsCharFilter->SetStep(step);
MultiScaleClassificationFilterType::Pointer classificationFilter = MultiScaleClassificationFilterType::New();
classificationFilter->SetOpeningProfileDerivativeMaxima(omsCharFilter->GetOutput());
classificationFilter->SetOpeningProfileCharacteristics(omsCharFilter->GetOutputCharacteristics());
classificationFilter->SetClosingProfileDerivativeMaxima(cmsCharFilter->GetOutput());
classificationFilter->SetClosingProfileCharacteristics(cmsCharFilter->GetOutputCharacteristics());
classificationFilter->SetSigma(sigma);
classificationFilter->SetLabelSeparator(initialValue + profileSize * step);
using namespace otb::Functor::MultiScaleConvexOrConcaveDecisionRule_tags;
classificationFilter->SetVariadicNamedInput<max_opening_profile_derivative>(omsCharFilter->GetOutput());
classificationFilter->SetVariadicNamedInput<opening_profile_characteristics>(omsCharFilter->GetOutputCharacteristics());
classificationFilter->SetVariadicNamedInput<max_closing_profile_derivative>(cmsCharFilter->GetOutput());
classificationFilter->SetVariadicNamedInput<closing_profile_characteristics>(cmsCharFilter->GetOutputCharacteristics());
classificationFilter->GetModifiableFunctor().SetSigma(sigma);
classificationFilter->GetModifiableFunctor().SetLabelSeparator(initialValue + profileSize * step);
LabeledWriterType::Pointer labeledWriter = LabeledWriterType::New();
......
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