From fb230dee46a60d3c12c510f53dc467c0469a87d5 Mon Sep 17 00:00:00 2001 From: Julien Michel <julien.michel@c-s.fr> Date: Mon, 28 Apr 2008 16:13:24 +0000 Subject: [PATCH] =?UTF-8?q?Corrections=20SOM=20gr=C3=A9goire?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otbEuclideanDistanceWithMissingValue.h | 100 +++++++ .../otbEuclideanDistanceWithMissingValue.txx | 149 +++++++++ .../otbCzihoSOMLearningBehaviorFunctor.h | 110 +++++++ .../otbCzihoSOMNeighborhoodBehaviorFunctor.h | 82 +++++ Code/Learning/otbPeriodicSOM.h | 130 ++++++++ Code/Learning/otbPeriodicSOM.txx | 109 +++++++ Code/Learning/otbSOM.h | 40 ++- Code/Learning/otbSOM.txx | 282 +++++++++++------- Code/Learning/otbSOMLearningBehaviorFunctor.h | 67 +++++ Code/Learning/otbSOMMap.h | 23 +- Code/Learning/otbSOMMap.txx | 4 + Testing/Code/BasicFilters/CMakeLists.txt | 12 + .../BasicFilters/otbBasicFiltersTests8.cxx | 2 + .../otbEuclideanDistanceWithMissingValue.cxx | 61 ++++ ...tbEuclideanDistanceWithMissingValueNew.cxx | 39 +++ Testing/Code/Learning/CMakeLists.txt | 16 + Testing/Code/Learning/otbLearningTests2.cxx | 2 + Testing/Code/Learning/otbPeriodicSOM.cxx | 109 +++++++ Testing/Code/Learning/otbPeriodicSOMNew.cxx | 53 ++++ Testing/Code/Learning/otbSOM.cxx | 30 +- .../Code/Learning/otbSOMActivationBuilder.cxx | 30 +- .../Learning/otbSOMActivationBuilderNew.cxx | 15 +- Testing/Code/Learning/otbSOMClassifier.cxx | 24 +- Testing/Code/Learning/otbSOMClassifierNew.cxx | 9 +- Testing/Code/Learning/otbSOMMap.cxx | 11 +- Testing/Code/Learning/otbSOMNew.cxx | 9 +- 26 files changed, 1354 insertions(+), 164 deletions(-) create mode 100644 Code/BasicFilters/otbEuclideanDistanceWithMissingValue.h create mode 100644 Code/BasicFilters/otbEuclideanDistanceWithMissingValue.txx create mode 100644 Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h create mode 100644 Code/Learning/otbCzihoSOMNeighborhoodBehaviorFunctor.h create mode 100644 Code/Learning/otbPeriodicSOM.h create mode 100644 Code/Learning/otbPeriodicSOM.txx create mode 100644 Code/Learning/otbSOMLearningBehaviorFunctor.h create mode 100644 Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.cxx create mode 100644 Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValueNew.cxx create mode 100644 Testing/Code/Learning/otbPeriodicSOM.cxx create mode 100644 Testing/Code/Learning/otbPeriodicSOMNew.cxx diff --git a/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.h b/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.h new file mode 100644 index 0000000000..e4f07d5c65 --- /dev/null +++ b/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.h @@ -0,0 +1,100 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Copyright (c) Institut Telecom / Telecom Bretagne. All rights reserved. + See ITCopyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef __otbEuclideanDistanceWithMissingValue_h +#define __otbEuclideanDistanceWithMissingValue_h + +#include <itkEuclideanDistance.h> + +namespace otb { + +namespace Statistics { + +/** \class EuclideanDistanceWithMissingValue + * \brief Euclidean distance function facing missing value. + * + * This class is derived from EuclideanDistance class. In addition + * to the initial Evaluate method, the class does not perform calculation + * when a component does not contain any data. + * + * The class can be templated over any container that holds data elements, as + * for template of EuclideanDistance. + * + * The only restriction is that elemnts have to support '\code{NaN}'. + * + * \sa EuclideanDistance + */ +template< class TVector > +class ITK_EXPORT EuclideanDistanceWithMissingValue : + public itk::Statistics::EuclideanDistance< TVector > +{ + public: + /** Standard "Self" typedef. */ + typedef EuclideanDistanceWithMissingValue Self; + typedef itk::Statistics::EuclideanDistance< TVector > Superclass; + typedef itk::SmartPointer< Self > Pointer ; + typedef itk::SmartPointer<const Self> ConstPointer; + typedef typename Superclass::MeasurementVectorSizeType MeasurementVectorSizeType; + + /** Run-time type information (and related methods). */ + itkTypeMacro(EuclideanDistanceWithMissingValue, EuclideanDistance); + + /** Method for creation through the object factory. */ + itkNewMacro(Self) ; + + /** Type of the component of a vector */ + typedef typename TVector::ValueType ValueType ; + + /** Gets the distance between the origin and x */ + double Evaluate(const TVector &x) const ; + + /** Gets the distance between x1 and x2 */ + double Evaluate(const TVector &x1, const TVector &x2) const ; + + /** Gets the cooridnate distance between a and b. NOTE: a and b + * should be type of component */ + double Evaluate(const ValueType &a, const ValueType &b) const ; + + /** Returns true if the distance between x and the origin is less + * than radius */ + bool IsWithinRange(const TVector &x, const double radius) const { + return Superclass::IsWithinRange( x, radius ); } + + /** Check if a value is NaN or not */ + static bool IsMissingValue ( const ValueType & v) ; + + /** Set a value to Nan */ + static void SetToMissingValue ( ValueType & v ); + + protected: + EuclideanDistanceWithMissingValue() {} + virtual ~EuclideanDistanceWithMissingValue() {} +} ; // end of class + +} // end namespace statistics + +} // end namespace otb + +#ifndef ITK_MANUAL_INSTANTIATION +#include "otbEuclideanDistanceWithMissingValue.txx" +#endif + +#endif + diff --git a/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.txx b/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.txx new file mode 100644 index 0000000000..70e7db1f57 --- /dev/null +++ b/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.txx @@ -0,0 +1,149 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Copyright (c) Institut Telecom / Telecom Bretagne. All rights reserved. + See ITCopyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef __otbEuclideanDistanceWithMissingValue_txx +#define __otbEuclideanDistanceWithMissingValue_txx + +#include "itkNumericTraits.h" + +namespace otb { + +namespace Statistics { + +template< class TVector > +inline double +EuclideanDistanceWithMissingValue< TVector > +::Evaluate(const TVector &x1, const TVector &x2) const +{ + if( itk::MeasurementVectorTraits::GetLength( x1 ) != + itk::MeasurementVectorTraits::GetLength( x2 ) ) + { + itkExceptionMacro( << "Vector lengths must be equal." ); + } + + double temp, distance = itk::NumericTraits< double >::Zero ; + + for(unsigned int i = 0 ; i < x1.Size(); i++ ) + { + if ( !IsMissingValue( x1[i] ) && !IsMissingValue( x2[i] ) ) + { + temp = x1[i] - x2[i] ; + distance += temp * temp ; + } + } + + return ::vcl_sqrt(distance) ; +} + +template< class TVector > +inline double +EuclideanDistanceWithMissingValue< TVector > +::Evaluate(const TVector &x) const +{ + MeasurementVectorSizeType + measurementVectorSize = this->GetMeasurementVectorSize(); + if(measurementVectorSize == 0) + { + itkExceptionMacro( << "Please set the MeasurementVectorSize first" ); + } + itk::MeasurementVectorTraits::Assert( this->m_Origin, measurementVectorSize, + "EuclideanDistance::Evaluate Origin and input vector have different lengths"); + + double temp, distance = itk::NumericTraits< double >::Zero ; + + for(unsigned int i = 0 ; i < measurementVectorSize ; i++ ) + { + if ( !IsMissingValue( this->GetOrigin()[i] ) && !IsMissingValue( x[i] ) ) + { + temp = this->GetOrigin()[i] - x[i] ; + distance += temp * temp ; + } + } + + return ::vcl_sqrt(distance) ; +} + +template< class TVector > +inline double +EuclideanDistanceWithMissingValue< TVector > +::Evaluate( const ValueType &a, const ValueType &b ) const +{ + // FIXME throw NaN exception ?? + if ( IsMissingValue( a ) || IsMissingValue( b ) ) + return 0.0; + + double temp = a - b ; + return ::vcl_sqrt(temp * temp) ; +} + +#if defined(_MSC_VER) /* Microsoft Visual C++ */ +#include <float.h> + +template< class TVector > +/*static */ +bool +EuclideanDistanceWithMissingValue< TVector > +::IsMissingValue ( const ValueType & v) +{ + return static_cast<bool>( _isnan( const_cast<double>( v ) ) ); +} + +#elif HAVE_IEEE_COMPARISONS + +template< class TVector > +/*static */ +bool +EuclideanDistanceWithMissingValue< TVector > +::IsMissingValue ( const ValueType & v) +{ + return (v!=v); +} + +#else + +template< class TVector > +/*static */ +bool +EuclideanDistanceWithMissingValue< TVector > +::IsMissingValue ( const ValueType & v) +{ + return static_cast<bool>( isnan(v) ); +} + +#endif + +template< class TVector > +/* static */ +void +EuclideanDistanceWithMissingValue< TVector > +::SetToMissingValue ( ValueType & v ) +{ + v = static_cast<ValueType>( 0.0/0.0 ); +} + + +} // end namespace statistics + +} // end namespace otb + +#endif + + + diff --git a/Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h b/Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h new file mode 100644 index 0000000000..44260ab818 --- /dev/null +++ b/Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h @@ -0,0 +1,110 @@ +/*========================================================================= + +Program: ORFEO Toolbox +Language: C++ +Date: $Date$ +Version: $Revision$ + + +Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. +See OTBCopyright.txt for details. + +Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. +See ITCopyright.txt for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef __otbCzihoSOMLearningBehaviorFunctor_h +#define __otbCzihoSOMLearningBehaviorFunctor_h + +#include "itkSize.h" + +namespace otb { + +namespace Functor { + + /** \class CzihoSOMLearningBehaviorFunctor + * \brief Beta behavior over SOM training phase + * + * This class implements an evolution of the \f$ \beta \f$ weightening + * coefficient over the SOM training. It is issued from A. Cziho's PhD: + * "Compression d'images et analyse de contenu par quantification vectorielle" + * PhD dissertation, University of Rennes I, Rennes, France. May 5th, 1999. + * + * Its behavior is decomposed into two steps depending on the number of iterations: + * \f{equation*} + \beta = \begn{cases} + \beta_0 \left( 1 - \frac{t}{t_0} \right) & \text{ if $t < t_0$} \\ + \beta_{\text{end}} \left( 1- \frac{t-t_O}{t_{\text{end}}-t_0} \right) + & \text{ if $ t_0 \leqslant t < t_{\text{end}}$} + \end{cases} + \f{equation*} + where \f$ t_0 \f$ stands for IterationThreshold. + * + * CzihoSOMLearningBehaviorFunctor uses some parameters of the SOM class such as: + * BetaInit, BetaEnd, NumberOfIterations, but also NeighborhoodSizeInit which may be + * (surprisingly) required for the IterationThreshold. + * + * The functor function uses \code{NumberOfIterations}, \code{BetaInit}, \code{BetaEnd} parameters, that is + * why it is necessary to call a specific method for \code{IterationThreshold} intialisation. + * + * \sa SOM + */ + class CzihoSOMLearningBehaviorFunctor + { + public : + /** Empty constructor / descructor */ + CzihoSOMLearningBehaviorFunctor () { m_IterationThreshold = 0; } + virtual ~CzihoSOMLearningBehaviorFunctor() { } + + /** Accessors */ + unsigned int GetIterationThreshold () { return this->m_IterationThreshold; } + + template < unsigned int VDimension > + void SetIterationThreshold ( const itk::Size<VDimension> & sizeInit, unsigned int iterMax ) + { + double V0 = static_cast<double>( sizeInit[0] ); + for ( int i = 1; i < VDimension; i++ ) + { + if ( V0 < static_cast<double>( sizeInit[i] ) ) + V0 = static_cast<double>( sizeInit[i] ); + } + + m_IterationThreshold = static_cast<unsigned int>( + static_cast<double>( iterMax ) * ( 1.0 - 1.0 / ::vcl_sqrt( V0 ) ) ); + } + + /** Functor */ + virtual double operator() ( unsigned int currentIteration, + unsigned int numberOfIterations, + double betaInit, double betaEnd ) + { + if ( currentIteration < m_IterationThreshold ) + { + return betaInit * ( 1.0 + - static_cast<double>( currentIteration ) + / static_cast<double>( numberOfIterations ) ); + } + else + { + return betaEnd * ( 1.0 + - static_cast<double>( currentIteration - m_IterationThreshold ) + / static_cast<double>( numberOfIterations - m_IterationThreshold ) ); + } + } + + private: + unsigned int m_IterationThreshold; + + }; // end of class CzihoSOMLearningBehaviorFunctor + +} // end namespace Functor + +} // end namespace otb + +#endif + diff --git a/Code/Learning/otbCzihoSOMNeighborhoodBehaviorFunctor.h b/Code/Learning/otbCzihoSOMNeighborhoodBehaviorFunctor.h new file mode 100644 index 0000000000..1d94c90ce9 --- /dev/null +++ b/Code/Learning/otbCzihoSOMNeighborhoodBehaviorFunctor.h @@ -0,0 +1,82 @@ +/*========================================================================= + +Program: ORFEO Toolbox +Language: C++ +Date: $Date$ +Version: $Revision$ + + +Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. +See OTBCopyright.txt for details. + +Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. +See ITCopyright.txt for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef __otbCzihoSOMNeighborhoodBehaviorFunctor_h +#define __otbCzihoSOMNeighborhoodBehaviorFunctor_h + + +namespace otb { + +namespace Functor { + + /** \class CzihoSOMNeighborhoodBehaviorFunctor + * \brief Neighborhood size behavior over SOM training phase + * + * This class implements an evolution of the neighborhood size + * over the SOM training. It is issued from A. Cziho's PhD: + * "Compression d'images et analyse de contenu par quantification vectorielle" + * PhD dissertation, University of Rennes I, Rennes, France. May 5th, 1999. + * + * The behavior of the radius r (\em ie. \code{SizeType} component 0, 1,...) is given by: + * \f{equation*} + r = r_{\text{init}} \left( 1 - \frac{t}{t_{\text{end}}} \right)^2 + \f{equation*} + * + * CzihoSOMNeighborhoodBehaviorFunctor uses some parameters of the SOM class such as: + * \code{NeighborhoodSizeInit}, \code{NumberOfIterations} which are parameters of the functor function. + * \code{operator()} is templated with the dimension of the neighborhoodSize. + * + * \sa SOM + */ + class CzihoSOMNeighborhoodBehaviorFunctor + { + public : + /** Empty constructor / descructor */ + CzihoSOMNeighborhoodBehaviorFunctor () { } + virtual ~CzihoSOMNeighborhoodBehaviorFunctor() { } + + /** Functor */ + template < unsigned int VDimension > + itk::Size<VDimension> operator() ( unsigned int currentIteration, + unsigned int numberOfIterations, + const itk::Size<VDimension> & sizeInit ) + { + itk::Size<VDimension> theSize; + double weightening = ::vcl_pow( 1.0 + - static_cast<double>( currentIteration ) + / static_cast<double>( numberOfIterations ), + 2.0 ); + for (unsigned int i = 0; i < VDimension; i++ ) + { + theSize[i] = static_cast<typename itk::Size<VDimension>::SizeValueType> ( + static_cast<double>( sizeInit[i] ) * weightening ); + } + + return theSize; + } + + }; // end of class CzihoSOMNeighborhoodBehaviorFunctor + +} // end namespace Functor + +} // end namespace otb + +#endif + diff --git a/Code/Learning/otbPeriodicSOM.h b/Code/Learning/otbPeriodicSOM.h new file mode 100644 index 0000000000..682c5419be --- /dev/null +++ b/Code/Learning/otbPeriodicSOM.h @@ -0,0 +1,130 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. + See ITCopyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef __otbPeriodicSOM_h +#define __otbPeriodicSOM_h + +#include "otbSOM.h" + +namespace otb { + +/** + * \class PeriodicSOM + * \brief This class is responsible for the learning of a self organizing + * map when considered to as a torus. + * + * This class extends the SOM object which implements the Self + * Organizing Map (or Kohonen map) learning. + * + * The learning process iteratively select the best-response neuron for each input vector, + * enhancing its response and the response of its neighbors with respect to a certain radius, + * computed from an initial radius, and to a certain learning factor, decreasing at each iteration. + * + * The behavior of the neighborhood is given by a functor (templated) which parameter is the current + * iteration. It returns a neighborhood of type \code{SizeType}. + * + * The behavior of the learning factor (hold by a beta variable) is given by an other functor + * which parameter is the current iteration. It returns a beta value of type \code{double}. + * + * The SOMMap produced as output can be either initialized with a constant custom value or randomly + * generated following a normal law. The seed for the random intialization can be modified. + * + * \sa SOMMap + * \sa SOMActivationBuilder + * \sa CzihoSOMLearningBehaviorFunctor + * \sa CzihoSOMNeighborhoodBehaviorFunctor + */ +template <class TListSample, class TMap, + class TSOMLearningBehaviorFunctor = Functor::CzihoSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor = Functor::CzihoSOMNeighborhoodBehaviorFunctor > +class ITK_EXPORT PeriodicSOM + : public SOM< TListSample, TMap, TSOMLearningBehaviorFunctor, TSOMNeighborhoodBehaviorFunctor > +{ +public: + /** Standard typedefs */ + typedef PeriodicSOM Self; + typedef SOM< TListSample, TMap, + TSOMLearningBehaviorFunctor, + TSOMNeighborhoodBehaviorFunctor > Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Creation through object factory macro */ + itkNewMacro(Self); + + /** Runtime informations macro */ + itkTypeMacro( PeriodicSOM, SOM ); + + typedef TListSample ListSampleType; + typedef typename ListSampleType::Pointer ListSamplePointerType; + typedef TMap MapType; + typedef typename MapType::PixelType NeuronType; + typedef typename NeuronType::ValueType ValueType; + typedef typename MapType::IndexType IndexType; + typedef typename MapType::SizeType SizeType; + typedef typename MapType::RegionType RegionType; + typedef typename MapType::Pointer MapPointerType; + +protected: + /** Constructor */ + PeriodicSOM() {} + /** Destructor */ + virtual ~PeriodicSOM() {} + /** Output information redefinition */ + virtual void GenerateOutputInformation () { + Superclass::GenerateOutputInformation (); } + /** Output allocation redefinition */ + virtual void AllocateOutputs() { + Superclass::AllocateOutputs(); } + /** Main computation method */ + virtual void GenerateData(void) { + Superclass::GenerateData(); } + /** + * Update the output map with a new sample. + * \param sample The new sample to learn, + * \param beta The learning coefficient, + * \param radius The radius of the nieghbourhood. + */ + virtual void UpdateMap(const NeuronType& sample, double beta, SizeType& radius); + /** + * Step one iteration. + */ + virtual void Step(unsigned int currentIteration) { + Superclass::Step( currentIteration ); } + /** PrintSelf method */ + void PrintSelf(std::ostream& os, itk::Indent indent) const { + Superclass::PrintSelf(os,indent); } + +private: + PeriodicSOM(const Self&); // purposely not implemented + void operator=(const Self&); // purposely not implemented + +}; // end of class + +} // end of namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbPeriodicSOM.txx" +#endif + +#endif + + + diff --git a/Code/Learning/otbPeriodicSOM.txx b/Code/Learning/otbPeriodicSOM.txx new file mode 100644 index 0000000000..c4811314d8 --- /dev/null +++ b/Code/Learning/otbPeriodicSOM.txx @@ -0,0 +1,109 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. + See ITCopyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef __otbPeriodicSOM_txx +#define __otbPeriodicSOM_txx + +#include <itkNumericTraits.h> +#include <itkNeighborhoodIterator.h> + +#include "otbPeriodicSOM.h" + + +namespace otb { + +/** + * Update the output map with a new sample. + * \param sample The new sample to learn, + * \param beta The learning coefficient, + * \param radius The radius of the nieghbourhood. + */ +template < class TListSample, class TMap, + class TSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor > +void +PeriodicSOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor> +::UpdateMap(const NeuronType& sample, double beta, SizeType& radius) +{ + unsigned int i,j; + + // output map pointer + MapPointerType map = this->GetOutput(0); + + // winner index in the map + IndexType position = map->GetWinner(sample); + NeuronType winner = map->GetPixel(position); + + // Local neighborhood definition + typedef typename MapType::Superclass ImageMapType; + typedef itk::NeighborhoodIterator< ImageMapType > NeighborhoodIteratorType; + typename MapType::RegionType mapRegion = map->GetLargestPossibleRegion(); + NeighborhoodIteratorType it ( radius, map, mapRegion ); + + // Here, the periodic update is achieved 'by hand' since + // PeriodicBoundaryCondition does not allow to modifiy + // VectorImage contents + SizeType mapSize = mapRegion.GetSize(); + IndexType positionToUpdate; + + // Iterate over the neighborhood ot the winner neuron + it.SetLocation( position ); + + for ( i = 0; i < it.Size(); i++ ) + { + typename NeighborhoodIteratorType::OffsetType offset = it.GetOffset(i); + + // The neighborhood is of elliptic shape + double theDistance = itk::NumericTraits< double >::Zero; + for ( j = 0; j < MapType::ImageDimension; j++ ) + theDistance += pow( static_cast<double>( offset[j] ), 2.0 ) + / pow( static_cast<double>( radius[j] ), 2.0 ); + + if ( theDistance <= 1.0 ) + { + for ( j = 0; j < MapType::ImageDimension; j++ ) + { + int pos = offset[j] + position[j]; + positionToUpdate[j] = ( pos >= 0 ) ? + pos % mapSize[j] : + ( mapSize[j] - ( (-pos) % mapSize[j] ) ) % mapSize[j]; + } + + NeuronType tempNeuron = it.GetPixel(i); + // NeuronType newNeuron ( tempNeuron.Size() ); + // newNeuron.Fill( 0.0 ); // FIXME + NeuronType newNeuron ( tempNeuron ); + + double tempBeta = beta / ( 1.0 + theDistance ); + for( j = 0; j < newNeuron.Size(); j++ ) + { + newNeuron[j] += static_cast<typename NeuronType::ValueType>( + ( sample[j] - tempNeuron[j] ) * tempBeta ); + } + map->SetPixel(positionToUpdate,newNeuron); + } + } + +} + +} // end of namespace otb + +#endif + diff --git a/Code/Learning/otbSOM.h b/Code/Learning/otbSOM.h index 7048ff1302..bcdbcec6f4 100644 --- a/Code/Learning/otbSOM.h +++ b/Code/Learning/otbSOM.h @@ -9,6 +9,8 @@ Version: $Revision$ Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. See OTBCopyright.txt for details. +Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. +See ITCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR @@ -21,6 +23,9 @@ PURPOSE. See the above copyright notices for more information. #include "itkImageToImageFilter.h" #include "itkEuclideanDistance.h" +#include "otbCzihoSOMLearningBehaviorFunctor.h" +#include "otbCzihoSOMNeighborhoodBehaviorFunctor.h" + namespace otb { /** @@ -32,13 +37,23 @@ namespace otb * enhancing its response and the response of its neighbors with respect to a certain radius, * computed from an initial radius, and to a certain learning factor, decreasing at each iteration. * + * The behavior of the neighborhood is given by a functor (templated) which parameter is the current + * iteration. It returns a neighborhood of type \code{SizeType}. + * + * The behavior of the learning factor (hold by a beta variable) is given by an other functor + * which parameter is the current iteration. It returns a beta value of type double. + * * The SOMMap produced as output can be either initialized with a constant custom value or randomly * generated following a normal law. The seed for the random intialization can be modified. * * \sa SOMMap * \sa SOMActivationBuilder + * \sa CzihoSOMLearningBehaviorFunctor + * \sa CzihoSOMNeighborhoodBehaviorFunctor */ -template <class TListSample,class TMap> +template < class TListSample, class TMap, + class TSOMLearningBehaviorFunctor = Functor::CzihoSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor = Functor::CzihoSOMNeighborhoodBehaviorFunctor > class ITK_EXPORT SOM : public itk::ImageSource<TMap> { @@ -64,6 +79,9 @@ class ITK_EXPORT SOM typedef typename MapType::RegionType RegionType; typedef typename MapType::Pointer MapPointerType; + typedef TSOMLearningBehaviorFunctor SOMLearningBehaviorFunctorType; + typedef TSOMNeighborhoodBehaviorFunctor SOMNeighborhoodBehaviorFunctorType; + /** Map dimension */ itkStaticConstMacro(MapDimension,unsigned int, MapType::ImageDimension); @@ -89,24 +107,34 @@ class ITK_EXPORT SOM itkGetObjectMacro(ListSample,ListSampleType); itkSetObjectMacro(ListSample,ListSampleType); + void SetBetaFunctor ( const SOMLearningBehaviorFunctorType & functor ) { + m_BetaFunctor = functor; } + + void SetNeighborhoodSizeFunctor ( const SOMNeighborhoodBehaviorFunctorType & functor ) { + m_NeighborhoodSizeFunctor = functor; } + protected: /** Constructor */ SOM(); /** Destructor */ virtual ~SOM(); + /** Output information redefinition */ + virtual void GenerateOutputInformation (); + /** Output allocation redefinition */ + virtual void AllocateOutputs(); /** Main computation method */ - void GenerateData(void); + virtual void GenerateData(void); /** * Update the output map with a new sample. * \param sample The new sample to learn, * \param beta The learning coefficient, * \param radius The radius of the nieghbourhood. */ - void UpdateMap(const NeuronType& sample, double beta, SizeType& radius); + virtual void UpdateMap(const NeuronType& sample, double beta, SizeType& radius); /** * Step one iteration. */ - void Step(unsigned int currentIteration); + virtual void Step(unsigned int currentIteration); /** PrintSelf method */ void PrintSelf(std::ostream& os, itk::Indent indent) const; @@ -133,6 +161,10 @@ class ITK_EXPORT SOM unsigned int m_Seed; /** The input list sample */ ListSamplePointerType m_ListSample; + /** Behavior of the Learning weightening (link to the beta coefficient) */ + SOMLearningBehaviorFunctorType m_BetaFunctor; + /** Behavior of the Neighborhood extent */ + SOMNeighborhoodBehaviorFunctorType m_NeighborhoodSizeFunctor; }; } // end namespace otb diff --git a/Code/Learning/otbSOM.txx b/Code/Learning/otbSOM.txx index abbed6dd10..177fe1ea2f 100644 --- a/Code/Learning/otbSOM.txx +++ b/Code/Learning/otbSOM.txx @@ -9,6 +9,9 @@ Version: $Revision$ Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. See OTBCopyright.txt for details. +Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. +See ITCopyright.txt for details. + This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR @@ -31,8 +34,10 @@ namespace otb /** * Constructor */ -template <class TListSample,class TMap> -SOM<TListSample,TMap> +template < class TListSample, class TMap, + class TSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor > +SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor> ::SOM() { this->SetNumberOfRequiredInputs(0); @@ -51,8 +56,10 @@ SOM<TListSample,TMap> /** * Destructor */ -template <class TListSample,class TMap> -SOM<TListSample,TMap> +template < class TListSample, class TMap, + class TSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor > +SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor> ::~SOM() { } @@ -62,138 +69,195 @@ SOM<TListSample,TMap> * \param beta The learning coefficient, * \param radius The radius of the nieghbourhood. */ -template <class TListSample,class TMap> +template < class TListSample, class TMap, + class TSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor > void -SOM<TListSample,TMap> -::UpdateMap(const NeuronType& sample, double beta, SizeType& radius) +SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor> +::UpdateMap( const NeuronType& sample, double beta, SizeType& radius ) { - // output map pointer - MapPointerType map = this->GetOutput(); - - // typedefs - typedef itk::ImageRegionIteratorWithIndex<MapType> IteratorType; - typedef itk::ContinuousIndex<double,MapType::ImageDimension> ContinuousIndexType; - typedef itk::Statistics::EuclideanDistance<ContinuousIndexType> DistanceType; - typename DistanceType::Pointer distance = DistanceType::New(); - - // winner index in the map - IndexType position = map->GetWinner(sample); - NeuronType winner = map->GetPixel(position); - - // Local neighborhood definition - RegionType localRegion; - IndexType localIndex = position-radius; - SizeType localSize; - for(unsigned int i=0;i<MapType::ImageDimension;++i) - { - localSize[i]= 2*radius[i]+1; - } - localRegion.SetIndex(localIndex); - localRegion.SetSize(localSize); - localRegion.Crop(map->GetLargestPossibleRegion()); - IteratorType it(map,localRegion); - - // Walk through the map, and evolve each neuron depending on its - // distance to the winner. - for(it.GoToBegin();!it.IsAtEnd();++it) - { - NeuronType tempNeuron = it.Get(); - NeuronType newNeuron; - double tempBeta = beta/(1+distance->Evaluate(ContinuousIndexType(position),ContinuousIndexType(it.GetIndex()))); - for(unsigned int i = 0; i<NeuronType::Length;++i) + // output map pointer + MapPointerType map = this->GetOutput(0); + + // typedefs + typedef itk::ImageRegionIteratorWithIndex<MapType> IteratorType; + typedef itk::ContinuousIndex<double,MapType::ImageDimension> ContinuousIndexType; + typedef itk::Statistics::EuclideanDistance<ContinuousIndexType> DistanceType; + typename DistanceType::Pointer distance = DistanceType::New(); + + // winner index in the map + IndexType position = map->GetWinner(sample); + NeuronType winner = map->GetPixel(position); + + // Local neighborhood definition + RegionType localRegion; + IndexType localIndex = position-radius; + SizeType localSize; + for(unsigned int i=0;i<MapType::ImageDimension;++i) + { + localSize[i]= 2*radius[i]+1; + } + localRegion.SetIndex(localIndex); + localRegion.SetSize(localSize); + localRegion.Crop( map->GetLargestPossibleRegion() ); + IteratorType it ( map, localRegion ); + + // Walk through the map, and evolve each neuron depending on its + // distance to the winner. + for(it.GoToBegin();!it.IsAtEnd();++it) { - newNeuron[i] = tempNeuron[i]+static_cast<typename NeuronType::ValueType>((sample[i]-tempNeuron[i])*tempBeta); + NeuronType tempNeuron = it.Get(); + NeuronType newNeuron ( tempNeuron.Size() ); + double tempBeta = beta + / ( 1 + + distance->Evaluate( ContinuousIndexType(position), + ContinuousIndexType(it.GetIndex()) ) ); + + for(unsigned int i = 0; i < newNeuron.Size();++i) + { + newNeuron[i] = tempNeuron[i] + +static_cast<typename NeuronType::ValueType>( + ( sample[i] - tempNeuron[i] ) * tempBeta ); + } + + it.Set(newNeuron); } - it.Set(newNeuron); - } } /** * Step one iteration. */ -template <class TListSample,class TMap> +template < class TListSample, class TMap, + class TSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor > void -SOM<TListSample,TMap> +SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor> ::Step(unsigned int currentIteration) { - // Compute the new learning coefficient - double newBeta = (m_BetaEnd-m_BetaInit)/static_cast<double>(m_NumberOfIterations) - *static_cast<double>(currentIteration)+m_BetaInit; - - // Compute the new neighborhood size - SizeType newSize; - newSize[0]=m_NeighborhoodSizeInit[0]-static_cast<int>((static_cast<float>(currentIteration) - /static_cast<float>(m_NumberOfIterations))*static_cast<float>(m_NeighborhoodSizeInit[0]-2)); - - newSize[1]=m_NeighborhoodSizeInit[1]-static_cast<int>((static_cast<float>(currentIteration) - /static_cast<float>(m_NumberOfIterations))*static_cast<float>(m_NeighborhoodSizeInit[1]-2)); - - // update the neurons map with each example of the training set. - otbMsgDebugMacro(<<"Beta: "<<newBeta<<", radius: "<<newSize); - for(typename ListSampleType::Iterator it=m_ListSample->Begin();it!=m_ListSample->End();++it) - { - UpdateMap(it.GetMeasurementVector(),newBeta,newSize); - } + // Compute the new learning coefficient + double newBeta = m_BetaFunctor( + currentIteration, m_NumberOfIterations, m_BetaInit, m_BetaEnd ); + + // Compute the new neighborhood size + SizeType newSize = m_NeighborhoodSizeFunctor( + currentIteration, m_NumberOfIterations, m_NeighborhoodSizeInit ); + + // update the neurons map with each example of the training set. + otbMsgDebugMacro(<<"Beta: "<<newBeta<<", radius: "<<newSize); + for ( typename ListSampleType::Iterator it = m_ListSample->Begin(); + it != m_ListSample->End(); + ++it ) + { + UpdateMap( it.GetMeasurementVector(), newBeta, newSize ); + } +} +/** + * Output information redefinition + */ +template < class TListSample, class TMap, + class TSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor > +void +SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor> +::GenerateOutputInformation () +{ + Superclass::GenerateOutputInformation(); + this->GetOutput()->SetNumberOfComponentsPerPixel( + m_ListSample->GetMeasurementVectorSize() ); + + IndexType index; + index.Fill(0); + + RegionType region; + region.SetIndex(index); + region.SetSize( this->GetMapSize() ); + this->GetOutput()->SetRegions( region ); + } +/** + * Output redefinition + */ +template < class TListSample, class TMap, + class TSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor > +void +SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor> +::AllocateOutputs() +{ + if ( this->GetNumberOfOutputs() != 1 ) + itkExceptionMacro( << "Number of output image should be 1" ); + + // output neuron map fill + MapPointerType map = this->GetOutput(0); + map->Allocate(); +} + /** * Main computation method */ -template <class TListSample,class TMap> +template < class TListSample, class TMap, + class TSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor > void -SOM<TListSample,TMap> +SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor> ::GenerateData(void) { - // output neuron map fill - MapPointerType map = this->GetOutput(); - RegionType region; - IndexType index; - index.Fill(0); - region.SetIndex(index); - region.SetSize(m_MapSize); - map->SetRegions(region); - map->Allocate(); - - if(m_RandomInit) - { - typedef itk::Statistics::MersenneTwisterRandomVariateGenerator GeneratorType; - typedef itk::ImageRegionIterator<MapType> IteratorType; - GeneratorType::Pointer generator = GeneratorType::New(); - generator->Initialize(m_Seed); - NeuronType neuronInit; - IteratorType it(map,map->GetLargestPossibleRegion()); - - for(it.GoToBegin();!it.IsAtEnd();++it) + this->AllocateOutputs(); + this->BeforeThreadedGenerateData(); + + MapPointerType map = this->GetOutput(0); + + if ( m_RandomInit ) { - for(int i=0;i<NeuronType::Length;++i) - { - neuronInit[i]=static_cast<typename NeuronType::ValueType>( - generator->GetUniformVariate(static_cast<double>(m_MinWeight),static_cast<double>(m_MaxWeight))); - } - it.Set(neuronInit); + typedef itk::Statistics::MersenneTwisterRandomVariateGenerator GeneratorType; + typedef itk::ImageRegionIterator<MapType> IteratorType; + GeneratorType::Pointer generator = GeneratorType::New(); + generator->Initialize(m_Seed); + + NeuronType neuronInit ( m_ListSample->GetMeasurementVectorSize() ); + IteratorType it ( map, map->GetLargestPossibleRegion() ); + + for ( it.GoToBegin(); !it.IsAtEnd(); ++it ) + { + for(unsigned int i=0;i< neuronInit.Size();++i) + { + neuronInit[i]=static_cast<typename NeuronType::ValueType>( + generator->GetUniformVariate(static_cast<double>(m_MinWeight), + static_cast<double>(m_MaxWeight)) ); + } + it.Set(neuronInit); + } + } + else + { + NeuronType neuronInit ( m_ListSample->GetMeasurementVectorSize() ); + neuronInit.Fill(m_MaxWeight); + map->FillBuffer(neuronInit); + } + + // Step through the iterations + for(unsigned int i = 0;i<m_NumberOfIterations;++i) + { + //otbMsgDebugMacro(<<"Step "<<i+1<<" / "<<m_NumberOfIterations); + std::cerr << "Step "<< i+1 <<" / "<<m_NumberOfIterations << " \r"; + Step(i); } - } - else - { - NeuronType neuronInit; - neuronInit.Fill(m_MaxWeight); - map->FillBuffer(neuronInit); - } - - // Step through the iterations - for(unsigned int i = 0;i<m_NumberOfIterations;++i) - { - otbMsgDebugMacro(<<"Step "<<i+1<<" / "<<m_NumberOfIterations); - Step(i); - } + + this->AfterThreadedGenerateData(); } /** *PrintSelf method */ -template <class TListSample,class TMap> +template < class TListSample, class TMap, + class TSOMLearningBehaviorFunctor, + class TSOMNeighborhoodBehaviorFunctor > void -SOM<TListSample,TMap> +SOM<TListSample,TMap,TSOMLearningBehaviorFunctor,TSOMNeighborhoodBehaviorFunctor> ::PrintSelf(std::ostream& os, itk::Indent indent) const { - Superclass::PrintSelf(os,indent); + Superclass::PrintSelf(os,indent); } + } // end namespace otb + #endif + diff --git a/Code/Learning/otbSOMLearningBehaviorFunctor.h b/Code/Learning/otbSOMLearningBehaviorFunctor.h new file mode 100644 index 0000000000..17e7073847 --- /dev/null +++ b/Code/Learning/otbSOMLearningBehaviorFunctor.h @@ -0,0 +1,67 @@ +/*========================================================================= + +Program: ORFEO Toolbox +Language: C++ +Date: $Date$ +Version: $Revision$ + + +Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. +See OTBCopyright.txt for details. + +Copyright (c) Institut Telecom ; Telecom bretagne. All rights reserved. +See ITCopyright.txt for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef __otbSOMLearningBehaviorFunctor_h +#define __otbSOMLearningBehaviorFunctor_h + + +namespace otb { + +namespace Functor { + + /** \class SOMLearningBehaviorFunctor + * \brief Classical Beta behavior over SOM training phase + * + * This class implements an standart evolution of the $\beta$ weightening + * coefficient over the SOM training. + * + * \f{equation*} + \beta = \beta_0 + \left( \beta_{\text{end}} - \beta_0 \right) + \frac{t}{t_{\text{end}}} + \f{equation*} + * + * \sa SOM + */ + class SOMLearningBehaviorFunctor + { + public : + /** Empty constructor / descructor */ + CzihoSOMLearningBehaviorFunctor () { } + virtual ~CzihoSOMLearningBehaviorFunctor() { } + + /** Functor */ + virtual double operator() ( unsigned int currentIteration, + unsigned int numberOfIterations, + double betaInit, double betaEnd ) + { + return betaInit + ( betaEnd - betaInit ) + * static_cast<double>( currentIteration ) + / static_cast<double>( numberOfIterations ); + } + + }; // end of class SOMLearningBehaviorFunctor + +} // end namespace Functor + +} // end namespace otb + +#endif + + diff --git a/Code/Learning/otbSOMMap.h b/Code/Learning/otbSOMMap.h index 173f9c26ed..a826d8e7b7 100644 --- a/Code/Learning/otbSOMMap.h +++ b/Code/Learning/otbSOMMap.h @@ -9,6 +9,9 @@ Version: $Revision$ Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. See OTBCopyright.txt for details. +Copyright (c) Institut Telecom ; Telecom Bretagne. All right reserved. +See GETCopyright.txt for details. + This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR @@ -18,9 +21,9 @@ PURPOSE. See the above copyright notices for more information. #ifndef _otbSOMMap_h #define _otbSOMMap_h -#include "itkFixedArray.h" +#include "itkVariableLengthVector.h" #include "itkEuclideanDistance.h" -#include "otbImage.h" +#include "otbVectorImage.h" namespace otb { @@ -42,22 +45,26 @@ namespace otb * \sa SOM * \sa SOMActivationBuilder */ -template <class TNeuron=itk::FixedArray<float,3>, - class TDistance=itk::Statistics::EuclideanDistance<TNeuron>,unsigned int VMapDimension=2> +template <class TNeuron=itk::VariableLengthVector<double>, + class TDistance=itk::Statistics::EuclideanDistance<TNeuron>, + unsigned int VMapDimension=2> class ITK_EXPORT SOMMap -: public Image<TNeuron,VMapDimension> +: public otb::VectorImage<typename TNeuron::ComponentType,VMapDimension> { public: /** Standard typedefs */ typedef SOMMap Self; - typedef Image<TNeuron,VMapDimension> Superclass; + typedef otb::VectorImage<typename TNeuron::ComponentType,VMapDimension> Superclass; typedef itk::SmartPointer<Self> Pointer; typedef itk::SmartPointer<const Self> ConstPointer; /** Creation through object factory macro */ itkNewMacro(Self); - /** Runtime informations macro */ - itkTypeMacro(SOMMap,Image); + /** + * There is no runtime informations macro since + * this class has to be considered to as a simple VectorImage + * // itkTypeMacro(SOMMap,VectorImage); + * */ /** Template parameters related typedefs */ typedef TNeuron NeuronType; diff --git a/Code/Learning/otbSOMMap.txx b/Code/Learning/otbSOMMap.txx index 288a5ffee4..a008f1f950 100644 --- a/Code/Learning/otbSOMMap.txx +++ b/Code/Learning/otbSOMMap.txx @@ -9,6 +9,9 @@ Version: $Revision$ Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. See OTBCopyright.txt for details. +Copyright (c) Institut Telecom ; Telecom Bretagne. All right reserved. +See GETCopyright.txt for details. + This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR @@ -59,6 +62,7 @@ SOMMap<TNeuron,TDistance,VMapDimension> // Define the minimum distance and position IndexType minPos = it.GetIndex(); + double minDistance = activation->Evaluate(sample,it.Get()); // Iterate through the map to get the minimum distance position diff --git a/Testing/Code/BasicFilters/CMakeLists.txt b/Testing/Code/BasicFilters/CMakeLists.txt index f65f5025a2..3a4cbb79ca 100755 --- a/Testing/Code/BasicFilters/CMakeLists.txt +++ b/Testing/Code/BasicFilters/CMakeLists.txt @@ -774,6 +774,16 @@ ADD_TEST(bfTvRationalQuotientResampleImageFilter ${BASICFILTERS_TESTS7} 80 80 ) +# ------- otb::EuclideanDistanceWithMissingValue ---------------------------- + + ADD_TEST(bfTuEuclideanDistanceWithMissingValueNew ${BASICFILTERS_TESTS8} + otbEuclideanDistanceWithMissingValueNew) + +ADD_TEST(bfTvEuclideanDistanceWithMissingValue ${BASICFILTERS_TESTS8} + otbEuclideanDistanceWithMissingValue) + + +======= # ------- otb::LabelizeNeighborhoodConnectedImageFilter ---------------------------- ADD_TEST(bfTuLabelizeNeighborhoodConnectedImageFilterNew ${BASICFILTERS_TESTS8} @@ -919,6 +929,8 @@ otbLabelizeNeighborhoodConnectedImageFilterNew.cxx otbLabelizeNeighborhoodConnectedImageFilter.cxx otbLabelizeConfidenceConnectedImageFilterNew.cxx otbLabelizeConfidenceConnectedImageFilter.cxx +otbEuclideanDistanceWithMissingValueNew.cxx +otbEuclideanDistanceWithMissingValue.cxx ) INCLUDE_DIRECTORIES("${OTBTesting_BINARY_DIR}") diff --git a/Testing/Code/BasicFilters/otbBasicFiltersTests8.cxx b/Testing/Code/BasicFilters/otbBasicFiltersTests8.cxx index f4e4171f88..abf982d8af 100644 --- a/Testing/Code/BasicFilters/otbBasicFiltersTests8.cxx +++ b/Testing/Code/BasicFilters/otbBasicFiltersTests8.cxx @@ -33,4 +33,6 @@ void RegisterTests() REGISTER_TEST(otbLabelizeNeighborhoodConnectedImageFilter); REGISTER_TEST(otbLabelizeConfidenceConnectedImageFilterNew); REGISTER_TEST(otbLabelizeConfidenceConnectedImageFilter); + REGISTER_TEST(otbEuclideanDistanceWithMissingValueNew); + REGISTER_TEST(otbEuclideanDistanceWithMissingValue); } diff --git a/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.cxx b/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.cxx new file mode 100644 index 0000000000..b88fdfa4a3 --- /dev/null +++ b/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValue.cxx @@ -0,0 +1,61 @@ +/*========================================================================= + +Program: ORFEO Toolbox +Language: C++ +Date: $Date$ +Version: $Revision$ + + +Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. +See OTBCopyright.txt for details. + +Copyright (c) Institut Telecom ; Telecom Bretagne. All rights reserved. +See ITCopyright.txt for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + + +#include <iostream> + +#include "itkVariableLengthVector.h" +#include "otbEuclideanDistanceWithMissingValue.h" + +int otbEuclideanDistanceWithMissingValue( int argc, char * argv[] ) +{ + + typedef itk::VariableLengthVector< double > VectorType; + typedef otb::Statistics::EuclideanDistanceWithMissingValue< VectorType > DistanceType; + + DistanceType::Pointer dist = DistanceType::New(); + + if ( dist->IsMissingValue( 0.0 ) ) + return EXIT_FAILURE; + + if ( dist->IsMissingValue( 1.0 ) ) + return EXIT_FAILURE; + + if ( dist->IsMissingValue( -1.0 ) ) + return EXIT_FAILURE; + + /* + std::cerr << "Is O Nan ?? -> " << dist->IsMissingValue( 0.0 ) << "\n"; + std::cerr << "Is 1 Nan ?? -> " << dist->IsMissingValue( 1.0 ) << "\n"; + std::cerr << "Is -1 Nan ?? -> " << dist->IsMissingValue( -1.0 ) << "\n"; + */ + + double x = 0.0; + + dist->SetToMissingValue(x); + if ( !dist->IsMissingValue( x ) ) + return EXIT_FAILURE; + // std::cerr << "Is x (=" << x << ") Nan ?? -> " << dist->IsMissingValue( x ) << "\n"; + + return EXIT_SUCCESS; +} + + + diff --git a/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValueNew.cxx b/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValueNew.cxx new file mode 100644 index 0000000000..063cdccfc3 --- /dev/null +++ b/Testing/Code/BasicFilters/otbEuclideanDistanceWithMissingValueNew.cxx @@ -0,0 +1,39 @@ +/*========================================================================= + +Program: ORFEO Toolbox +Language: C++ +Date: $Date$ +Version: $Revision$ + + +Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. +See OTBCopyright.txt for details. + +Copyright (c) Institut Telecom ; Telecom Bretagne. All rights reserved. +See ITCopyright.txt for details. + +This software is distributed WITHOUT ANY WARRANTY; without even +the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + + +#include <iostream> + +#include "itkVariableLengthVector.h" +#include "otbEuclideanDistanceWithMissingValue.h" + +int otbEuclideanDistanceWithMissingValueNew( int argc, char * argv[] ) +{ + + typedef itk::VariableLengthVector< double > VectorType; + typedef otb::Statistics::EuclideanDistanceWithMissingValue< VectorType > DistanceType; + + DistanceType::Pointer dist = DistanceType::New(); + + return EXIT_SUCCESS; +} + + + diff --git a/Testing/Code/Learning/CMakeLists.txt b/Testing/Code/Learning/CMakeLists.txt index 05aff8bbc7..1730b07384 100644 --- a/Testing/Code/Learning/CMakeLists.txt +++ b/Testing/Code/Learning/CMakeLists.txt @@ -161,6 +161,20 @@ ADD_TEST(leTvSOM ${LEARNING_TESTS2} ${TEMP}/leSOMPoupeesSubOutputMap1.hdr 32 32 10 10 5 1.0 0.1 0) +# ------- otb::PeriodicSOM ----------------------------- + +ADD_TEST(leTuPeriodicSOMNew ${LEARNING_TESTS2} + otbPeriodicSOMNew) + +ADD_TEST(leTvPeriodicSOM ${LEARNING_TESTS2} + --compare-image ${EPSILON} + ${BASELINE}/lePeriodicSOMPoupeesSubOutputMap1.hdr + ${TEMP}/lePeriodicSOMPoupeesSubOutputMap1.hdr + otbSOM + ${INPUTDATA}/poupees_sub.png + ${TEMP}/lePeriodicSOMPoupeesSubOutputMap1.hdr + 32 32 10 10 5 1.0 0.1 0) + # ------- otb::SOMActivationBuilder ----------------------------- ADD_TEST(leTuSOMActivationBuilderNew ${LEARNING_TESTS2} @@ -267,6 +281,8 @@ otbSOMMapNew.cxx otbSOMMap.cxx otbSOMNew.cxx otbSOM.cxx +otbPeriodicSOMNew.cxx +otbPeriodicSOM.cxx otbSOMActivationBuilderNew.cxx otbSOMActivationBuilder.cxx ) diff --git a/Testing/Code/Learning/otbLearningTests2.cxx b/Testing/Code/Learning/otbLearningTests2.cxx index d7c0956f34..cc1f0e7232 100644 --- a/Testing/Code/Learning/otbLearningTests2.cxx +++ b/Testing/Code/Learning/otbLearningTests2.cxx @@ -37,6 +37,8 @@ REGISTER_TEST(otbSOMMapNew); REGISTER_TEST(otbSOMMap); REGISTER_TEST(otbSOMNew); REGISTER_TEST(otbSOM); +REGISTER_TEST(otbPeriodicSOMNew); +REGISTER_TEST(otbPeriodicSOM); REGISTER_TEST(otbSOMActivationBuilderNew); REGISTER_TEST(otbSOMActivationBuilder); } diff --git a/Testing/Code/Learning/otbPeriodicSOM.cxx b/Testing/Code/Learning/otbPeriodicSOM.cxx new file mode 100644 index 0000000000..05b8a2c836 --- /dev/null +++ b/Testing/Code/Learning/otbPeriodicSOM.cxx @@ -0,0 +1,109 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "itkExceptionObject.h" +#include "otbVectorImage.h" +#include "otbSOMMap.h" +#include "otbPeriodicSOM.h" +#include "itkRGBPixel.h" +#include "itkEuclideanDistance.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" +#include "itkListSample.h" +#include "itkImageRegionIterator.h" + +int otbPeriodicSOM(int argc, char* argv[]) +{ +try + { + const unsigned int Dimension = 2; + char * inputFileName = argv[1]; + char * outputFileName = argv[2]; + unsigned int sizeX = atoi(argv[3]); + unsigned int sizeY = atoi(argv[4]); + unsigned int neighInitX = atoi(argv[5]); + unsigned int neighInitY= atoi(argv[6]); + unsigned int nbIterations= atoi(argv[7]); + double betaInit = atof(argv[8]); + double betaEnd= atof(argv[9]); + double initValue = atof(argv[10]); + + + typedef double ComponentType; + typedef itk::VariableLengthVector<ComponentType> PixelType; + typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; + typedef otb::SOMMap<PixelType,DistanceType,Dimension> MapType; + typedef otb::VectorImage<ComponentType,Dimension> ImageType; + typedef otb::ImageFileReader<ImageType> ReaderType; + typedef itk::Statistics::ListSample<PixelType> ListSampleType; + + typedef otb::PeriodicSOM<ListSampleType,MapType> SOMType; + typedef otb::ImageFileWriter<MapType> WriterType; + + ReaderType::Pointer reader = ReaderType::New(); + reader->SetFileName(inputFileName); + reader->Update(); + + ListSampleType::Pointer listSample = ListSampleType::New(); + + itk::ImageRegionIterator<ImageType> it(reader->GetOutput(),reader->GetOutput()->GetLargestPossibleRegion()); + + it.GoToBegin(); + + while(!it.IsAtEnd()) + { + listSample->PushBack(it.Get()); + ++it; + } + + std::cout<<"LIST SAMPLE SIZE: "<<listSample->GetMeasurementVectorSize()<<std::endl; + + // Instantiation + SOMType::Pointer som = SOMType::New(); + som->SetListSample(listSample); + SOMType::SizeType size; + size[0]=sizeX; + size[1]=sizeY; + som->SetMapSize(size); + SOMType::SizeType radius; + radius[0] = neighInitX; + radius[1] = neighInitY; + som->SetNeighborhoodSizeInit(radius); + som->SetNumberOfIterations(nbIterations); + som->SetBetaInit(betaInit); + som->SetBetaEnd(betaEnd); + som->SetMaxWeight(initValue); + som->SetRandomInit(false); + + WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(outputFileName); + writer->SetInput(som->GetOutput()); + writer->Update(); + } +catch( itk::ExceptionObject & err ) + { + std::cout << "Exception itk::ExceptionObject thrown !" << std::endl; + std::cout << err << std::endl; + return EXIT_FAILURE; + } +catch( ... ) + { + std::cout << "Unknown exception thrown !" << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/Testing/Code/Learning/otbPeriodicSOMNew.cxx b/Testing/Code/Learning/otbPeriodicSOMNew.cxx new file mode 100644 index 0000000000..3f8d35e9e2 --- /dev/null +++ b/Testing/Code/Learning/otbPeriodicSOMNew.cxx @@ -0,0 +1,53 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "itkExceptionObject.h" +#include "otbSOMMap.h" +#include "otbPeriodicSOM.h" +#include "itkRGBPixel.h" +#include "itkEuclideanDistance.h" +#include "itkListSample.h" + +int otbPeriodicSOMNew(int argc, char* argv[]) +{ +try + { + const unsigned int Dimension = 2; + typedef float ComponentType; + typedef itk::VariableLengthVector<ComponentType> PixelType; + typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; + typedef otb::SOMMap<PixelType,DistanceType,Dimension> SOMMapType; +// typedef itk::Statistics::ImageToListAdaptor<SOMMapType> AdaptorType; + typedef itk::Statistics::ListSample<PixelType> ListSampleType; + typedef otb::PeriodicSOM<ListSampleType,SOMMapType> SOMType; + + // Instantiation + SOMType::Pointer som = SOMType::New(); + } +catch( itk::ExceptionObject & err ) + { + std::cout << "Exception itk::ExceptionObject thrown !" << std::endl; + std::cout << err << std::endl; + return EXIT_FAILURE; + } +catch( ... ) + { + std::cout << "Unknown exception thrown !" << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/Testing/Code/Learning/otbSOM.cxx b/Testing/Code/Learning/otbSOM.cxx index 71367c1d4f..03b1474f39 100644 --- a/Testing/Code/Learning/otbSOM.cxx +++ b/Testing/Code/Learning/otbSOM.cxx @@ -16,14 +16,15 @@ =========================================================================*/ #include "itkExceptionObject.h" -#include "otbImage.h" +#include "otbVectorImage.h" #include "otbSOMMap.h" #include "otbSOM.h" #include "itkRGBPixel.h" #include "itkEuclideanDistance.h" #include "otbImageFileReader.h" #include "otbImageFileWriter.h" -#include "itkImageToListAdaptor.h" +#include "itkListSample.h" +#include "itkImageRegionIterator.h" int otbSOM(int argc, char* argv[]) { @@ -43,26 +44,37 @@ try typedef double ComponentType; - typedef itk::RGBPixel<ComponentType> PixelType; + typedef itk::VariableLengthVector<ComponentType> PixelType; typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; typedef otb::SOMMap<PixelType,DistanceType,Dimension> MapType; - typedef otb::Image<PixelType,Dimension> ImageType; + typedef otb::VectorImage<ComponentType,Dimension> ImageType; typedef otb::ImageFileReader<ImageType> ReaderType; - typedef itk::Statistics::ImageToListAdaptor<ImageType> ListAdaptorType; + typedef itk::Statistics::ListSample<PixelType> ListSampleType; - typedef otb::SOM<ListAdaptorType,MapType> SOMType; + typedef otb::SOM<ListSampleType,MapType> SOMType; typedef otb::ImageFileWriter<MapType> WriterType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(inputFileName); reader->Update(); - ListAdaptorType::Pointer adaptor = ListAdaptorType::New(); - adaptor->SetImage(reader->GetOutput()); + ListSampleType::Pointer listSample = ListSampleType::New(); + + itk::ImageRegionIterator<ImageType> it(reader->GetOutput(),reader->GetOutput()->GetLargestPossibleRegion()); + + it.GoToBegin(); + while(!it.IsAtEnd()) + { + listSample->PushBack(it.Get()); + ++it; + } + + std::cout<<"LIST SAMPLE SIZE: "<<listSample->GetMeasurementVectorSize()<<std::endl; + // Instantiation SOMType::Pointer som = SOMType::New(); - som->SetListSample(adaptor); + som->SetListSample(listSample); SOMType::SizeType size; size[0]=sizeX; size[1]=sizeY; diff --git a/Testing/Code/Learning/otbSOMActivationBuilder.cxx b/Testing/Code/Learning/otbSOMActivationBuilder.cxx index c3a6494858..7eb60a3e41 100644 --- a/Testing/Code/Learning/otbSOMActivationBuilder.cxx +++ b/Testing/Code/Learning/otbSOMActivationBuilder.cxx @@ -19,11 +19,13 @@ #include "otbImage.h" #include "otbSOMMap.h" #include "otbSOMActivationBuilder.h" -#include "itkRGBPixel.h" +#include "itkVariableLengthVector.h" #include "itkEuclideanDistance.h" #include "otbImageFileReader.h" #include "otbImageFileWriter.h" -#include "itkImageToListAdaptor.h" +#include "itkListSample.h" +#include "otbVectorImage.h" +#include "itkImageRegionIterator.h" int otbSOMActivationBuilder(int argc, char* argv[]) { @@ -36,33 +38,43 @@ try typedef float ComponentType; typedef unsigned char OutputPixelType; - typedef itk::RGBPixel<ComponentType> PixelType; + typedef itk::VariableLengthVector<ComponentType> PixelType; typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; typedef otb::SOMMap<PixelType,DistanceType,Dimension> MapType; typedef otb::ImageFileReader<MapType> MapReaderType; - typedef otb::Image<PixelType,Dimension> InputImageType; + typedef otb::VectorImage<ComponentType,Dimension> InputImageType; typedef otb::ImageFileReader<InputImageType> ReaderType; - typedef itk::Statistics::ImageToListAdaptor<InputImageType> AdaptorType; + typedef itk::Statistics::ListSample<PixelType> ListSampleType; typedef otb::Image<OutputPixelType,Dimension> OutputImageType; typedef otb::ImageFileWriter<OutputImageType> WriterType; - typedef otb::SOMActivationBuilder<AdaptorType,MapType,OutputImageType> SOMActivationBuilderType; + typedef otb::SOMActivationBuilder<ListSampleType,MapType,OutputImageType> SOMActivationBuilderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(vectorSetFileName); reader->Update(); - AdaptorType::Pointer adaptor = AdaptorType::New(); - adaptor->SetImage(reader->GetOutput()); + + ListSampleType::Pointer listSample = ListSampleType::New(); + + itk::ImageRegionIterator<InputImageType> it(reader->GetOutput(),reader->GetOutput()->GetLargestPossibleRegion()); + + it.GoToBegin(); + + while(!it.IsAtEnd()) + { + listSample->PushBack(it.Get()); + ++it; + } MapReaderType::Pointer mapReader = MapReaderType::New(); mapReader->SetFileName(mapFileName); SOMActivationBuilderType::Pointer somAct = SOMActivationBuilderType::New(); somAct->SetInput(mapReader->GetOutput()); - somAct->SetListSample(adaptor); + somAct->SetListSample(listSample); WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outputFileName); diff --git a/Testing/Code/Learning/otbSOMActivationBuilderNew.cxx b/Testing/Code/Learning/otbSOMActivationBuilderNew.cxx index 85d704ee54..1e75883dfe 100644 --- a/Testing/Code/Learning/otbSOMActivationBuilderNew.cxx +++ b/Testing/Code/Learning/otbSOMActivationBuilderNew.cxx @@ -19,10 +19,11 @@ #include "otbSOMMap.h" #include "otbSOM.h" #include "otbSOMActivationBuilder.h" -#include "itkRGBPixel.h" #include "itkEuclideanDistance.h" -#include "itkImageToListAdaptor.h" - +#include "itkListSample.h" +#include "itkVariableLengthVector.h" +#include "otbImage.h" +#include "otbVectorImage.h" int otbSOMActivationBuilderNew(int argc, char* argv[]) { @@ -31,14 +32,14 @@ try const unsigned int Dimension =2; typedef float ComponentType; typedef unsigned char OutputPixelType; - typedef itk::RGBPixel<ComponentType> PixelType; + typedef itk::VariableLengthVector<ComponentType> PixelType; typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; typedef otb::SOMMap<PixelType,DistanceType,Dimension> MapType; - typedef otb::Image<PixelType,Dimension> InputImageType; - typedef itk::Statistics::ImageToListAdaptor<InputImageType> AdaptorType; + typedef otb::VectorImage<ComponentType,Dimension> InputImageType; + typedef itk::Statistics::ListSample<PixelType> ListSampleType; typedef otb::Image<OutputPixelType,Dimension> OutputImageType; - typedef otb::SOMActivationBuilder<AdaptorType,MapType,OutputImageType> SOMActivationBuilderType; + typedef otb::SOMActivationBuilder<ListSampleType,MapType,OutputImageType> SOMActivationBuilderType; // Instantiation SOMActivationBuilderType::Pointer somAct = SOMActivationBuilderType::New(); diff --git a/Testing/Code/Learning/otbSOMClassifier.cxx b/Testing/Code/Learning/otbSOMClassifier.cxx index 838d09cee1..a7045c1012 100644 --- a/Testing/Code/Learning/otbSOMClassifier.cxx +++ b/Testing/Code/Learning/otbSOMClassifier.cxx @@ -22,12 +22,13 @@ #include <fstream> #include "otbVectorImage.h" +#include "otbImage.h" #include "otbSOMMap.h" #include "otbSOMClassifier.h" #include "otbImageFileReader.h" #include "otbImageFileWriter.h" #include "itkImageRegionIterator.h" -#include "itkImageToListAdaptor.h" +#include "itkListSample.h" int otbSOMClassifier(int argc, char* argv[] ) { @@ -48,13 +49,13 @@ int otbSOMClassifier(int argc, char* argv[] ) typedef int LabelPixelType; const unsigned int Dimension = 2; - typedef itk::RGBPixel<InputPixelType> PixelType; + typedef itk::VariableLengthVector<InputPixelType> PixelType; typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; typedef otb::SOMMap<PixelType,DistanceType,Dimension> SOMMapType; - typedef otb::Image<PixelType,Dimension> InputImageType; + typedef otb::VectorImage<InputPixelType,Dimension> InputImageType; typedef otb::ImageFileReader< InputImageType > ReaderType; typedef otb::ImageFileReader<SOMMapType> SOMReaderType; - typedef itk::Statistics::ImageToListAdaptor< InputImageType > SampleType; + typedef itk::Statistics::ListSample< PixelType > SampleType; typedef otb::SOMClassifier<SampleType,SOMMapType,LabelPixelType> ClassifierType; typedef otb::Image<LabelPixelType, Dimension > OutputImageType; typedef itk::ImageRegionIterator< OutputImageType> OutputIteratorType; @@ -70,11 +71,20 @@ int otbSOMClassifier(int argc, char* argv[] ) somreader->Update(); std::cout<<"SOM map read"<<std::endl; - SampleType::Pointer sample = SampleType::New(); - sample->SetImage(reader->GetOutput()); + SampleType::Pointer listSample = SampleType::New(); + + itk::ImageRegionIterator<InputImageType> it(reader->GetOutput(),reader->GetOutput()->GetLargestPossibleRegion()); + + it.GoToBegin(); + + while(!it.IsAtEnd()) + { + listSample->PushBack(it.Get()); + ++it; + } ClassifierType::Pointer classifier = ClassifierType::New() ; - classifier->SetSample(sample.GetPointer()); + classifier->SetSample(listSample.GetPointer()); classifier->SetMap(somreader->GetOutput()); classifier->Update() ; diff --git a/Testing/Code/Learning/otbSOMClassifierNew.cxx b/Testing/Code/Learning/otbSOMClassifierNew.cxx index 0e53d63797..ec95897e89 100644 --- a/Testing/Code/Learning/otbSOMClassifierNew.cxx +++ b/Testing/Code/Learning/otbSOMClassifierNew.cxx @@ -23,7 +23,8 @@ #include <fstream> #include "otbSOMMap.h" #include "otbSOMClassifier.h" -#include "itkImageToListAdaptor.h" +#include "itkListSample.h" +#include "otbVectorImage.h" int otbSOMClassifierNew(int argc, char* argv[] ) { @@ -33,11 +34,11 @@ int otbSOMClassifierNew(int argc, char* argv[] ) typedef int LabelPixelType; const unsigned int Dimension = 2; - typedef itk::RGBPixel<InputPixelType> PixelType; + typedef itk::VariableLengthVector<InputPixelType> PixelType; typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; typedef otb::SOMMap<PixelType,DistanceType,Dimension> SOMMapType; - typedef otb::Image<PixelType,Dimension> InputImageType; - typedef itk::Statistics::ImageToListAdaptor< InputImageType > SampleType; + typedef otb::VectorImage<InputPixelType,Dimension> InputImageType; + typedef itk::Statistics::ListSample< PixelType > SampleType; typedef otb::SOMClassifier<SampleType,SOMMapType,LabelPixelType> ClassifierType; ClassifierType::Pointer classifier = ClassifierType::New() ; diff --git a/Testing/Code/Learning/otbSOMMap.cxx b/Testing/Code/Learning/otbSOMMap.cxx index 5fa01dcfde..f85fbe17eb 100644 --- a/Testing/Code/Learning/otbSOMMap.cxx +++ b/Testing/Code/Learning/otbSOMMap.cxx @@ -19,17 +19,19 @@ #include "otbSOMMap.h" #include "itkRGBPixel.h" #include "itkEuclideanDistance.h" +#include "itkVariableLengthVector.h" int otbSOMMap(int argc, char* argv[]) { try { const unsigned int Dimension = 2; - typedef float ComponentType; - typedef itk::RGBPixel<ComponentType> PixelType; - typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; + typedef float InternalPixelType; + typedef itk::VariableLengthVector<InternalPixelType> PixelType; + typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; typedef otb::SOMMap<PixelType,DistanceType,Dimension> SOMMapType; + // Instantiation SOMMapType::Pointer somMap = SOMMapType::New(); @@ -42,15 +44,18 @@ try region.SetIndex(index); region.SetSize(size); somMap->SetRegions(region); + somMap->SetNumberOfComponentsPerPixel(3); somMap->Allocate(); // Filling with null pixels PixelType nullPixel; + nullPixel.SetSize(3); nullPixel.Fill(0); somMap->FillBuffer(nullPixel); // Definition of a non-null pixel PixelType winner; + winner.SetSize(3); winner.Fill(1); index.Fill(32); somMap->SetPixel(index,winner); diff --git a/Testing/Code/Learning/otbSOMNew.cxx b/Testing/Code/Learning/otbSOMNew.cxx index 4a24a778a8..326ff6bd79 100644 --- a/Testing/Code/Learning/otbSOMNew.cxx +++ b/Testing/Code/Learning/otbSOMNew.cxx @@ -20,7 +20,7 @@ #include "otbSOM.h" #include "itkRGBPixel.h" #include "itkEuclideanDistance.h" -#include "itkImageToListAdaptor.h" +#include "itkListSample.h" int otbSOMNew(int argc, char* argv[]) { @@ -28,11 +28,12 @@ try { const unsigned int Dimension = 2; typedef float ComponentType; - typedef itk::RGBPixel<ComponentType> PixelType; + typedef itk::VariableLengthVector<ComponentType> PixelType; typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; typedef otb::SOMMap<PixelType,DistanceType,Dimension> SOMMapType; - typedef itk::Statistics::ImageToListAdaptor<SOMMapType> AdaptorType; - typedef otb::SOM<AdaptorType,SOMMapType> SOMType; +// typedef itk::Statistics::ImageToListAdaptor<SOMMapType> AdaptorType; + typedef itk::Statistics::ListSample<PixelType> ListSampleType; + typedef otb::SOM<ListSampleType,SOMMapType> SOMType; // Instantiation SOMType::Pointer som = SOMType::New(); -- GitLab