From 922b08f32bf9fcbf133bc056ea91d01a8b6cecb8 Mon Sep 17 00:00:00 2001 From: Patrick Imbo <patrick.imbo@c-s.fr> Date: Mon, 28 Aug 2006 16:30:42 +0000 Subject: [PATCH] =?UTF-8?q?CompacityPathFunction=20:=20impl=C3=A9mentation?= =?UTF-8?q?=20de=20la=20classe=20et=20des=20testing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../otbCompacityPathFunction.h | 89 +++++++++++++ .../otbCompacityPathFunction.txx | 122 ++++++++++++++++++ Testing/Code/FeatureExtraction/CMakeLists.txt | 18 +++ .../otbCompacityPathCircle.cxx | 93 +++++++++++++ .../FeatureExtraction/otbCompacityPathNew.cxx | 51 ++++++++ .../otbCompacityPathRectangle.cxx | 100 ++++++++++++++ .../otbCompacityPathSquare.cxx | 94 ++++++++++++++ .../otbFeatureExtractionTests.cxx | 4 + 8 files changed, 571 insertions(+) create mode 100644 Code/FeatureExtraction/otbCompacityPathFunction.h create mode 100644 Code/FeatureExtraction/otbCompacityPathFunction.txx create mode 100644 Testing/Code/FeatureExtraction/otbCompacityPathCircle.cxx create mode 100644 Testing/Code/FeatureExtraction/otbCompacityPathNew.cxx create mode 100644 Testing/Code/FeatureExtraction/otbCompacityPathRectangle.cxx create mode 100644 Testing/Code/FeatureExtraction/otbCompacityPathSquare.cxx diff --git a/Code/FeatureExtraction/otbCompacityPathFunction.h b/Code/FeatureExtraction/otbCompacityPathFunction.h new file mode 100644 index 0000000000..5baba7fb8d --- /dev/null +++ b/Code/FeatureExtraction/otbCompacityPathFunction.h @@ -0,0 +1,89 @@ +/*========================================================================= + + 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. + +=========================================================================*/ +#ifndef _otbCompacityPathFunction_h +#define _otbCompacityPathFunction_h + +#include "otbPathFunction.h" +#include "itkVectorContainer.h" + +namespace otb +{ + +/** + * \class CompacityPathFunction + * \brief Calculate the compacity of a path. + * The formula of the compacity is : + * \f[ compacity = Surface / Perimeter^{2} \cdot \pi \f] + * + * The path must contain at least 3 points. + * The result value is comprise between 0.0 and 1.0 + * + * \ingroup PathFunctions + */ + +template < class TInputPath, + class TOutput = double> +class ITK_EXPORT CompacityPathFunction : + public PathFunction< TInputPath, TOutput > +{ +public: + /** Standard class typedefs. */ + typedef CompacityPathFunction Self; + typedef PathFunction<TInputPath, TOutput> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(CompacityPathFunction, PathFunction); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** InputPathType typedef support. */ + typedef typename Superclass::InputPathType PathType; + typedef typename Superclass::InputPathConstPointer PathConstPointer; + typedef typename PathType::ContinuousIndexType VertexType; + typedef itk::VectorContainer< unsigned,VertexType > VertexListType; + typedef typename VertexListType::ConstPointer VertexListPointer; + typedef TOutput OutputType; + + typedef double RealType; + + + /** Evaluate the function at non-integer positions */ + virtual OutputType Evaluate( const PathType& path) const; + virtual OutputType Evaluate( ) const; + +protected: + CompacityPathFunction(){}; + ~CompacityPathFunction(){}; + void PrintSelf(std::ostream& os, itk::Indent indent) const; + +private: + CompacityPathFunction( const Self& ); //purposely not implemented + void operator=( const Self& ); //purposely not implemented + +}; + +} // namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbCompacityPathFunction.txx" +#endif + +#endif diff --git a/Code/FeatureExtraction/otbCompacityPathFunction.txx b/Code/FeatureExtraction/otbCompacityPathFunction.txx new file mode 100644 index 0000000000..d1beef6cc8 --- /dev/null +++ b/Code/FeatureExtraction/otbCompacityPathFunction.txx @@ -0,0 +1,122 @@ +/*========================================================================= + + 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. + +=========================================================================*/ +#ifndef _otbCompacityPathFunction_txx +#define _otbCompacityPathFunction_txx + +#include "otbPathFunction.h" +#include "itkNumericTraits.h" +#include "otbMacro.h" + +namespace otb +{ + +template < class TInputPath, class TOutput> +void +CompacityPathFunction< TInputPath, TOutput > +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + this->Superclass::PrintSelf(os,indent); +} + + + +template < class TInputPath, class TOutput> +typename CompacityPathFunction<TInputPath, + TOutput>::OutputType +CompacityPathFunction<TInputPath,TOutput> +::Evaluate(const PathType& path) const +{ + typedef double RealType; + + VertexListPointer vertexList; + VertexType cindex; + VertexType IndexOut; + int nbPath; + RealType Surface=0.0; + RealType Perimeter=0.0; + RealType Compacity; + RealType x1,x2,y1,y2; + + vertexList = path.GetVertexList(); + nbPath = vertexList->Size(); + + if(nbPath >2) + { + for(int i =0 ; i<nbPath ;i++) + { + cindex = vertexList->GetElement(i); + x1 = cindex[0]; + y1 = cindex[1]; + + if( i == (nbPath-1) ) + { + cindex = vertexList->GetElement(0); + } + else + { + cindex = vertexList->GetElement(i+1); + } + x2 = cindex[0]; + y2 = cindex[1]; + + RealType Norm; + + Norm = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) ); + + Perimeter += Norm; + + RealType P = x2 * (y2-y1); + RealType Q = y2 * (x2-x1); + + Surface += ( P - Q ); + } // FOR loop + } // IF loop + else + { + itkExceptionMacro(<<"CompacityPathFunction::Evaluate() FAILED -- path must contains at least 3 points"); + } + Surface /= 2.0; + + Compacity = Surface / (Perimeter * Perimeter); + Compacity *= ( 4.* acos(-1.0) ); + + return (static_cast<OutputType>(Compacity) ); + +} + +template < class TInputPath, class TOutput> +typename CompacityPathFunction<TInputPath, + TOutput>::OutputType +CompacityPathFunction<TInputPath,TOutput> +::Evaluate() const +{ + if( !this->GetInputPath() ) + { + otbMsgDevMacro( << "Problem with GetInputPath" ); + return static_cast<OutputType>(itk::NumericTraits<OutputType>::max() ); + } + + OutputType Result = Evaluate( *(this->GetInputPath()) ); + + return Result; +} + + +} // namespace otb + +#endif diff --git a/Testing/Code/FeatureExtraction/CMakeLists.txt b/Testing/Code/FeatureExtraction/CMakeLists.txt index b22d9dcb45..9acb0c6118 100755 --- a/Testing/Code/FeatureExtraction/CMakeLists.txt +++ b/Testing/Code/FeatureExtraction/CMakeLists.txt @@ -116,6 +116,20 @@ ADD_TEST(feTuOrientationPath_090 ${FEATUREEXTRACTION_TESTS} ADD_TEST(feTuOrientationPath1_80 ${FEATUREEXTRACTION_TESTS} otbOrientationPath 180.0) +# ------- otb::CompacityPathFunction ------------------------ + +ADD_TEST(feTuCompacityPathNew ${FEATUREEXTRACTION_TESTS} + otbCompacityPathNew) + +ADD_TEST(feTuCompacityPathCircle ${FEATUREEXTRACTION_TESTS} + otbCompacityPathCircle 1000) + +ADD_TEST(feTuCompacityPathSquare ${FEATUREEXTRACTION_TESTS} + otbCompacityPathSquare 10.0) + +ADD_TEST(feTuCompacityPathRectangle ${FEATUREEXTRACTION_TESTS} + otbCompacityPathRectangle 10.0 20.0) + # ------- otb::TouziEdgeDetector ------------------------------ ADD_TEST(feTuTouziNew ${FEATUREEXTRACTION_TESTS} @@ -389,6 +403,10 @@ otbFlusserPathNew.cxx otbFlusserPath.cxx otbOrientationPathNew.cxx otbOrientationPath.cxx +otbCompacityPathNew.cxx +otbCompacityPathCircle.cxx +otbCompacityPathSquare.cxx +otbCompacityPathRectangle.cxx otbTouziEdgeDetectorNew.cxx otbTouziEdgeDetector.cxx otbTouziEdgeDetectorDirection.cxx diff --git a/Testing/Code/FeatureExtraction/otbCompacityPathCircle.cxx b/Testing/Code/FeatureExtraction/otbCompacityPathCircle.cxx new file mode 100644 index 0000000000..208699f675 --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbCompacityPathCircle.cxx @@ -0,0 +1,93 @@ +/*========================================================================= + + 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. + +=========================================================================*/ + +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbCompacityPathFunction.h" +#include "itkPolyLineParametricPath.h" +#include "itkExceptionObject.h" + +int otbCompacityPathCircle( int argc, char * argv[] ) +{ + try + { + unsigned int NbOfPoints((unsigned int)::atoi(argv[1])); + + unsigned int Number; + const unsigned int Dimension = 2; + typedef itk::PolyLineParametricPath< Dimension > PathType; + typedef otb::CompacityPathFunction<PathType> FunctionType; + typedef FunctionType::RealType RealType; + + PathType::ContinuousIndexType cindex; + PathType::Pointer pathElt = PathType::New(); + + if(NbOfPoints<2) + { + std::cout << "NbOfPoints must be greater than 2 !" << std::endl; + return EXIT_FAILURE; + } + + RealType deltaTheta; + RealType Rho = 100.0; + + deltaTheta = 2.* acos(-1.0) / static_cast<RealType>(NbOfPoints); + + pathElt->Initialize(); + + for(int noTheta = 0 ; noTheta < NbOfPoints ; noTheta++) + { + RealType Theta = deltaTheta * static_cast<RealType>(noTheta); + + cindex[0]= (Rho * cos(Theta) ); + cindex[1]= (Rho * sin(Theta) ); + pathElt->AddVertex(cindex); + } + + FunctionType::Pointer function =FunctionType::New(); + function->SetInputPath( pathElt ); + + RealType Result = function->Evaluate(); + std::cout << "Compacity result: " << Result <<std::endl; + + RealType Error; + Error = fabs(Result - static_cast<RealType>(1.0) ); + + if( Error > 1.E-5) + { + std::cout << "Error in estimation !" << std::endl; + return EXIT_FAILURE; + } + + } + catch( itk::ExceptionObject & err ) + { + std::cout << "itk::ExceptionObject catch !" << std::endl; + std::cout << err << std::endl; + return EXIT_FAILURE; + } + catch( ... ) + { + std::cout << "unknown Exception catch !" << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + diff --git a/Testing/Code/FeatureExtraction/otbCompacityPathNew.cxx b/Testing/Code/FeatureExtraction/otbCompacityPathNew.cxx new file mode 100644 index 0000000000..8fbff180c8 --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbCompacityPathNew.cxx @@ -0,0 +1,51 @@ +/*========================================================================= + + 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. + +=========================================================================*/ + +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbCompacityPathFunction.h" +#include "itkPolyLineParametricPath.h" +#include "itkExceptionObject.h" + +int otbCompacityPathNew( int argc, char * argv[] ) +{ + try + { + const unsigned int Dimension = 2; + typedef itk::PolyLineParametricPath< Dimension > PathType; + typedef otb::CompacityPathFunction<PathType> FunctionType; + + FunctionType::Pointer function =FunctionType::New(); + + } + catch( itk::ExceptionObject & err ) + { + std::cout << "itk::ExceptionObject catch !" << std::endl; + std::cout << err << std::endl; + return EXIT_FAILURE; + } + catch( ... ) + { + std::cout << "Unknown exception catch !" << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + diff --git a/Testing/Code/FeatureExtraction/otbCompacityPathRectangle.cxx b/Testing/Code/FeatureExtraction/otbCompacityPathRectangle.cxx new file mode 100644 index 0000000000..4b5b9f98dc --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbCompacityPathRectangle.cxx @@ -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. + + + 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. + +=========================================================================*/ + +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbCompacityPathFunction.h" +#include "itkPolyLineParametricPath.h" +#include "itkExceptionObject.h" + +int otbCompacityPathRectangle( int argc, char * argv[] ) +{ + try + { + double A ((double)::atof(argv[1])); + double B ((double)::atof(argv[2])); + + unsigned int Number; + const unsigned int Dimension = 2; + typedef itk::PolyLineParametricPath< Dimension > PathType; + typedef otb::CompacityPathFunction<PathType> FunctionType; + typedef FunctionType::RealType RealType; + + PathType::ContinuousIndexType cindex; + PathType::Pointer pathElt = PathType::New(); + + if(A<0) + { + std::cout << "retangle must be greater than 0.0 !" << std::endl; + return EXIT_FAILURE; + } + + if(B<0) + { + std::cout << "rectangle must be greater than 0.0 !" << std::endl; + return EXIT_FAILURE; + } + + pathElt->Initialize(); + + cindex[0]= 100; + cindex[1]= 100; + pathElt->AddVertex(cindex); + cindex[0]= 100+A; + cindex[1]= 100; + pathElt->AddVertex(cindex); + cindex[0]= 100+A; + cindex[1]= 100+B; + pathElt->AddVertex(cindex); + cindex[0]= 100; + cindex[1]= 100+B; + pathElt->AddVertex(cindex); + + + FunctionType::Pointer function =FunctionType::New(); + function->SetInputPath( pathElt ); + + RealType Result = function->Evaluate(); + std::cout << "Compacity result: " << Result <<std::endl; + + RealType Error; + Error = fabs(Result - static_cast<RealType>(acos(-1.0) * A*B / (A+B) / (A+B)) ); + + if( Error > 1.E-9) + { + std::cout << "Error in estimation !" << std::endl; + return EXIT_FAILURE; + } + + } + catch( itk::ExceptionObject & err ) + { + std::cout << "itk::ExceptionObject catch !" << std::endl; + std::cout << err << std::endl; + return EXIT_FAILURE; + } + catch( ... ) + { + std::cout << "unknown Exception catch !" << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + diff --git a/Testing/Code/FeatureExtraction/otbCompacityPathSquare.cxx b/Testing/Code/FeatureExtraction/otbCompacityPathSquare.cxx new file mode 100644 index 0000000000..a1d79e0ca5 --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbCompacityPathSquare.cxx @@ -0,0 +1,94 @@ +/*========================================================================= + + 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. + +=========================================================================*/ + +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbCompacityPathFunction.h" +#include "itkPolyLineParametricPath.h" +#include "itkExceptionObject.h" + +int otbCompacityPathSquare( int argc, char * argv[] ) +{ + try + { + double A ((double)::atof(argv[1])); + + unsigned int Number; + const unsigned int Dimension = 2; + typedef itk::PolyLineParametricPath< Dimension > PathType; + typedef otb::CompacityPathFunction<PathType> FunctionType; + typedef FunctionType::RealType RealType; + + PathType::ContinuousIndexType cindex; + PathType::Pointer pathElt = PathType::New(); + + if(A<0) + { + std::cout << "square must be greater than 0.0 !" << std::endl; + return EXIT_FAILURE; + } + + + pathElt->Initialize(); + + cindex[0]= 100; + cindex[1]= 100; + pathElt->AddVertex(cindex); + cindex[0]= 100+A; + cindex[1]= 100; + pathElt->AddVertex(cindex); + cindex[0]= 100+A; + cindex[1]= 100+A; + pathElt->AddVertex(cindex); + cindex[0]= 100; + cindex[1]= 100+A; + pathElt->AddVertex(cindex); + + + FunctionType::Pointer function =FunctionType::New(); + function->SetInputPath( pathElt ); + + RealType Result = function->Evaluate(); + std::cout << "Compacity result: " << Result <<std::endl; + + RealType Error; + Error = fabs(Result - static_cast<RealType>(acos(-1.0)/4.) ); + + if( Error > 1.E-9) + { + std::cout << "Error in Theta estimation :" << std::endl; + return EXIT_FAILURE; + } + + } + catch( itk::ExceptionObject & err ) + { + std::cout << "itk::ExceptionObject catch !" << std::endl; + std::cout << err << std::endl; + return EXIT_FAILURE; + } + catch( ... ) + { + std::cout << "unknown Exception catch !" << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + diff --git a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests.cxx b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests.cxx index 6b72909562..3387db6797 100755 --- a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests.cxx +++ b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests.cxx @@ -44,6 +44,10 @@ REGISTER_TEST(otbFlusserPathNew); REGISTER_TEST(otbFlusserPath); REGISTER_TEST(otbOrientationPathNew); REGISTER_TEST(otbOrientationPath); +REGISTER_TEST(otbCompacityPathNew); +REGISTER_TEST(otbCompacityPathCircle); +REGISTER_TEST(otbCompacityPathSquare); +REGISTER_TEST(otbCompacityPathRectangle); REGISTER_TEST(otbTouziEdgeDetectorNew); REGISTER_TEST(otbTouziEdgeDetector); REGISTER_TEST(otbTouziEdgeDetectorDirection); -- GitLab