diff --git a/Code/FeatureExtraction/otbCompacityPathFunction.h b/Code/FeatureExtraction/otbCompacityPathFunction.h new file mode 100644 index 0000000000000000000000000000000000000000..5baba7fb8d8c0d8be464970497fdf1a677cb9c74 --- /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 0000000000000000000000000000000000000000..d1beef6cc8acf300a3e186fbde786b5d94d127b5 --- /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 b22d9dcb456b8de27d216dc24150854860e9a2ed..9acb0c6118fe6f0bb5c6f58684f3305011b589fc 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 0000000000000000000000000000000000000000..208699f675a50839efad287a2cb10c976d5a85c4 --- /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 0000000000000000000000000000000000000000..8fbff180c8b8833ab442e3c647dbf80c32263fdc --- /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 0000000000000000000000000000000000000000..4b5b9f98dc80a32f9a98ccbdea2bfdb2ddecb8db --- /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 0000000000000000000000000000000000000000..a1d79e0ca5275abb7e2a752fdc06072a94095f16 --- /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 6b72909562447ef2a287688f194762285cc82369..3387db67978f841e743c108a40a8c3d50963d65a 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);