Skip to content
Snippets Groups Projects
Commit 4b598231 authored by Julien Michel's avatar Julien Michel
Browse files

REFAC: Refactoring RadiometricLabelMapFilter to use functor pattern implementation

parent f2dde803
Branches
Tags
No related merge requests found
......@@ -18,9 +18,7 @@
#ifndef __otbRadiometricAttributesLabelMapFilter_h
#define __otbRadiometricAttributesLabelMapFilter_h
#include "itkInPlaceLabelMapFilter.h"
#include "itkMatrix.h"
#include "itkVector.h"
#include "otbStatisticsAttributesLabelMapFilter.h"
#include "otbVegetationIndicesFunctor.h"
#include "otbSoilIndicesFunctor.h"
......@@ -30,10 +28,98 @@
#include "otbMultiChannelRAndGAndNIRVegetationIndexImageFilter.h"
#include "otbVectorImageToIntensityImageFilter.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbStatisticsAttributesLabelMapFilter.h"
namespace otb
{
namespace Functor
{
/** \class MulitStatsAttributesLabelObjectFunctor
* \brief Functor to compute multiple statistics attributes.
*
* For one label object, this functors applies the
* StatisticsAttributesLabelObjectFunctor
* for a set of feature images along with their feature names.
*
* As such, it allows to compute in one pass statistics related to
* mulitple features. It is used in the
* RadiometricAttributesLabelMapFilter.
*
* Features can be added, removed or cleared via the appropriate
* methods.
*
* \sa RadiometricAttributesLabelMapFilter
* \sa StatisticsAttributesLabelObjectFunctor
*/
template <class TLabelObject, class TFeatureImage>
class MultiStatsAttributesLabelObjectFunctor
{
public:
// Self typedef
typedef MultiStatsAttributesLabelObjectFunctor Self;
/// Typedef of the feature image type
typedef typename TFeatureImage::PixelType FeatureType;
/// Typedef of the label object
typedef TLabelObject LabelObjectType;
/// Feature image const pointer
typedef typename TFeatureImage::ConstPointer FeatureImageConstPointer;
/// Statistics functor
typedef StatisticsAttributesLabelObjectFunctor
<TLabelObject,TFeatureImage> StatsFunctorType;
/// Map to store the functors
typedef std::map<std::string,StatsFunctorType> StatsFunctorsMapType;
/** Constructor */
MultiStatsAttributesLabelObjectFunctor();
/** Destructor */
virtual ~MultiStatsAttributesLabelObjectFunctor();
/** The comparators */
bool operator!=(const Self& self);
bool operator==(const Self& self);
/** This is the functor implementation
* Calling the functor on a label object
* will update its statistics attributes */
inline void operator()(LabelObjectType * lo) const;
/** Add a feature with the given name */
void AddFeature(const std::string & name, const TFeatureImage * img);
/** Remove the feature with this name if it exists */
bool RemoveFeature(const std::string & name);
/** Get the feature image with this name */
const TFeatureImage * GetFeature(const std::string & name) const;
/** Clear all the features */
void ClearAllFeatures();
/** Get the number of features */
unsigned int GetNumberOfFeatures() const;
/** Set the reduced attribute set */
void SetReducedAttributeSet(bool flag);
/** Get the reduced attribute set */
bool GetReducedAttributeSet() const;
private:
/// True to compute only a reduced attribute set
bool m_ReducedAttributeSet;
/// The Stat functors map
StatsFunctorsMapType m_StatsFunctorsMap;
};
} // End namespace Functor
/** \class RadiometricAttributesLabelMapFilter
* \brief This filter computes radiometric attributes for each object.
*
......@@ -52,20 +138,36 @@ namespace otb
* The ReducedAttributesSet flag allows to tell the internal
* statistics filter to compute only the main attributes.
*
* \sa StatisticsAttributesImageFilter AttributesMapLabelObject
* \sa MultiStatsAttributesLabelObjectFunctor AttributesMapLabelObject
* \sa GEMI NDVI IR IC IB NDWI2
* \sa VectorIntensityImageFilter
*
* \ingroup ImageEnhancement MathematicalMorphologyImageFilters
*/
template<class TImage, class TFeatureImage>
class ITK_EXPORT RadiometricAttributesLabelMapFilter :
public itk::InPlaceLabelMapFilter<TImage>
class ITK_EXPORT RadiometricAttributesLabelMapFilter
: public LabelMapFeaturesFunctorImageFilter
< TImage,
typename Functor::MultiStatsAttributesLabelObjectFunctor
< typename TImage::LabelObjectType, otb::Image<double,2> > >
{
public:
/** Some convenient typedefs. */
typedef TImage ImageType;
typedef typename ImageType::LabelObjectType LabelObjectType;
typedef TFeatureImage FeatureImageType;
typedef typename FeatureImageType::InternalPixelType FeatureInternalPixelType;
typedef double InternalPrecisionType;
typedef Image<InternalPrecisionType,2> InternalImageType;
/** Functor typedef */
typedef Functor::MultiStatsAttributesLabelObjectFunctor
<LabelObjectType,InternalImageType> FunctorType;
/** Standard class typedefs. */
typedef RadiometricAttributesLabelMapFilter Self;
typedef itk::InPlaceLabelMapFilter<TImage> Superclass;
typedef LabelMapFeaturesFunctorImageFilter
<ImageType,FunctorType> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
......@@ -76,28 +178,7 @@ public:
itkNewMacro(Self);
/** Runtime information support. */
itkTypeMacro(RadiometricAttributesLabelMapFilter,InPlaceLabelMapFilter);
/** Some convenient typedefs. */
typedef TImage ImageType;
typedef typename ImageType::Pointer ImagePointer;
typedef typename ImageType::ConstPointer ImageConstPointer;
typedef typename ImageType::PixelType PixelType;
typedef typename ImageType::IndexType IndexType;
typedef typename ImageType::PointType PointType;
typedef typename ImageType::LabelObjectType LabelObjectType;
typedef TFeatureImage FeatureImageType;
typedef typename FeatureImageType::Pointer FeatureImagePointer;
typedef typename FeatureImageType::ConstPointer FeatureImageConstPointer;
typedef typename FeatureImageType::PixelType FeatureImagePixelType;
typedef typename FeatureImageType::InternalPixelType FeatureInternalPixelType;
typedef double InternalPrecisionType;
typedef Image<InternalPrecisionType,2> InternalImageType;
/// Internal statistics filter typedef
typedef StatisticsAttributesLabelMapFilter
<ImageType,InternalImageType> StatisticsLabelMapFilterType;
typedef typename StatisticsLabelMapFilterType::Pointer StatisticsLabelMapFilterPointerType;
itkTypeMacro(RadiometricAttributesLabelMapFilter,LabelMapFeaturesFunctorImageFilter);
/// Fuctors typedef
......@@ -154,30 +235,11 @@ public:
typedef typename ChannelFilterType::Pointer ChannelFilterPointerType;
/** Set the feature image */
void SetFeatureImage(TFeatureImage *input)
{
// Process object is not const-correct so the const casting is required.
this->SetNthInput( 1, const_cast<TFeatureImage *>(input) );
}
/** Set the feature image */
void SetFeatureImage(const TFeatureImage *input);
/** Get the feature image */
FeatureImageType * GetFeatureImage()
{
return static_cast<FeatureImageType*>(const_cast<itk::DataObject *>(this->itk::ProcessObject::GetInput(1)));
}
/** Set the input image */
void SetInput1(TImage *input)
{
this->SetInput( input );
}
/** Set the feature image */
void SetInput2(TFeatureImage *input)
{
this->SetFeatureImage( input );
}
const FeatureImageType * GetFeatureImage() const;
/** Set/Get the red channel index */
itkSetMacro(RedChannelIndex,unsigned int);
......@@ -195,9 +257,12 @@ public:
itkSetMacro(NIRChannelIndex,unsigned int);
itkGetMacro(NIRChannelIndex,unsigned int);
/** Set/get the ReducedAttributesSet flag */
itkSetMacro(ReducedAttributeSet,bool);
itkGetMacro(ReducedAttributeSet,bool);
/** Set the reduced attribute set */
void SetReducedAttributeSet(bool flag);
/** Get the reduced attribute set */
bool GetReducedAttributeSet() const;
itkBooleanMacro(ReducedAttributeSet);
protected:
......@@ -206,8 +271,8 @@ protected:
/** Destructor */
~RadiometricAttributesLabelMapFilter() {};
/** GenerateData method */
virtual void GenerateData();
/** Before threaded data generation */
virtual void BeforeThreadedGenerateData();
/** PrintSelf method */
void PrintSelf(std::ostream& os, itk::Indent indent) const;
......@@ -227,10 +292,6 @@ private:
/** The near infra-red channel index */
unsigned int m_NIRChannelIndex;
/// Use only a reduced attribute set
bool m_ReducedAttributeSet;
} ; // end of class
} // end namespace itk
......
......@@ -23,137 +23,290 @@
namespace otb
{
namespace Functor
{
/** Constructor */
template <class TLabelObject, class TFeatureImage>
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::MultiStatsAttributesLabelObjectFunctor() : m_ReducedAttributeSet(true),
m_StatsFunctorsMap()
{}
/** Destructor */
template <class TLabelObject, class TFeatureImage>
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::~MultiStatsAttributesLabelObjectFunctor(){}
/** The comparators */
template <class TLabelObject, class TFeatureImage>
bool
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::operator!=(const Self& self)
{
bool resp = true;
resp = resp && (m_ReducedAttributeSet != self.m_ReducedAttributeSet);
resp = resp && (m_StatsFunctorsMap != self.m_StatsFunctorsMap);
return resp;
}
template <class TLabelObject, class TFeatureImage>
bool
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::operator==(const Self& self)
{
return !(this != self);
}
/** This is the functor implementation
* Calling the functor on a label object
* will update its statistics attributes */
template <class TLabelObject, class TFeatureImage>
void
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
:: operator()(LabelObjectType * lo) const
{
// Walk every registered functors
for(typename StatsFunctorsMapType::const_iterator it = m_StatsFunctorsMap.begin();
it!=m_StatsFunctorsMap.end(); ++it)
{
(it->second)(lo);
}
}
/** Add a feature with the given name */
template <class TLabelObject, class TFeatureImage>
void
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::AddFeature(const std::string & name, const TFeatureImage * img)
{
// Create a new functor
StatsFunctorType newFunctor;
// Set the reduced attribute set option
newFunctor.SetReducedAttributeSet(m_ReducedAttributeSet);
// Set the feature and its name
newFunctor.SetFeatureName(name);
// Set the feature image
newFunctor.SetFeatureImage(img);
// Add it to the map
m_StatsFunctorsMap[name]=newFunctor;
}
/** Remove the feature with this name if it exists */
template <class TLabelObject, class TFeatureImage>
bool
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::RemoveFeature(const std::string & name)
{
return (m_StatsFunctorsMap.erase(name) == 1);
}
/** Get the feature image with this name */
template <class TLabelObject, class TFeatureImage>
const TFeatureImage *
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::GetFeature(const std::string & name) const
{
if(m_StatsFunctorsMap.count(name) == 0)
{
itkGenericExceptionMacro(<<"No feature named "<<name<<" in map.");
}
return m_StatsFunctorsMap[name].GetFeatureImage();
}
/** Clear all the features */
template <class TLabelObject, class TFeatureImage>
void
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::ClearAllFeatures()
{
m_StatsFunctorsMap.clear();
}
/** Get the number of features */
template <class TLabelObject, class TFeatureImage>
unsigned int
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::GetNumberOfFeatures() const
{
return m_StatsFunctorsMap.size();
}
/** Set the reduced attribute set */
template <class TLabelObject, class TFeatureImage>
void
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::SetReducedAttributeSet(bool flag)
{
// Set the flag
m_ReducedAttributeSet = flag;
// Set the flag to all the already existing functors
for(typename StatsFunctorsMapType::iterator it = m_StatsFunctorsMap.begin();
it!=m_StatsFunctorsMap.end(); ++it)
{
it->second.SetReducedAttributeSet(m_ReducedAttributeSet);
}
}
/** Get the reduced attribute set */
template <class TLabelObject, class TFeatureImage>
bool
MultiStatsAttributesLabelObjectFunctor<TLabelObject,TFeatureImage>
::GetReducedAttributeSet() const
{
return m_ReducedAttributeSet;
}
} // End namespace Functor
template <class TImage, class TFeatureImage>
RadiometricAttributesLabelMapFilter<TImage, TFeatureImage>
::RadiometricAttributesLabelMapFilter() : m_RedChannelIndex(2), m_GreenChannelIndex(1), m_BlueChannelIndex(0), m_NIRChannelIndex(3), m_ReducedAttributeSet(true)
::RadiometricAttributesLabelMapFilter() : m_RedChannelIndex(2),
m_GreenChannelIndex(1),
m_BlueChannelIndex(0),
m_NIRChannelIndex(3)
{
this->SetNumberOfRequiredInputs(2);
}
/** Set the feature image */
template <class TImage, class TFeatureImage>
void
RadiometricAttributesLabelMapFilter<TImage, TFeatureImage>
::SetFeatureImage(const TFeatureImage *input)
{
// Set the Nth input
this->SetNthInput(1,const_cast<TFeatureImage*>(input));
}
/** Get the feature image */
template <class TImage, class TFeatureImage>
const typename RadiometricAttributesLabelMapFilter<TImage, TFeatureImage>
::FeatureImageType *
RadiometricAttributesLabelMapFilter<TImage, TFeatureImage>
::GetFeatureImage() const
{
return static_cast<const TFeatureImage *>(this->itk::ProcessObject::GetInput(1));
}
/** Set the reduced attribute set */
template <class TImage, class TFeatureImage>
void
RadiometricAttributesLabelMapFilter<TImage, TFeatureImage>
::SetReducedAttributeSet(bool flag)
{
if(this->GetFunctor().GetReducedAttributeSet() != flag)
{
this->GetFunctor().SetReducedAttributeSet(flag);
this->Modified();
}
}
/** Get the reduced attribute set */
template <class TImage, class TFeatureImage>
bool
RadiometricAttributesLabelMapFilter<TImage, TFeatureImage>
::GetReducedAttributeSet() const
{
return this->GetFunctor().GetReducedAttributeSet();
}
template <class TImage, class TFeatureImage>
void
RadiometricAttributesLabelMapFilter<TImage, TFeatureImage>
::GenerateData()
::BeforeThreadedGenerateData()
{
// Clear any previous feature
this->GetFunctor().ClearAllFeatures();
// Gemi
GEMIFilterPointerType gemi = GEMIFilterType::New();
gemi->SetRedIndex(m_RedChannelIndex+1);
gemi->SetNIRIndex(m_NIRChannelIndex+1);
gemi->SetInput(this->GetFeatureImage());
gemi->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
gemi->Update();
this->GetFunctor().AddFeature("Gemi",gemi->GetOutput());
StatisticsLabelMapFilterPointerType stats1 = StatisticsLabelMapFilterType::New();
stats1->SetInput(this->GetInput());
stats1->SetFeatureImage(gemi->GetOutput());
stats1->SetFeatureName("Gemi");
stats1->SetReducedAttributeSet(m_ReducedAttributeSet);
// Ndvi
NDVIFilterPointerType ndvi = NDVIFilterType::New();
ndvi->SetRedIndex(m_RedChannelIndex+1);
ndvi->SetNIRIndex(m_NIRChannelIndex+1);
ndvi->SetInput(this->GetFeatureImage());
StatisticsLabelMapFilterPointerType stats2 = StatisticsLabelMapFilterType::New();
stats2->SetInput(stats1->GetOutput());
stats2->SetFeatureImage(ndvi->GetOutput());
stats2->SetFeatureName("Ndvi");
stats2->SetReducedAttributeSet(m_ReducedAttributeSet);
ndvi->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
ndvi->Update();
this->GetFunctor().AddFeature("Ndvi",ndvi->GetOutput());
// IR
IRFilterPointerType ir = IRFilterType::New();
ir->SetGreenIndex(m_GreenChannelIndex+1);
ir->SetRedIndex(m_RedChannelIndex+1);
ir->SetInput(this->GetFeatureImage());
StatisticsLabelMapFilterPointerType stats3 = StatisticsLabelMapFilterType::New();
stats3->SetInput(stats2->GetOutput());
stats3->SetFeatureImage(ir->GetOutput());
stats3->SetFeatureName("Redness");
stats3->SetReducedAttributeSet(m_ReducedAttributeSet);
ir->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
ir->Update();
this->GetFunctor().AddFeature("Redness",ir->GetOutput());
// IC
ICFilterPointerType ic = ICFilterType::New();
ic->SetGreenIndex(m_GreenChannelIndex+1);
ic->SetRedIndex(m_RedChannelIndex+1);
ic->SetInput(this->GetFeatureImage());
ic->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
ic->Update();
this->GetFunctor().AddFeature("Color",ic->GetOutput());
StatisticsLabelMapFilterPointerType stats4 = StatisticsLabelMapFilterType::New();
stats4->SetInput(stats3->GetOutput());
stats4->SetFeatureImage(ic->GetOutput());
stats4->SetFeatureName("Color");
stats4->SetReducedAttributeSet(m_ReducedAttributeSet);
// IB
IBFilterPointerType ib = IBFilterType::New();
ib->SetGreenIndex(m_GreenChannelIndex+1);
ib->SetRedIndex(m_RedChannelIndex+1);
ib->SetInput(this->GetFeatureImage());
ib->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
ib->Update();
this->GetFunctor().AddFeature("Brightness",ib->GetOutput());
StatisticsLabelMapFilterPointerType stats5 = StatisticsLabelMapFilterType::New();
stats5->SetInput(stats4->GetOutput());
stats5->SetFeatureImage(ib->GetOutput());
stats5->SetFeatureName("Brightness");
stats5->SetReducedAttributeSet(m_ReducedAttributeSet);
// NDWI2
NDWI2FilterPointerType ndwi2 = NDWI2FilterType::New();
ndwi2->GetFunctor().SetGIndex(m_GreenChannelIndex+1);
ndwi2->GetFunctor().SetNIRIndex(m_NIRChannelIndex+1);
ndwi2->SetInput(this->GetFeatureImage());
ndwi2->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
ndwi2->Update();
this->GetFunctor().AddFeature("Ndwi2",ndwi2->GetOutput());
StatisticsLabelMapFilterPointerType stats6 = StatisticsLabelMapFilterType::New();
stats6->SetInput(stats5->GetOutput());
stats6->SetFeatureImage(ndwi2->GetOutput());
stats6->SetFeatureName("Ndwi2");
stats6->SetReducedAttributeSet(m_ReducedAttributeSet);
IntensityFilterPointerType intensity = IntensityFilterType::New();
intensity->SetInput(this->GetFeatureImage());
StatisticsLabelMapFilterPointerType stats7 = StatisticsLabelMapFilterType::New();
stats7->SetInput(stats6->GetOutput());
stats7->SetFeatureImage(intensity->GetOutput());
stats7->SetFeatureName("Intensity");
stats7->SetReducedAttributeSet(m_ReducedAttributeSet);
// Red
ChannelFilterPointerType red = ChannelFilterType::New();
red->SetChannel(m_RedChannelIndex+1);
red->SetInput(this->GetFeatureImage());
red->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
red->Update();
this->GetFunctor().AddFeature("Red",red->GetOutput());
StatisticsLabelMapFilterPointerType stats8 = StatisticsLabelMapFilterType::New();
stats8->SetInput(stats7->GetOutput());
stats8->SetFeatureImage(red->GetOutput());
stats8->SetFeatureName("Red");
stats8->SetReducedAttributeSet(m_ReducedAttributeSet);
// Green
ChannelFilterPointerType green = ChannelFilterType::New();
green->SetChannel(m_GreenChannelIndex+1);
green->SetInput(this->GetFeatureImage());
green->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
green->Update();
this->GetFunctor().AddFeature("Green",green->GetOutput());
StatisticsLabelMapFilterPointerType stats9 = StatisticsLabelMapFilterType::New();
stats9->SetInput(stats8->GetOutput());
stats9->SetFeatureImage(green->GetOutput());
stats9->SetFeatureName("Green");
stats9->SetReducedAttributeSet(m_ReducedAttributeSet);
// Blue
ChannelFilterPointerType blue = ChannelFilterType::New();
blue->SetChannel(m_BlueChannelIndex+1);
blue->SetInput(this->GetFeatureImage());
StatisticsLabelMapFilterPointerType stats10 = StatisticsLabelMapFilterType::New();
stats10->SetInput(stats9->GetOutput());
stats10->SetFeatureImage(blue->GetOutput());
stats10->SetFeatureName("Blue");
stats10->SetReducedAttributeSet(m_ReducedAttributeSet);
blue->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
blue->Update();
this->GetFunctor().AddFeature("Blue",blue->GetOutput());
// Nir
ChannelFilterPointerType nir = ChannelFilterType::New();
nir->SetChannel(m_NIRChannelIndex+1);
nir->SetInput(this->GetFeatureImage());
StatisticsLabelMapFilterPointerType stats11 = StatisticsLabelMapFilterType::New();
stats11->SetInput(stats10->GetOutput());
stats11->SetFeatureImage(nir->GetOutput());
stats11->SetFeatureName("Nir");
stats11->SetReducedAttributeSet(m_ReducedAttributeSet);
stats11->GraftOutput(this->GetOutput());
stats11->Update();
this->GraftOutput(stats11->GetOutput());
nir->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
nir->Update();
this->GetFunctor().AddFeature("NIR",nir->GetOutput());
}
template <class TImage, class TFeatureImage>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment