diff --git a/Code/BasicFilters/otbPolygonCompacityFunctor.h b/Code/BasicFilters/otbPolygonCompacityFunctor.h index 3f667bc141d421980da8e83fe3a662c9d944a886..20e4fb3b6156f4d9bf3dbcf7526a3e60c9a981c9 100644 --- a/Code/BasicFilters/otbPolygonCompacityFunctor.h +++ b/Code/BasicFilters/otbPolygonCompacityFunctor.h @@ -61,7 +61,7 @@ public: inline bool operator()(const TInput1 & input) { - double circularityRatio = 4*M_PI*input->GetSurface() + double circularityRatio = 4*M_PI*input->GetArea() / M_SQUARE(input->GetLength()); if (circularityRatio > m_Threshold) diff --git a/Code/Common/otbPolygon.h b/Code/Common/otbPolygon.h index 3c2faa615631bf2020db1694a5cbe8c030440fb2..853f265b4412cf34d621436adaecb1c606134126 100644 --- a/Code/Common/otbPolygon.h +++ b/Code/Common/otbPolygon.h @@ -126,7 +126,7 @@ public: * Return the polygon surface. * \return The surface. */ - double GetSurface() const; + double GetArea() const; /** * Return the polygon length (perimeter). @@ -134,11 +134,16 @@ public: */ virtual double GetLength() const; + + void AddVertex (const ContinuousIndexType &vertex); + protected: /** Constructor */ Polygon() { m_Epsilon = 0.000001; + m_Area = -1.0; + m_AreaIsValid = false; }; /** Destructor */ @@ -147,12 +152,15 @@ protected: /**PrintSelf method */ virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; + virtual void ComputeArea() const; private: Polygon(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented double m_Epsilon; + mutable double m_Area; + mutable bool m_AreaIsValid; }; }// End namespace otb diff --git a/Code/Common/otbPolygon.txx b/Code/Common/otbPolygon.txx index a6e73e9dd913f5f1f372e5f4f4c75881682e8bec..0cdeab82a177cec3a09e7953d614c0f95876767a 100644 --- a/Code/Common/otbPolygon.txx +++ b/Code/Common/otbPolygon.txx @@ -22,6 +22,16 @@ PURPOSE. See the above copyright notices for more information. namespace otb { + +template<class TValue> +void +Polygon<TValue> +::AddVertex(const ContinuousIndexType &vertex) +{ + Superclass::AddVertex(vertex); + m_AreaIsValid=false; +} + /** * Check wether point is strictly inside the polygon. * \param point The point to check. @@ -475,19 +485,18 @@ Polygon<TValue> /** - * Surface computation (for non convex polygons as well) + * Area computation (for non convex polygons as well) */ template<class TValue> -double +void Polygon<TValue> -::GetSurface() const +::ComputeArea() const { - double m_Surface; - m_Surface = 0.0; VertexListConstIteratorType it = this->GetVertexList()->Begin(); if (this->GetVertexList()->Size()>2) { + double area=0.0; VertexType origin = it.Value(); it++; VertexType pt1 = it.Value(); @@ -503,21 +512,37 @@ Polygon<TValue> double vector2x = pt2[0] - origin[0]; double vector2y = pt2[1] - origin[1]; double crossProdduct = vector1x*vector2y - vector2x*vector1y; - m_Surface += crossProdduct; + area += crossProdduct; it++; } - m_Surface = fabs(m_Surface/2.0); + m_Area = fabs(area/2.0); } else //if there is strictly less than 3 points, surface is 0 { - m_Surface = 0.0; + m_Area = 0.0; } - return m_Surface; + m_AreaIsValid = true; } +/** + * Get surface + */ +template<class TValue> + double + Polygon<TValue> + ::GetArea() const +{ + if (!m_AreaIsValid) + { + ComputeArea(); + } + return m_Area; +} + + /** * Lenght computation (difference with path is in the last addition) */ diff --git a/Code/FeatureExtraction/otbAngularSecondMomentumTextureFunctor.h b/Code/FeatureExtraction/otbAngularSecondMomentumTextureFunctor.h index dc73d666c079a0f1158602e228b25f201dbcf3b4..377ba08ae0f19b57e5c39b9ffcb73a4ffe67df92 100644 --- a/Code/FeatureExtraction/otbAngularSecondMomentumTextureFunctor.h +++ b/Code/FeatureExtraction/otbAngularSecondMomentumTextureFunctor.h @@ -18,7 +18,7 @@ #ifndef __otbAngularSecondMomentumTextureFunctor_h #define __otbAngularSecondMomentumTextureFunctor_h -#include "otbEntropyTextureFunctor.h" +#include "otbTextureFunctorBase.h" namespace otb { @@ -39,7 +39,7 @@ namespace Functor */ template <class TIterInput1, class TIterInput2, class TOutput> class ITK_EXPORT AngularSecondMomentumTextureFunctor : -public EntropyTextureFunctor<TIterInput1, TIterInput2, TOutput> +public TextureFunctorBase<TIterInput1, TIterInput2, TOutput> { public: AngularSecondMomentumTextureFunctor(){}; @@ -56,12 +56,11 @@ public: typedef std::vector<double> DoubleVectorType; typedef std::vector<int> IntVectorType; typedef std::vector<IntVectorType> IntVectorVectorType; - typedef EntropyTextureFunctor<TIterInput1, TIterInput2, TOutput> Superclass; virtual double ComputeOverSingleChannel(const NeighborhoodType &neigh, const NeighborhoodType &neighOff) { - DoubleVectorType binsLength = Superclass::StatComputation(neigh, neighOff); + DoubleVectorType binsLength = this->StatComputation(neigh, neighOff); RadiusType radius = neigh.GetRadius(); double area = static_cast<double>(neigh.GetSize()[0]*neigh.GetSize()[1]); diff --git a/Code/FeatureExtraction/otbContrastTextureFunctor.h b/Code/FeatureExtraction/otbContrastTextureFunctor.h index ca9003288c52438fbef8a6d9e8ee9a1c503407e4..8e508bc525b542f77a4ba2abb75265d3d915e23a 100644 --- a/Code/FeatureExtraction/otbContrastTextureFunctor.h +++ b/Code/FeatureExtraction/otbContrastTextureFunctor.h @@ -18,7 +18,7 @@ #ifndef __otbContrastTextureFunctor_h #define __otbContrastTextureFunctor_h -#include "otbEntropyTextureFunctor.h" +#include "otbTextureFunctorBase.h" namespace otb { @@ -39,7 +39,7 @@ namespace Functor */ template <class TIterInput1, class TIterInput2, class TOutput> class ITK_EXPORT ContrastTextureFunctor : -public EntropyTextureFunctor<TIterInput1, TIterInput2, TOutput> +public TextureFunctorBase<TIterInput1, TIterInput2, TOutput> { public: ContrastTextureFunctor(){}; @@ -56,12 +56,11 @@ public: typedef std::vector<double> DoubleVectorType; typedef std::vector<int> IntVectorType; typedef std::vector<IntVectorType> IntVectorVectorType; - typedef EntropyTextureFunctor<TIterInput1, TIterInput2, TOutput> Superclass; virtual double ComputeOverSingleChannel(const NeighborhoodType &neigh, const NeighborhoodType &neighOff) { - DoubleVectorType binsLength = Superclass::StatComputation(neigh, neighOff); + DoubleVectorType binsLength = this->StatComputation(neigh, neighOff); RadiusType radius = neigh.GetRadius(); double area = static_cast<double>(neigh.GetSize()[0]*neigh.GetSize()[1]); @@ -121,7 +120,7 @@ public: double rVal = (static_cast<double>(r)+0.5)*binsLength[1]; for (unsigned s = 0; s<histo[r].size(); s++) { - if( vcl_abs( rVal - (static_cast<double>(s)+0.5)*binsLength[0]) < nCeil ) + if( vcl_abs( rVal - (static_cast<double>(s)+0.5)*binsLength[0] - nCeil) < vcl_abs(binsLength[0]-binsLength[1]) ) { double p = static_cast<double>(histo[r][s])*areaInv; out += nCeilSquare * p; @@ -130,14 +129,13 @@ public: } } - return out; } }; - + } // namespace Functor } // namespace otb diff --git a/Code/FeatureExtraction/otbCorrelationTextureFunctor.h b/Code/FeatureExtraction/otbCorrelationTextureFunctor.h index b9d8dfbace265e6f00398cb05a113ef27b6b1b8e..16ec51d9d848cbf7a110a82167f5ca00c6862b8c 100644 --- a/Code/FeatureExtraction/otbCorrelationTextureFunctor.h +++ b/Code/FeatureExtraction/otbCorrelationTextureFunctor.h @@ -18,7 +18,7 @@ #ifndef __otbCorrelationTextureFunctor_h #define __otbCorrelationTextureFunctor_h -#include "otbEntropyTextureFunctor.h" +#include "otbTextureFunctorBase.h" namespace otb { @@ -39,7 +39,7 @@ namespace Functor */ template <class TIterInput1, class TIterInput2, class TOutput> class ITK_EXPORT CorrelationTextureFunctor : -public EntropyTextureFunctor<TIterInput1, TIterInput2, TOutput> +public TextureFunctorBase<TIterInput1, TIterInput2, TOutput> { public: CorrelationTextureFunctor(){}; @@ -56,12 +56,11 @@ public: typedef std::vector<double> DoubleVectorType; typedef std::vector<int> IntVectorType; typedef std::vector<IntVectorType> IntVectorVectorType; - typedef EntropyTextureFunctor<TIterInput1, TIterInput2, TOutput> Superclass; virtual double ComputeOverSingleChannel(const NeighborhoodType &neigh, const NeighborhoodType &neighOff) { - DoubleVectorType binsLength = Superclass::StatComputation(neigh, neighOff); + DoubleVectorType binsLength = this->StatComputation(neigh, neighOff); RadiusType radius = neigh.GetRadius(); double area = static_cast<double>(neigh.GetSize()[0]*neigh.GetSize()[1]); diff --git a/Code/FeatureExtraction/otbDifferenceEntropyTextureFunctor.h b/Code/FeatureExtraction/otbDifferenceEntropyTextureFunctor.h new file mode 100644 index 0000000000000000000000000000000000000000..a61f5be5c0f1c37d19c97486115bf21462ae36f8 --- /dev/null +++ b/Code/FeatureExtraction/otbDifferenceEntropyTextureFunctor.h @@ -0,0 +1,145 @@ +/*========================================================================= + + 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 __otbDifferenceEntropyTextureFunctor_h +#define __otbDifferenceEntropyTextureFunctor_h + +#include "otbTextureFunctorBase.h" + +namespace otb +{ +namespace Functor +{ +/** \class DifferenceEntropyTextureFunctor + * \brief This functor calculates the inverse difference moment of an image + * + * Computes joint histogram (neighborhood and offset neighborhood) + * which bins are computing using Scott formula. + * Computes the probabiltiy p for each pair of pixel. + * InverseDifferenceMoment is the sum 1/(1+(pi-poff)²)*p over the neighborhood. + * TIterInput is an ietrator, TOutput is a PixelType. + * + * \ingroup Functor + * \ingroup + * \ingroup Statistics + */ +template <class TIterInput1, class TIterInput2, class TOutput> +class ITK_EXPORT DifferenceEntropyTextureFunctor : +public TextureFunctorBase<TIterInput1, TIterInput2, TOutput> +{ +public: + DifferenceEntropyTextureFunctor(){}; + ~DifferenceEntropyTextureFunctor(){}; + + typedef TIterInput1 IterType1; + typedef TIterInput2 IterType2; + typedef TOutput OutputType; + typedef typename IterType1::OffsetType OffsetType; + typedef typename IterType1::RadiusType RadiusType; + typedef typename IterType1::InternalPixelType InternalPixelType; + typedef typename IterType1::ImageType ImageType; + typedef itk::Neighborhood<InternalPixelType,::itk::GetImageDimension<ImageType>::ImageDimension> NeighborhoodType; + typedef std::vector<double> DoubleVectorType; + typedef std::vector<int> IntVectorType; + typedef std::vector<IntVectorType> IntVectorVectorType; + + + virtual double ComputeOverSingleChannel(const NeighborhoodType &neigh, const NeighborhoodType &neighOff) + { + DoubleVectorType binsLength = this->StatComputation(neigh, neighOff); + + RadiusType radius = neigh.GetRadius(); + double area = static_cast<double>(neigh.GetSize()[0]*neigh.GetSize()[1]); + double areaInv = 1/area; + OffsetType offset; + offset.Fill(0); + OffsetType offsetOff; + OffsetType offsetOffInit; + + offsetOffInit[0] = -radius[0]+this->GetOffset()[0]-1; + offsetOffInit[1] = -radius[1]+this->GetOffset()[1]-1; + + int histoIdX = 0; + int histoIdY = 0; + double out = 0.; + + IntVectorType histoTemp; + IntVectorVectorType histo; + if (binsLength[0] != 0) + histoTemp = IntVectorType( vcl_floor( static_cast<double>(this->GetMaxi()-this->GetMini())/binsLength[0])+1., 0); + else + histoTemp = IntVectorType( 1, 0 ); + + if (binsLength[1] != 0) + histo = IntVectorVectorType( vcl_floor(static_cast<double>(this->GetMaxiOff()-this->GetMiniOff())/binsLength[1])+1., histoTemp ); + else + histo = IntVectorVectorType( 1, histoTemp ); + + offsetOff = offsetOffInit; + for ( int l = -static_cast<int>(radius[0]); l <= static_cast<int>(radius[0]); l++ ) + { + offsetOff[0]++; + offsetOff[1] = offsetOffInit[1]; + offset[0] = l; + for ( int k = -static_cast<int>(radius[1]); k <= static_cast<int>(radius[1]); k++) + { + offsetOff[1]++; + offset[1] = k; + histoIdX = 0; + histoIdY = 0; + if ( binsLength[1] != 0) + histoIdX = static_cast<int>(vcl_floor( (static_cast<double>(neighOff[offsetOff])-this->GetMiniOff()) / static_cast<double>(binsLength[1]) )); + if ( binsLength[0] !=0 ) + histoIdY = static_cast<int>(vcl_floor( (static_cast<double>(neigh[offset])-this->GetMini()) /static_cast<double>( binsLength[0]) )); + + histo[histoIdX][histoIdY]++; + + } + } + // loop over bin neighborhood values + for (unsigned sB = 0; sB<histo[0].size(); sB++) + { + double Px_y = 0.; + double nCeil = (static_cast<double>(sB)+0.5)*binsLength[0]; + double nCeilSquare = vcl_pow( nCeil, 2); + for (unsigned r = 0; r<histo.size(); r++) + { + double rVal = (static_cast<double>(r)+0.5)*binsLength[1]; + for (unsigned s = 0; s<histo[r].size(); s++) + { + if( vcl_abs( rVal - (static_cast<double>(s)+0.5)*binsLength[0] - nCeil ) < vcl_abs( binsLength[0]+binsLength[1]) ) + { + Px_y += static_cast<double>(histo[r][s])*areaInv; + } + } + } + if(Px_y != 0.) + out += Px_y * nCeil * vcl_log(Px_y); + } + + + return out; + } + +}; + + +} // namespace Functor +} // namespace otb + +#endif + diff --git a/Code/FeatureExtraction/otbEnergyTextureFunctor.h b/Code/FeatureExtraction/otbEnergyTextureFunctor.h index 8d907fb25b500af523a6829c5027742fd33605a5..64cea3216537f8fd61edf14dba1667ce4b1c9e79 100644 --- a/Code/FeatureExtraction/otbEnergyTextureFunctor.h +++ b/Code/FeatureExtraction/otbEnergyTextureFunctor.h @@ -18,7 +18,6 @@ #ifndef __otbEnergyTextureFunctor_h #define __otbEnergyTextureFunctor_h - #include "otbTextureFunctorBase.h" diff --git a/Code/FeatureExtraction/otbInverseDifferenceMomentTextureFunctor.h b/Code/FeatureExtraction/otbInverseDifferenceMomentTextureFunctor.h index 680c51966f60c9205aafa84b4102db7e50331202..6387738532f22f0c5e1cf6b29645065085bd2eb5 100644 --- a/Code/FeatureExtraction/otbInverseDifferenceMomentTextureFunctor.h +++ b/Code/FeatureExtraction/otbInverseDifferenceMomentTextureFunctor.h @@ -18,7 +18,7 @@ #ifndef __otbInverseDifferenceMomentTextureFunctor_h #define __otbInverseDifferenceMomentTextureFunctor_h -#include "otbEntropyTextureFunctor.h" +#include "otbTextureFunctorBase.h" namespace otb { @@ -39,7 +39,7 @@ namespace Functor */ template <class TIterInput1, class TIterInput2, class TOutput> class ITK_EXPORT InverseDifferenceMomentTextureFunctor : -public EntropyTextureFunctor<TIterInput1, TIterInput2, TOutput> +public TextureFunctorBase<TIterInput1, TIterInput2, TOutput> { public: InverseDifferenceMomentTextureFunctor(){}; @@ -56,12 +56,11 @@ public: typedef std::vector<double> DoubleVectorType; typedef std::vector<int> IntVectorType; typedef std::vector<IntVectorType> IntVectorVectorType; - typedef EntropyTextureFunctor<TIterInput1, TIterInput2, TOutput> Superclass; virtual double ComputeOverSingleChannel(const NeighborhoodType &neigh, const NeighborhoodType &neighOff) { - DoubleVectorType binsLength = Superclass::StatComputation(neigh, neighOff); + DoubleVectorType binsLength = this->StatComputation(neigh, neighOff); RadiusType radius = neigh.GetRadius(); double area = static_cast<double>(neigh.GetSize()[0]*neigh.GetSize()[1]); diff --git a/Code/FeatureExtraction/otbLineSegmentDetector.h b/Code/FeatureExtraction/otbLineSegmentDetector.h new file mode 100644 index 0000000000000000000000000000000000000000..c63c48422b5afb4806e1313e7f8caf0a95b34652 --- /dev/null +++ b/Code/FeatureExtraction/otbLineSegmentDetector.h @@ -0,0 +1,251 @@ +/*========================================================================= + + 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 __otbLineSegmentDetector_h +#define __otbLineSegmentDetector_h + + +#include "otbImageToLineSpatialObjectListFilter.h" +#include "otbLineSpatialObjectList.h" +#include "otbImage.h" +#include "itkPointSet.h" + +#include "itkUnaryFunctorImageFilter.h" +#include "itkGradientImageFilter.h" + +namespace otb +{ + +namespace Functor + { + /** \class MagnitudeFunctor + * \brief This functor computes the magnitude of a covariant vector. + */ + template <class TInputPixel,class TOutputPixel> + class MagnitudeFunctor + { + public: + + inline TOutputPixel operator()(const TInputPixel& input) + { + return vcl_sqrt((input[0]+input[1])*(input[0]+input[1]) +(input[0]*input[1])*(input[0]*input[1]) ); + } + }; + + /** \class OrientationFunctor + * \brief This functor computes the orientation of a cavariant vector<br> + * Orientation values lies between 0 and 2*Pi. + */ + template <class TInputPixel,class TOutputPixel> + class OrientationFunctor + { + public: + + inline TOutputPixel operator()(const TInputPixel& input) + { + TOutputPixel resp = vcl_atan2(input[1],-input[0]); +/* if (resp<0) */ +/* { */ +/* resp+=2*M_PI; */ +/* } */ + + return resp; + } + }; + }// end namespace Functor +/** \class LineSegmentDetector + * \brief this class implement a fast line detector with false detection control + * + * + * + */ + +template <class TInputImage,class TPrecision> +class ITK_EXPORT LineSegmentDetector : + public otb::ImageToLineSpatialObjectListFilter< TInputImage > +{ +public: + + /** typedef for the classes standards. */ + typedef LineSegmentDetector Self; + typedef ImageToLineSpatialObjectListFilter< TInputImage> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Method for management of the object factory. */ + itkNewMacro(Self); + + /** Return the name of the class. */ + itkTypeMacro(LineSegmentDetector,ImageToLineSpatialObjectListFilter ); + + /** Definition of the input image and the output ObjectList*/ + typedef TInputImage InputImageType; + typedef typename InputImageType::PixelType InputPixelType; + typedef typename InputImageType::IndexType InputIndexType; + typedef typename InputImageType::SizeType SizeType; + + /** Definition of the list of lines. */ + typedef LineSpatialObjectList LineSpatialObjectListType; + typedef LineSpatialObjectListType::Pointer LineSpatialObjectListPointer; + typedef LineSpatialObjectListType::LineType LineSpatialObjectType; + typedef LineSpatialObjectType::PointListType PointListType; + typedef LineSpatialObjectType::LinePointType PointType; + + + /** Definition of temporary image ised to store LABELS*/ + typedef otb::Image<TPrecision ,2> OutputImageType; + typedef typename OutputImageType::PixelType OutputPixelType; + typedef typename OutputImageType::IndexType OutputIndexType; + typedef typename OutputImageType::SizeType OutputSizeType; + + /** Histogram to store the coordinate of ordered pixels*/ + typedef std::vector<OutputIndexType> IndexVectorType; + typedef typename IndexVectorType::iterator IndexVectorIteratorType; + typedef std::vector<IndexVectorType > CoordinateHistogramType; + typedef typename CoordinateHistogramType::iterator CoordinateHistogramIteratorType; + + + /** typedef structure to store REGION*/ + typedef std::vector<IndexVectorType> VectorOfIndexVectorType; + typedef std::vector<float> DirectionVectorType; + typedef typename DirectionVectorType::iterator DirectionVectorIteratorType; + + /** */ + typedef itk::GradientImageFilter<InputImageType,InputPixelType,InputPixelType > GradientFilterType; + typedef typename GradientFilterType::Pointer GradientFilterPointerType; + typedef typename GradientFilterType::OutputImageType GradientOutputImageType; + + + typedef itk::UnaryFunctorImageFilter<GradientOutputImageType,InputImageType, + Functor::MagnitudeFunctor<typename GradientOutputImageType::PixelType,typename InputImageType::PixelType> > MagnitudeFilterType; + typedef typename MagnitudeFilterType::Pointer MagnitudeFilterPointerType; + typedef typename MagnitudeFilterType::OutputImageType::PixelType MagnitudePixelType; + + typedef itk::UnaryFunctorImageFilter<GradientOutputImageType,InputImageType, + Functor::OrientationFunctor<typename GradientOutputImageType::PixelType,typename InputImageType::PixelType> > OrientationFilterType; + typedef typename OrientationFilterType::Pointer OrientationFilterPointerType; + typedef typename OrientationFilterType::OutputImageType OutputImageDirType; + typedef typename OutputImageDirType::RegionType OutputImageDirRegionType ; + + /** Create an image to store the label USED(1) or notUsed (0)*/ + typedef otb::Image<unsigned char, 2> LabelImageType; + typedef typename LabelImageType::Pointer LabelImagePointerType; + + /** Vector to store the rectangle characteization center, width, orientation ,( begin ,end ) of the central line*/ + typedef std::vector<float> RectangleType; + typedef typename RectangleType::iterator RectangleIteratorType; + typedef std::vector< RectangleType> RectangleListType; + typedef typename RectangleListType::iterator RectangleListTypeIterator; +protected: + LineSegmentDetector(); + virtual ~LineSegmentDetector() {}; + + /** Generate Data method*/ + virtual void GenerateData(); + + /** Sort the image and store the coordinates in a histogram + * this method is used to determine the seeds where to begin the search segments + * Points with large gradient modulus are more able to belong to a segment + */ + virtual CoordinateHistogramType SortImageByModulusValue(OutputImageType * modulusImage); + + /** */ + virtual void LineSegmentDetection(CoordinateHistogramType * CoordinateHistogram); + + /** */ + virtual bool IsUsed(InputIndexType index); + + /** Set Pixel flag to USED*/ + virtual void SetPixelToUsed(InputIndexType index); + + + /** search for a segment which begins from a seed "index "*/ + virtual void GrowRegion(InputIndexType index); + + /** Define if two are aligned */ + virtual bool IsAligned(float Angle, float regionAngle, float prec); + + /** For each region of the region List it builds a rectangle */ + virtual int ComputeRectangles(); + + /** */ + virtual void Region2Rect(IndexVectorType region , float angleRegion); + + /** */ + virtual float ComputeRegionOrientation(IndexVectorType region , float x, float y , float angleRegion); + + /** */ + virtual float angle_diff(float a, float b); + + /** Compute the Number Of False Alarm for a rectangle*/ + virtual float ComputeRectNFA(RectangleType rec); + + /** */ + virtual float ImproveRectangle(RectangleType * rec , float NFA); + + /** NFA For a rectangle*/ + virtual float NFA(int n, int k, double p, double logNT); + + /** Create a copy of a rectangle*/ + virtual void CopyRectangle(RectangleType * rDst , RectangleType *rSrc ); + + + /** Rutines from numerical recipies*/ + virtual float betacf(float a, float b, float x); + virtual float gammln(float xx); + virtual float betai(float a, float b, float x); + virtual float factln(int n); + + /** Printself method*/ + void PrintSelf(std::ostream& os, itk::Indent indent) const; + +private: + LineSegmentDetector(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + VectorOfIndexVectorType m_RegionList; + DirectionVectorType m_DirectionVector; + LabelImagePointerType m_UsedPointImage; + RectangleListType m_RectangleList; + + float m_Threshold; + unsigned int m_MinimumRegionSize; + unsigned int m_NumberOfImagePixels; + + /** Gradient filter */ + GradientFilterPointerType m_GradientFilter; + + /** Magnitude filter */ + MagnitudeFilterPointerType m_MagnitudeFilter; + + /** Orientation filter */ + OrientationFilterPointerType m_OrientationFilter; + + /** Output*/ + LineSpatialObjectListPointer m_LineList; + + +}; +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbLineSegmentDetector.txx" +#endif + + +#endif + diff --git a/Code/FeatureExtraction/otbLineSegmentDetector.txx b/Code/FeatureExtraction/otbLineSegmentDetector.txx new file mode 100644 index 0000000000000000000000000000000000000000..9e2fc7ee75715d55b1d655f547bd5115cfbe3a58 --- /dev/null +++ b/Code/FeatureExtraction/otbLineSegmentDetector.txx @@ -0,0 +1,969 @@ +/*========================================================================= + + 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 __otbLineSegmentDetector_txx +#define __otbLineSegmentDetector_txx + +#include "otbLineSegmentDetector.h" +#include "itkImageRegionIterator.h" +#include "itkNumericTraits.h" +#include "itkMinimumMaximumImageCalculator.h" +#include "itkConstNeighborhoodIterator.h" +#include "otbPolygon.h" + +#include "otbMath.h" + +#include "itkMatrix.h" +#include "itkSymmetricEigenAnalysis.h" + +#define MAXIT 100 +#define EPS 3.0e-7 +#define FPMIN 1.0e-30 + +namespace otb +{ + +/** + * + */ +template <class TInputImage, class TPrecision> +LineSegmentDetector<TInputImage,TPrecision > +::LineSegmentDetector() +{ + m_Threshold = 2.; + + /** Compute the modulus and the orientation gradient images */ + m_GradientFilter = GradientFilterType::New(); + m_MagnitudeFilter = MagnitudeFilterType::New(); + m_OrientationFilter = OrientationFilterType::New(); + + /** */ + m_UsedPointImage = LabelImageType::New(); + + /** */ + LineSpatialObjectListType::Pointer m_LineList = LineSpatialObjectListType::New(); +} + + +/** + * + */ + +template <class TInputImage, class TPrecision > +void +LineSegmentDetector<TInputImage,TPrecision > +::GenerateData() +{ + /** The Output*/ + m_LineList = this->GetOutput(); + + /** Allocate memory for the temporary label Image*/ + m_UsedPointImage->SetRegions(this->GetInput()->GetRequestedRegion()); + m_UsedPointImage->Allocate(); + m_UsedPointImage->FillBuffer(0); + + /** Compute the modulus and the orientation gradient image*/ + m_GradientFilter->SetInput(this->GetInput()); + m_MagnitudeFilter->SetInput(m_GradientFilter->GetOutput()); + m_OrientationFilter->SetInput(m_GradientFilter->GetOutput()); + m_MagnitudeFilter->Update(); + m_OrientationFilter->Update(); + + /** Comupute the seed histogram to begin the search*/ + CoordinateHistogramType CoordinateHistogram; + CoordinateHistogram = this->SortImageByModulusValue(m_MagnitudeFilter->GetOutput()); + + /** Serach the segments on the image by growing a region from a seed */ + this->LineSegmentDetection(&CoordinateHistogram); + + /** + * Compute The rectangles + * Out : a List of rectangles : m_RectangleList + * + */ + this->ComputeRectangles(); + +} + +/**************************************************************************************************************/ +/** + * + */ + +template <class TInputImage, class TPrecision > +typename LineSegmentDetector<TInputImage,TPrecision > +::CoordinateHistogramType +LineSegmentDetector<TInputImage,TPrecision > +::SortImageByModulusValue(OutputImageType * modulusImage) +{ + /* Size of the images **/ + SizeType SizeInput = this->GetInput()->GetRequestedRegion().GetSize(); + m_NumberOfImagePixels = SizeInput[0]*SizeInput[1]; + + /** Define constants + * prec = M_PI/8 : 8 is the number off direction allowed + * p =1/8 + */ + float logNT = 5.*(vcl_log10(static_cast<float>(SizeInput[0])) + vcl_log10(static_cast<float>(SizeInput[1])))/2.; + float log1_p = vcl_log10(0.125); + float rapport = logNT/log1_p; + m_MinimumRegionSize = -1*static_cast<unsigned int>(rapport); + + + /** Definition of the min & the max of an image*/ + OutputPixelType min = itk::NumericTraits<MagnitudePixelType >::Zero; + OutputPixelType max = itk::NumericTraits<MagnitudePixelType >::Zero; + + /** Computing the min & max of the image*/ + typedef itk::MinimumMaximumImageCalculator<OutputImageType> MinMaxCalculatorFilter; + typename MinMaxCalculatorFilter::Pointer minmaxCalculator = MinMaxCalculatorFilter::New(); + + minmaxCalculator->SetImage(modulusImage); + minmaxCalculator->ComputeMinimum(); + min = minmaxCalculator->GetMinimum(); + minmaxCalculator->ComputeMaximum(); + max = minmaxCalculator->GetMaximum(); + + /** Compute the threshold on the gradient*/ + float d = 8.; // d : the number of allowed directions + m_Threshold = 4*m_Threshold /vcl_sin(M_PI/d)*((max-min)/255.); // threshold normalized with min & max of the values + + /** Computing the length of the bins*/ + unsigned int NbBin = 10; + MagnitudePixelType lengthBin = (max - min)/static_cast<MagnitudePixelType>(NbBin-1) ; + CoordinateHistogramType tempHisto(NbBin); /** Initializing the histogram */ + + + itk::ImageRegionIterator<OutputImageType> it(modulusImage, + modulusImage->GetRequestedRegion()); + + //std::cout << "min "<< min<< " max " << max << " lengthBin " << lengthBin << " et thresh" << m_Threshold << std::endl; + it.GoToBegin(); + while(!it.IsAtEnd()) + { + OutputIndexType index = it.GetIndex(); + if(static_cast<unsigned int>(index[0]) > 0 && static_cast<unsigned int>(index[1]) <SizeInput[0]-1 + && static_cast<unsigned int>(index[1]) >0 && static_cast<unsigned int>(index[1]) <SizeInput[1]-1 ) + { + unsigned int bin = static_cast<unsigned int> (it.Value()/lengthBin); + if( it.Value()- m_Threshold >1e-10 ) + tempHisto[NbBin-bin-1].push_back(it.GetIndex()); + } + ++it; + } + + return tempHisto; +} + +/**************************************************************************************************************/ +/** + * Method used to search the segments + */ + +template <class TInputImage, class TPrecision > +void +LineSegmentDetector<TInputImage, TPrecision> +::LineSegmentDetection(CoordinateHistogramType *CoordinateHistogram) +{ + + /** Begin the search of the segments*/ + CoordinateHistogramIteratorType ItCoordinateList = CoordinateHistogram->begin(); + + while(ItCoordinateList != CoordinateHistogram->end()) + { + typename IndexVectorType::iterator ItIndexVector = (*ItCoordinateList).begin(); + while(ItIndexVector != (*ItCoordinateList).end()) + { + InputIndexType index = *ItIndexVector; + + /** If the point is not yet computed */ + if(!this->IsUsed(index)) + { + this->GrowRegion(index); + } + ++ItIndexVector; + } + ++ItCoordinateList; + } + +} + +/**************************************************************************************************************/ +/** + * Method used to compute rectangles from region + * Here you can access the NFA for each region + */ +template <class TInputImage, class TPrecision > +int +LineSegmentDetector<TInputImage, TPrecision> +::ComputeRectangles() +{ + /** Check the size of the region list */ + unsigned int sizeRegion = m_RegionList.size(); + if(sizeRegion ==0) + return EXIT_FAILURE; + + /** Compute the rectangle*/ + CoordinateHistogramIteratorType ItRegion = m_RegionList.begin(); + DirectionVectorIteratorType ItDir = m_DirectionVector.begin(); + std::cout << " NB DE REGIONS : "<< m_RegionList.size()<< std::endl; + + while(ItRegion != m_RegionList.end() && ItDir !=m_DirectionVector.end() ) + { + + this->Region2Rect(*ItRegion, *ItDir ); + ++ItRegion; + ++ItDir; + } + + /** Improve the rectangles & store the lines*/ + RectangleListTypeIterator itRec = m_RectangleList.begin(); + while(itRec != m_RectangleList.end()) + { + float NFA = this->ComputeRectNFA(*itRec); + //float NFAImproved = this->ImproveRectangle(&(*itRec) , NFA); + /** + * Here we start building the OUTPUT :a LineSpatialObjectList. + */ + if(NFA > 0./** eps */) + { + //std::cout << (*itRec)[0] << " " << (*itRec)[1] << " " << (*itRec)[2] << " " << (*itRec)[3]<<std::endl; + PointListType pointList; + PointType point; + + point.SetPosition((*itRec)[0],(*itRec)[1]); + pointList.push_back(point); + point.SetPosition((*itRec)[2],(*itRec)[3]); + pointList.push_back(point); + + typename LineSpatialObjectType::Pointer line = LineSpatialObjectType::New(); + line->SetId(0); + line->SetPoints( pointList ); + line->ComputeBoundingBox(); + m_LineList->push_back(line); + pointList.clear(); + } + + ++itRec; + } + + + return EXIT_SUCCESS; +} + +/**************************************************************************************************************/ +/** + * + */ +template <class TInputImage, class TPrecision > +void +LineSegmentDetector<TInputImage, TPrecision> +::CopyRectangle(RectangleType * rDst , RectangleType *rSrc ) +{ + RectangleIteratorType itSrc = (*rSrc).begin(); + + while(itSrc != (*rSrc).end()) + { + (*rDst).push_back(*itSrc); + ++itSrc; + } +} + +/**************************************************************************************************************/ +/** + * Method used to compute improve the NFA of The rectangle + */ +template <class TInputImage, class TPrecision > +float +LineSegmentDetector<TInputImage, TPrecision> +:: ImproveRectangle(RectangleType * rec , float NFA) +{ + int n = 0; + float nfa_new; + float delta = 0.5; + float delta_2 = delta / 2.0; + RectangleType r; + + if( NFA > 0. ) return NFA; + + /*Try to improve the precison of the oriented */ + CopyRectangle(&r ,rec ); + for(n=0; n<5; n++) + { + r[7] /= 2.0; + r[6] = M_PI * r[7]; // prec = rec[6] + nfa_new = this->ComputeRectNFA(r); + if( nfa_new > NFA ) + { + NFA = nfa_new; + CopyRectangle(rec ,&r ); + } + } + if( NFA > 0. ) return NFA; + + /*Try to improve the width of the rectangle*/ + CopyRectangle(&r ,rec ); + for(n=0; n<5; n++) + { + r[4] -= delta; //r[4] is stored as the width + nfa_new = this->ComputeRectNFA(r); + if( nfa_new > NFA ) + { + NFA = nfa_new; + CopyRectangle(rec ,&r ); + } + } + if( NFA > 0. ) return NFA; + + /*Try to improve the extremity of the segments*/ + CopyRectangle(&r ,rec ); + for(n=0; n<5; n++) + { + if( (r[4] - delta) >= 0.5 ) + { + r[0] += -vcl_sin(r[5]) * delta_2; + r[1] += vcl_cos(r[5])* delta_2; + r[2] += -vcl_sin(r[5])* delta_2; + r[3] += vcl_cos(r[5])* delta_2; + r[4] -= delta; + + nfa_new = this->ComputeRectNFA(r); + if( nfa_new > NFA ) + { + NFA = nfa_new; + CopyRectangle(rec ,&r ); + } + } + } + if( NFA > 0. ) return NFA; + + CopyRectangle(&r ,rec ); + for(n=0; n<5; n++) + { + if( (r[4] - delta) >= 0.5 ) + { + r[0] -= -vcl_sin(r[5]) * delta_2; + r[1] -= vcl_cos(r[5])* delta_2; + r[2] -= -vcl_sin(r[5])* delta_2; + r[3] -= vcl_cos(r[5])* delta_2; + r[4] -= delta; + + nfa_new = this->ComputeRectNFA(r); + if( nfa_new > NFA ) + { + NFA = nfa_new; + CopyRectangle(rec ,&r ); + } + } + } + if( NFA > 0. ) return NFA; + + /*Try to improve the precision again */ + CopyRectangle(&r ,rec ); + for(n=0; n<5; n++) + { + r[7] /= 2.0; + r[6] = M_PI * r[7]; // prec = rec[] + nfa_new = this->ComputeRectNFA(r); + if( nfa_new > NFA ) + { + NFA = nfa_new; + CopyRectangle(rec ,&r ); + } + } + if( NFA > 0. ) return NFA; + + return NFA; + +} + +/**************************************************************************************************************/ +/** + * Method IsUsed : Determine if a point exists in the pointSet of already computed points. + */ +template <class TInputImage, class TPrecision > +bool +LineSegmentDetector<TInputImage, TPrecision> +::IsUsed(InputIndexType index) +{ + bool isUsed = false; + + typedef itk::NeighborhoodIterator<LabelImageType> NeighborhoodLabelIteratorType; + typename NeighborhoodLabelIteratorType::SizeType radiusLabel; + radiusLabel.Fill(0); + NeighborhoodLabelIteratorType itLabel(radiusLabel,m_UsedPointImage, + m_UsedPointImage->GetRequestedRegion()); + + itLabel.SetLocation(index); + if(*(itLabel.GetCenterValue()) == 1) + isUsed = true; + + return isUsed; +} + +/** + * Method SetPixelToUsed : Determine if a point exists in the pointSet of already computed points. + */ +template <class TInputImage, class TPrecision > +void +LineSegmentDetector<TInputImage, TPrecision> +::SetPixelToUsed(InputIndexType index) +{ + typedef itk::NeighborhoodIterator<LabelImageType> NeighborhoodLabelIteratorType; + typename NeighborhoodLabelIteratorType::SizeType radiusLabel; + radiusLabel.Fill(0); + NeighborhoodLabelIteratorType itLabel(radiusLabel,m_UsedPointImage, + m_UsedPointImage->GetRequestedRegion()); + itLabel.SetLocation(index); + itLabel.SetCenterPixel(1); // 1 : Set the point status to : Used Point +} + +/**************************************************************************************************************/ +/** + * Method GrowRegion : + */ +template <class TInputImage, class TPrecision > +void +LineSegmentDetector<TInputImage, TPrecision> +::GrowRegion(InputIndexType index ) +{ + /** Add the point to the used list point*/ + this->SetPixelToUsed(index); + + /** Neighborhooding */ + typedef itk::ConstNeighborhoodIterator<InputImageType> NeighborhoodIteratorType; + typename NeighborhoodIteratorType::SizeType radius; + radius.Fill(1); + NeighborhoodIteratorType itNeigh(radius,m_MagnitudeFilter->GetOutput(), + m_MagnitudeFilter->GetOutput()->GetRequestedRegion()); + NeighborhoodIteratorType itNeighDir(radius,m_OrientationFilter->GetOutput() , + m_OrientationFilter->GetOutput()->GetRequestedRegion()); + + /** Vector where to store the point belonging to the current region*/ + unsigned int neighSize = itNeigh.GetSize()[0]*itNeigh.GetSize()[1]; + IndexVectorType reg; + + /** Angle of the region*/ + float regionAngle = 0; + + /** Add the first point to the region */ + reg.push_back(index); + float sumX = 0.; + float sumY = 0.; + + /** + * Loop for searching regions + */ + for (unsigned int cpt = 0; cpt < reg.size() ; cpt++ ) + { + itNeigh.SetLocation(reg[cpt]); + itNeighDir.SetLocation(reg[cpt]); + sumX += vcl_cos(*(itNeighDir.GetCenterValue())); + sumY += vcl_sin(*(itNeighDir.GetCenterValue())); + regionAngle = vcl_atan2(sumY,sumX); + + unsigned int s = 0; + while(s < neighSize ) + { + InputIndexType NeighIndex = itNeigh.GetIndex(s); + float angleComp = itNeighDir.GetPixel(s); + float prec = M_PI/8; + + if( !this->IsUsed(NeighIndex) && this->IsAligned(angleComp, regionAngle ,prec) ) + { + if(this->GetInput()->GetRequestedRegion().IsInside(NeighIndex)) /** Check if the index is inside the image*/ + { + this->SetPixelToUsed(NeighIndex); + reg.push_back(NeighIndex); + } + } + s++; + } + }/** End Searching loop*/ + + /** Store the region*/ + if(reg.size()> m_MinimumRegionSize && reg.size() < static_cast<unsigned int>(m_NumberOfImagePixels/2)) + { + m_RegionList.push_back(reg); + m_DirectionVector.push_back(regionAngle); + } +} + +/**************************************************************************************************************/ +/** + * + */ +template <class TInputImage, class TPrecision > +bool +LineSegmentDetector<TInputImage, TPrecision> +::IsAligned(float Angle, float regionAngle, float prec) +{ + + // if(Angle < 0.) Angle = - Angle; +// if(regionAngle < 0.) regionAngle = -regionAngle ; + +// while(Angle > M_PI) Angle -= M_PI; +// while( regionAngle > M_PI) regionAngle -= M_PI; + +// if(Angle < 0.) Angle = - Angle; +// if(regionAngle < 0.) regionAngle = -regionAngle ; + + float diff = Angle - regionAngle; + + if( diff < 0.0 ) diff = -diff; + + if( diff > 1.5*M_PI ) + { + diff -= 2*M_PI; + if( diff < 0.0 ) diff = -diff; + } + + + + + return diff < prec; +} + +/**************************************************************************************************************/ +/** + * + */ +template <class TInputImage, class TPrecision > +void +LineSegmentDetector<TInputImage, TPrecision> +::Region2Rect(IndexVectorType region , float angleRegion) +{ + /** Local Variables*/ + float weight = 0.,sumWeight = 0.; + float x = 0., y = 0.; + float l_min = 0., l_max = 0.,l =0., w=0. , w_min = 0. , w_max =0.; + + /** Neighborhooding again*/ + typedef itk::ConstNeighborhoodIterator<InputImageType> NeighborhoodIteratorType; + typename NeighborhoodIteratorType::SizeType radius; + radius.Fill(0); + NeighborhoodIteratorType itNeigh(radius,m_MagnitudeFilter->GetOutput(), + m_MagnitudeFilter->GetOutput()->GetRequestedRegion()); + + /** Computing the center of the rectangle*/ + IndexVectorIteratorType it = region.begin(); + while(it != region.end()) + { + itNeigh.SetLocation(*it); + weight = *itNeigh.GetCenterValue(); + x += static_cast<float>((*it)[0])* weight; + y += static_cast<float>((*it)[1])* weight; + sumWeight += weight; + ++it; + } + if(sumWeight < 1e-10) + { + x = 0.; y = 0.; + } + else + { + x/= sumWeight ; + y/= sumWeight ; + } + + /** Compute the orientation of the region*/ + float theta = this->ComputeRegionOrientation(region , x , y , angleRegion); + + /* Lenght & Width of the rectangle **/ + + typedef std::vector<MagnitudePixelType> MagnitudeVector; + SizeType sizeInput = this->GetInput()->GetRequestedRegion().GetSize(); + + int Diagonal = static_cast<unsigned int>(vcl_sqrt(sizeInput[0]*sizeInput[0] +sizeInput[1]*sizeInput[1])) + 2; + MagnitudeVector sum_l( 2*Diagonal, itk::NumericTraits<MagnitudePixelType>::Zero); + MagnitudeVector sum_w( 2*Diagonal, itk::NumericTraits<MagnitudePixelType>::Zero); + + float dx = vcl_cos(theta); + float dy = vcl_sin(theta); + + it = region.begin(); + while(it != region.end()) + { + itNeigh.SetLocation(*it); + weight = *itNeigh.GetCenterValue(); + l = ( static_cast<float>((*it)[0]) - x )*dx + ( static_cast<float>((*it)[1]) - y )*dy; + w = -( static_cast<float>((*it)[0]) - x )*dy + ( static_cast<float>((*it)[1]) - y )*dx; + + if(l<l_min) l_min = l; if(l>l_max) l_max = l; + if(w<w_min) w_min = w; if(w>w_max) w_max = w; + + sum_l[static_cast< int>(vcl_floor(l)+0.5)+ Diagonal ] += weight; + sum_w[static_cast< int>(vcl_floor(w)+0.5)+ Diagonal ] += weight; + + ++it; + } + + /** Thresholdinq the width and the length*/ + + float sum_th = 0.01 * sumWeight; /* weight threshold for selecting region */ + float s = 0.; + int i = 0; + + for( s=0.0,i = static_cast<int>(l_min); s<sum_th && i<=static_cast<int>(l_max) ; i++) + s += sum_l[ Diagonal + i]; + + float lb = (static_cast<float>(i-1) - 0.5 ) ; + + for(s=0.0,i=static_cast<int>(l_max); s<sum_th && i>=static_cast<int>(l_min); i--) + s += sum_l[ Diagonal + i]; + float lf = (static_cast<float>(i-1) - 0.5 ); + + for(s=0.0,i=static_cast<int>(w_min); s<sum_th && i<=static_cast<int>(w_max); i++) + s += sum_w[ Diagonal + i]; + + float wr = (static_cast<float>(i-1) - 0.5) ; + + for(s=0.0,i=static_cast<int>(w_max); s<sum_th && i>=static_cast<int>(w_min); i--) + s += sum_w[Diagonal + i]; + + float wl = (static_cast<float>(i-1) - 0.5 ) ; + + + /** Finally store the rectangle in vector this way : + * vec[0] = x1 + * vec[1] = y1 + * vec[2] = x2 + * vec[3] = y2 + * vec[4] = width + * vec[5] = theta + * vec[6] = prec = Pi/8 + * vec[7] = p = 1/8 + */ + + RectangleType rec(8 ,0.); // Definition of a rectangle : 8 components + rec[0] = (x + lb*dx >0)?x + lb*dx:0.; + rec[1] = (y + lb*dy>0 )?y + lb*dy:0.; + rec[2] = (x + lf*dx >0)?x + lf*dx:0.; + rec[3] = (y + lf*dy >0)? y + lf*dy:0; + rec[4] = vcl_abs(wl - wr); + rec[5] = theta; + rec[6] = M_PI/8; + rec[7] = 1./8.; + + if(rec[4] - 1. <1e-10) rec[4] = 1.; + m_RectangleList.push_back(rec); +} + +/**************************************************************************************************************/ +template <class TInputImage, class TPrecision > +float +LineSegmentDetector<TInputImage, TPrecision> +::ComputeRegionOrientation(IndexVectorType region , float x,float y , float angleRegion) +{ + + float Ixx = 0.0; + float Iyy = 0.0; + float Ixy = 0.0; + float theta = 0.; + float weight = 0.,sum = 0.; + + /** Neighborhooding again*/ + typedef itk::ConstNeighborhoodIterator<InputImageType> NeighborhoodIteratorType; + typename NeighborhoodIteratorType::SizeType radius; + radius.Fill(0); + NeighborhoodIteratorType itNeigh(radius,m_MagnitudeFilter->GetOutput(), + m_MagnitudeFilter->GetOutput()->GetRequestedRegion()); + + /** Computing the center iof the rectangle*/ + IndexVectorIteratorType it = region.begin(); + while(it != region.end()) + { + itNeigh.SetLocation(*it); + weight = *itNeigh.GetCenterValue(); + float Iyy2 = static_cast<float>((*it)[0]) - x; + float Ixx2 = static_cast<float>((*it)[1]) - y; + + Ixx += Ixx2*Ixx2*weight; + Iyy += Iyy2*Iyy2*weight; + Ixy -= Ixx2*Iyy2*weight; + sum += weight; + ++it; + } + + /** using te itk Eigen analysis*/ + typedef itk::Matrix<float , 2, 2> MatrixType; + typedef std::vector<float > MatrixEigenType; + MatrixType Inertie, eigenVector; + MatrixEigenType eigenMatrix(2,0.); + Inertie[0][0] =Ixx; + Inertie[1][1] =Iyy; + Inertie[0][1] =Ixy; + Inertie[1][0] =Ixy; + + typedef itk::SymmetricEigenAnalysis<MatrixType,MatrixEigenType> EigenAnalysisType; + EigenAnalysisType eigenFilter(2) ; + eigenFilter.ComputeEigenValuesAndVectors(Inertie,eigenMatrix,eigenVector ); + theta = vcl_atan2(eigenVector[1][1], -eigenVector[1][0]); + + /* the previous procedure don't cares orientations, + so it could be wrong by 180 degrees. + here is corrected if necessary */ + + float prec = M_PI/8; + if( this->angle_diff(theta,angleRegion) > prec ) theta += M_PI; + + return theta; +} + +/**************************************************************************************************************/ +/** + * Compute the difference betwenn 2 angles modulo 2_PI + */ +template <class TInputImage, class TPrecision > +float +LineSegmentDetector<TInputImage, TPrecision> +::angle_diff(float a, float b) +{ + a -= b; + while( a <= -M_PI ) a += 2*M_PI; + while( a > M_PI ) a -= 2*M_PI; + if( a < 0.0 ) a = -a; + return a; +} + +/** + * compute the number of false alarm of the rectangle + */ +template <class TInputImage, class TPrecision > +float +LineSegmentDetector<TInputImage, TPrecision> +::ComputeRectNFA(RectangleType rec) +{ + int NbAligned = 0; + float nfa_val = 0.; + + float dx = vcl_cos(rec[5]); + float dy = vcl_sin(rec[5]); + float halfWidth = rec[4]/2; + + /** Determine the four corners of the rectangle*/ + /** Remember : + * vec[0] = x1 + * vec[1] = y1 + * vec[2] = x2 + * vec[3] = y2 + * vec[4] = width + * vec[5] = theta + * vec[6] = prec = Pi/8 + * vec[7] = p = 1/8 + */ + + RectangleType X(4,0.) , Y(4,0.); + + X[0] = rec[0] + dy* halfWidth ; + Y[0] = rec[1] - dx* halfWidth ; + X[1] = rec[0] - dy* halfWidth ; + Y[1] = rec[1] + dx* halfWidth ; + X[2] = rec[2] + dy* halfWidth ; + Y[2] = rec[3] - dx* halfWidth ; + X[3] = rec[2] - dy* halfWidth ; + Y[3] = rec[3] + dx* halfWidth ; + + /** Compute the NFA of the rectangle + * We Need : The number of : Points in the rec (Area of the rectangle) + * Aligned points with theta in the rectangle + */ + + /** Compute the number of points aligned */ + typedef otb::Polygon<float> PolygonType; + PolygonType::Pointer rectangle = PolygonType::New(); + + /** Fill the rectangle with the points*/ + for (int i = 0; i<static_cast<int>(X.size()); i++) + { + InputIndexType vertex; + vertex[0] = X[i] ; vertex[1] = Y[i]; + rectangle->AddVertex(vertex); + } + + /** Get The Bounding Region*/ + OutputImageDirRegionType region = rectangle->GetBoundingRegion(); + + itk::ImageRegionIterator<OutputImageDirType> it(m_OrientationFilter->GetOutput(), region/*m_OrientationFilter->GetOutput()->GetRequestedRegion()*/); + it.GoToBegin(); + + int pts = 0; + + while(!it.IsAtEnd()) + { + if( rectangle->IsInside( it.GetIndex() )) + { + pts++; + + if(this->IsAligned(it.Get(), rec[5] /*theta*/ ,rec[6] /*Prec*/)) + NbAligned++; + } + ++it; + } + + /** Compute the NFA from the rectangle computed below*/ + SizeType SizeInput = this->GetInput()->GetRequestedRegion().GetSize(); + float logNT = 5.*(vcl_log10(static_cast<float>(SizeInput[0])) + vcl_log10(static_cast<float>(SizeInput[1])))/2.; + + nfa_val = NFA(pts,NbAligned ,0.125,logNT); + + return nfa_val; +} + +/**************************************************************************************************************/ +/* + compute logarithm of binomial NFA + NFA = NT.b(n,k,p) + log10 NFA = log10( NFA ) + + n,k,p - binomial parameters. + logNT - logarithm of Number of Tests + */ +template <class TInputImage, class TPrecision > +float +LineSegmentDetector<TInputImage, TPrecision> +::NFA(int n, int k, double p, double logNT) +{ + float val; + + if(k==0) return -logNT; + + val = -logNT - log10(betai((double)k,(double)(n-k+1),p)); + + if(isinf(val)) /* approximate by the first term of the tail */ + val = -logNT - ( factln(n) - factln(k) - factln(n-k) ) / M_LN10 + - (double)k * log10(p) - (double)(n-k) * log10(1.0-p); + + return val; +} + + +/** + * Standard "PrintSelf" method + */ +template <class TInputImage, class TPrecision > +void +LineSegmentDetector<TInputImage, TPrecision> +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf( os, indent ); + +} + + +/**************************************************************************************************************/ +/**************************************************************************************************************/ +/* + rutines betacf, gammln, betai, and factln + taken from "Numerical Recipes in C", Second Edtion, 1992 by + W.H. Press, S.A. Teukolsky, W.T.Vetterling and B.P. Flannery +*/ +/**************************************************************************************************************/ +/**************************************************************************************************************/ +template <class TInputImage, class TPrecision > +float +LineSegmentDetector<TInputImage, TPrecision> +::betacf(float a, float b, float x) +{ + int m,m2; + float aa,c,d,del,h,qab,qam,qap; + + qab=a+b; + qap=a+1.0; + qam=a-1.0; + c=1.0; + d=1.0-qab*x/qap; + if (fabs(d) < FPMIN) d=FPMIN; + d=1.0/d; + h=d; + for (m=1;m<=MAXIT;m++) { + m2=2*m; + aa=m*(b-m)*x/((qam+m2)*(a+m2)); + d=1.0+aa*d; + if (fabs(d) < FPMIN) d=FPMIN; + c=1.0+aa/c; + if (fabs(c) < FPMIN) c=FPMIN; + d=1.0/d; + h *= d*c; + aa = -(a+m)*(qab+m)*x/((a+m2)*(qap+m2)); + d=1.0+aa*d; + if (fabs(d) < FPMIN) d=FPMIN; + c=1.0+aa/c; + if (fabs(c) < FPMIN) c=FPMIN; + d=1.0/d; + del=d*c; + h *= del; + if (fabs(del-1.0) < EPS) break; + } + + return h; +} + +template <class TInputImage, class TPrecision > +float +LineSegmentDetector<TInputImage, TPrecision> +::gammln(float xx) +{ + double x,y,tmp,ser; + static double cof[6]={76.18009172947146,-86.50532032941677, + 24.01409824083091,-1.231739572450155, + 0.1208650973866179e-2,-0.5395239384953e-5}; + int j; + + y=x=xx; + tmp=x+5.5; + tmp -= (x+0.5)*log(tmp); + ser=1.000000000190015; + for (j=0;j<=5;j++) ser += cof[j]/++y; + return -tmp+log(2.5066282746310005*ser/x); +} + +template <class TInputImage, class TPrecision > +float +LineSegmentDetector<TInputImage, TPrecision> +::betai(float a, float b, float x) +{ + float betacf(float a, float b, float x); + float gammln(float xx); + float bt; + + if (x == 0.0 || x == 1.0) bt=0.0; + else + bt=exp(this->gammln(a+b)-this->gammln(a)-this->gammln(b)+a*log(x)+b*log(1.0-x)); + if (x < (a+1.0)/(a+b+2.0)) + return bt*this->betacf(a,b,x)/a; + else + return 1.0-bt*this->betacf(b,a,1.0-x)/b; +} + + +template <class TInputImage, class TPrecision > +float +LineSegmentDetector<TInputImage, TPrecision> +::factln(int n) +{ + float gammln(float xx); + static float a[101]; + + if (n <= 1) return 0.0; + if (n <= 100) return a[n] ? a[n] : (a[n]=this->gammln(n+1.0)); + else return this->gammln(n+1.0); +} +/*--------------------------------------------------------------------------------------------------------*/ +} // end namespace otb + +#endif diff --git a/Code/FeatureExtraction/otbSumAverageTextureFunctor.h b/Code/FeatureExtraction/otbSumAverageTextureFunctor.h new file mode 100644 index 0000000000000000000000000000000000000000..c9028a7b273677322805bd2f6c4c412f18b36a5e --- /dev/null +++ b/Code/FeatureExtraction/otbSumAverageTextureFunctor.h @@ -0,0 +1,147 @@ +/*========================================================================= + + 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 __otbSumAverageTextureFunctor_h +#define __otbSumAverageTextureFunctor_h + +#include "otbTextureFunctorBase.h" + +namespace otb +{ +namespace Functor +{ +/** \class SumAverageTextureFunctor + * \brief This functor calculates the inverse difference moment of an image + * + * Computes joint histogram (neighborhood and offset neighborhood) + * which bins are computing using Scott formula. + * Computes the probabiltiy p for each pair of pixel. + * InverseDifferenceMoment is the sum 1/(1+(pi-poff)²)*p over the neighborhood. + * TIterInput is an ietrator, TOutput is a PixelType. + * + * \ingroup Functor + * \ingroup + * \ingroup Statistics + */ +template <class TIterInput1, class TIterInput2, class TOutput> +class ITK_EXPORT SumAverageTextureFunctor : +public TextureFunctorBase<TIterInput1, TIterInput2, TOutput> +{ +public: + SumAverageTextureFunctor(){}; + ~SumAverageTextureFunctor(){}; + + typedef TIterInput1 IterType1; + typedef TIterInput2 IterType2; + typedef TOutput OutputType; + typedef typename IterType1::OffsetType OffsetType; + typedef typename IterType1::RadiusType RadiusType; + typedef typename IterType1::InternalPixelType InternalPixelType; + typedef typename IterType1::ImageType ImageType; + typedef itk::Neighborhood<InternalPixelType,::itk::GetImageDimension<ImageType>::ImageDimension> NeighborhoodType; + typedef std::vector<double> DoubleVectorType; + typedef std::vector<int> IntVectorType; + typedef std::vector<IntVectorType> IntVectorVectorType; + + + virtual double ComputeOverSingleChannel(const NeighborhoodType &neigh, const NeighborhoodType &neighOff) + { + DoubleVectorType binsLength = this->StatComputation(neigh, neighOff); + + RadiusType radius = neigh.GetRadius(); + double area = static_cast<double>(neigh.GetSize()[0]*neigh.GetSize()[1]); + double areaInv = 1/area; + OffsetType offset; + offset.Fill(0); + OffsetType offsetOff; + OffsetType offsetOffInit; + + offsetOffInit[0] = -radius[0]+this->GetOffset()[0]-1; + offsetOffInit[1] = -radius[1]+this->GetOffset()[1]-1; + + int histoIdX = 0; + int histoIdY = 0; + double out = 0.; + + IntVectorType histoTemp; + IntVectorVectorType histo; + if (binsLength[0] != 0) + histoTemp = IntVectorType( vcl_floor( static_cast<double>(this->GetMaxi()-this->GetMini())/binsLength[0])+1., 0); + else + histoTemp = IntVectorType( 1, 0 ); + + if (binsLength[1] != 0) + histo = IntVectorVectorType( vcl_floor(static_cast<double>(this->GetMaxiOff()-this->GetMiniOff())/binsLength[1])+1., histoTemp ); + else + histo = IntVectorVectorType( 1, histoTemp ); + + offsetOff = offsetOffInit; + for ( int l = -static_cast<int>(radius[0]); l <= static_cast<int>(radius[0]); l++ ) + { + offsetOff[0]++; + offsetOff[1] = offsetOffInit[1]; + offset[0] = l; + for ( int k = -static_cast<int>(radius[1]); k <= static_cast<int>(radius[1]); k++) + { + offsetOff[1]++; + offset[1] = k; + histoIdX = 0; + histoIdY = 0; + if ( binsLength[1] != 0) + histoIdX = static_cast<int>(vcl_floor( (static_cast<double>(neighOff[offsetOff])-this->GetMiniOff()) / static_cast<double>(binsLength[1]) )); + if ( binsLength[0] !=0 ) + histoIdY = static_cast<int>(vcl_floor( (static_cast<double>(neigh[offset])-this->GetMini()) /static_cast<double>( binsLength[0]) )); + + histo[histoIdX][histoIdY]++; + + } + } + // loop over bin neighborhood values + for (unsigned sB = 0; sB<histo[0].size(); sB++) + { + double nCeil = (static_cast<double>(sB)+0.5)*binsLength[0]; + for (unsigned r = 0; r<histo.size(); r++) + { + double rVal = (static_cast<double>(r)+0.5)*binsLength[1]; + for (unsigned s = 0; s<histo[r].size(); s++) + { + double sVal = (static_cast<double>(s)+0.5)*binsLength[0]; + // In theory don't have the abs but will deals with neighborhood and offset without the same histo + // thus loop over 2*Ng don't have sense + if( vcl_abs(rVal + sVal - nCeil) < vcl_abs(binsLength[0]+binsLength[1]) || vcl_abs(rVal + sVal - 2*nCeil) < vcl_abs(binsLength[0]+binsLength[1]) ) + { + double p = static_cast<double>(histo[r][s])*areaInv; + out += sVal * p; + } + } + } + } + + + return out; + } + +}; + + + + +} // namespace Functor +} // namespace otb + +#endif + diff --git a/Code/FeatureExtraction/otbTextureFunctorBase.h b/Code/FeatureExtraction/otbTextureFunctorBase.h index 2f0a1e460ad65fac4272bc5569eaf1213be3695c..f7423cd92d6de2c9a8f33c5edc25a86bb3e84299 100644 --- a/Code/FeatureExtraction/otbTextureFunctorBase.h +++ b/Code/FeatureExtraction/otbTextureFunctorBase.h @@ -19,8 +19,11 @@ #define __otbTextureFunctorBase_h #include "otbMath.h" +#include "itkMacro.h" +#include "itkNumericTraits.h" #include "itkNeighborhood.h" + namespace otb { namespace Functor @@ -62,7 +65,7 @@ public: typedef typename OutputType::ValueType OutputPixelType; typedef typename IterType1::InternalPixelType InternalPixelType; typedef typename IterType1::ImageType ImageType; - typedef itk::Neighborhood<InternalPixelType,::itk::GetImageDimension<ImageType>::ImageDimension> NeighborhoodType; + typedef itk::Neighborhood<InternalPixelType, ::itk::GetImageDimension<ImageType>::ImageDimension> NeighborhoodType; typedef std::vector<double> DoubleVectorType; void SetOffset(OffsetType off){ m_Offset=off; }; diff --git a/Code/Radiometry/otbRAndGAndNIRVegetationIndexImageFilter.h b/Code/Radiometry/otbRAndGAndNIRVegetationIndexImageFilter.h index 4061f13d4e4a2902ce86fc59f31b90f563d28583..342352e8c0eeddf4cbc1f245e353c251dcdccc0b 100644 --- a/Code/Radiometry/otbRAndGAndNIRVegetationIndexImageFilter.h +++ b/Code/Radiometry/otbRAndGAndNIRVegetationIndexImageFilter.h @@ -30,7 +30,7 @@ namespace otb */ template <class TInputImageR, class TInputImageG, class TInputImageNIR, class TOutputImage, -class TFunction = Functor::ARVI< typename TInputImageR::PixelType, +class TFunction = Functor::AVI< typename TInputImageR::PixelType, typename TInputImageG::PixelType, typename TInputImageNIR::PixelType, typename TOutputImage::PixelType > > diff --git a/Code/Radiometry/otbVegetationIndex.h b/Code/Radiometry/otbVegetationIndex.h index 7cd9d56467102df0e51ff3a0778594adcc361137..325ca707e86833e984323cf4e20ecf3e580c68ea 100644 --- a/Code/Radiometry/otbVegetationIndex.h +++ b/Code/Radiometry/otbVegetationIndex.h @@ -235,7 +235,7 @@ private: /** \class NDVI - * \brief This functor calculate the NormalizeD Vegetation Index (NDVI) + * \brief This functor computes the NormalizeD Vegetation Index (NDVI) * * [Pearson et Miller, 1972] * @@ -265,7 +265,7 @@ protected: }; /** \class RVI - * \brief This functor calculate the Ratio Vegetation Index (RVI) + * \brief This functor computes the Ratio Vegetation Index (RVI) * * [Rouse et al., 1973] * @@ -290,7 +290,7 @@ protected: } }; /** \class PVI - * \brief This functor calculate the Perpendicular Vegetation Index (PVI) + * \brief This functor computes the Perpendicular Vegetation Index (PVI) * * [Richardson et Wiegand, 1977] * @@ -340,7 +340,7 @@ private: /** \class SAVI - * \brief This functor calculate the Soil Adjusted Vegetation Index (SAVI) + * \brief This functor computes the Soil Adjusted Vegetation Index (SAVI) * * [Huete, 1988] * @@ -383,7 +383,7 @@ private: }; /** \class TSAVI - * \brief This functor calculate the Transformed Soil Adjusted Vegetation Index (TSAVI) + * \brief This functor computes the Transformed Soil Adjusted Vegetation Index (TSAVI) * * [Baret et al. 1989, Baret et Guyot, 1991] * @@ -447,7 +447,7 @@ private: }; /** \class MSAVI - * \brief This functor calculate the Modified Soil Adjusted Vegetation Index (MSAVI) + * \brief This functor computes the Modified Soil Adjusted Vegetation Index (MSAVI) * * [Qi et al., 1994] * @@ -476,7 +476,7 @@ protected: }; /** \class GEMI - * \brief This functor calculate the Global Environment Monitoring Index (GEMI) + * \brief This functor computes the Global Environment Monitoring Index (GEMI) * * [Pinty & Verstraete , 1992] * @@ -519,7 +519,7 @@ protected: }; /** \class WDVI - * \brief This functor calculate the Weighted Difference Vegetation Index (WDVI) + * \brief This functor computes the Weighted Difference Vegetation Index (WDVI) * * [Clevers, 1988] * @@ -556,7 +556,7 @@ private: }; /** \class AVI - * \brief This functor calculate the Angular Vegetation Index (AVI) + * \brief This functor computes the Angular Vegetation Index (AVI) * * This vegetation index use three inputs channels * @@ -606,9 +606,33 @@ protected: double dfact1 = (m_LambdaNir - m_LambdaR) / m_LambdaR; double dfact2 = (m_LambdaR - m_LambdaG) / m_LambdaR; - double dAVI = vcl_atan(dfact1/(dnir - dr)) + vcl_atan(dfact2/(dg - dr)); + double ddenom1; + double ddenom2; + if( (dnir-dr) == 0 ) + { + ddenom1 = 0; + } + else + { + ddenom1 = vcl_tan(dfact1/(dnir - dr)); + } + + if( (dg-dr) == 0 ) + { + ddenom2 = 0; + } + else + { + ddenom2 = vcl_tan(dfact2/(dg - dr)); + } + + if ( ddenom2 == 0 || ddenom1 == 0 ) + { + return ( static_cast<TOutput> (0) ); + } + else + return ( static_cast<TOutput> (1/ddenom1 + 1/ddenom2) ); - return ( static_cast<TOutput>( dAVI )); } private: @@ -624,7 +648,7 @@ private: /** \class ARVI - * \brief This functor calculate the Atmospherically Resistant Vegetation Index (ARVI) + * \brief This functor computes the Atmospherically Resistant Vegetation Index (ARVI) * * This vegetation index use three inputs channels * @@ -671,7 +695,7 @@ private: }; /** \class TSARVI - * \brief This functor calculate the Transformed Soil Atmospherical Resistant Vegetation Index (TSARVI) + * \brief This functor computes the Transformed Soil Atmospherical Resistant Vegetation Index (TSARVI) * * [Yoram J. Kaufman and Didier Tanré, 1992] * @@ -749,7 +773,7 @@ private: /** \class EVI - * \brief This functor calculate the Enhanced Vegetation Index (EVI) + * \brief This functor computes the Enhanced Vegetation Index (EVI) * * This vegetation index use three inputs channels * @@ -808,7 +832,7 @@ protected: double denominator = dnir + m_C1*dr - m_C2*db + m_L; if ( denominator == 0. ) { - return static_cast<TOutput>(0.); + return ( static_cast<TOutput>(0.) ); } return ( static_cast<TOutput>( m_G * (dnir - dr)/denominator ) ); } @@ -829,9 +853,9 @@ private: }; /** \class IPVI - * \brief This functor calculate the + * \brief This functor computes the Infrared Percentage VI (IPVI) * - * [Qi et al., 1994] + * [Crippen, 1990] * * \ingroup Functor */ @@ -845,16 +869,23 @@ public: protected: inline TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const { - - return 0; + double dr = static_cast<double>(r); + double dnir = static_cast<double>(nir); + if ((dnir + dr) == 0) + { + return static_cast<TOutput>(0.); + } + else + { + return ( static_cast<TOutput>( dnir/(dnir+dr) ) ); + } } - }; /** \class TNDVI - * \brief This functor calculate the + * \brief This functor computes the Transformed NDVI (TNDVI) * - * [Qi et al., 1994] + * [Deering, 1975] * * \ingroup Functor */ @@ -862,16 +893,22 @@ template <class TInput1, class TInput2, class TOutput> class TNDVI : public RAndNIRIndexBase<TInput1, TInput2, TOutput> { public: + typedef NDVI<TInput1, TInput2, TOutput> NDVIFunctorType; TNDVI() {}; ~TNDVI() {}; + + NDVIFunctorType GetNDVI(void)const + { + return (m_NDVIfunctor); + } protected: inline TOutput Evaluate(const TInput1 &r, const TInput2 &nir) const { - - return 0; + return ( static_cast<TOutput>(this->GetNDVI()(r,nir) + 0.5 )); } - +private: + const NDVIFunctorType m_NDVIfunctor; }; } // namespace Functor diff --git a/Testing/Code/Common/otbPolygon.cxx b/Testing/Code/Common/otbPolygon.cxx index 73e8e8fb869d4b0ac3a4c1baa8631abcda4ec222..5b5cea6f0774396ae3e5e1b1c7b367fa5920ecc1 100644 --- a/Testing/Code/Common/otbPolygon.cxx +++ b/Testing/Code/Common/otbPolygon.cxx @@ -132,8 +132,8 @@ int otbPolygon(int argc, char * argv[]) file<<std::endl<<std::endl; file<<"Surface computation : "<<std::endl; - file<<"Surface 1 :" << (double) polygon1->GetSurface() << std::endl; - file<<"Surface 2 :" << polygon2->GetSurface() << std::endl; + file<<"Surface 1 :" << (double) polygon1->GetArea() << std::endl; + file<<"Surface 2 :" << polygon2->GetArea() << std::endl; file<<std::endl<<std::endl; file<<"Length computation : "<<std::endl; diff --git a/Testing/Code/FeatureExtraction/CMakeLists.txt b/Testing/Code/FeatureExtraction/CMakeLists.txt index f2153df55aa5db0de6927066e22aad78acccb813..4ffdc3c835912a3347f4be5e5d97e8763c0b1556 100644 --- a/Testing/Code/FeatureExtraction/CMakeLists.txt +++ b/Testing/Code/FeatureExtraction/CMakeLists.txt @@ -28,6 +28,8 @@ SET(FEATUREEXTRACTION_TESTS9 ${CXX_TEST_PATH}/otbFeatureExtractionTests9) SET(FEATUREEXTRACTION_TESTS10 ${CXX_TEST_PATH}/otbFeatureExtractionTests10) SET(FEATUREEXTRACTION_TESTS11 ${CXX_TEST_PATH}/otbFeatureExtractionTests11) SET(FEATUREEXTRACTION_TESTS12 ${CXX_TEST_PATH}/otbFeatureExtractionTests12) +SET(FEATUREEXTRACTION_TESTS13 ${CXX_TEST_PATH}/otbFeatureExtractionTests13) + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbFeatureExtractionTests1 ~~~~~~~~~~~~~~~~~~~~~ @@ -977,7 +979,7 @@ ADD_TEST(feTuLandmarkNew ${FEATUREEXTRACTION_TESTS10} # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbFeatureExtractionTests11 ~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbFeatureExtractionTests11 ~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1040,8 +1042,28 @@ ADD_TEST(feTpSimplifyManyPathListFilter ${FEATUREEXTRACTION_TESTS11} 1.0 ) + +# ------- otb::LineSegmenbtDetector ------------- +ADD_TEST(feTuLineSegmentDetectorNew ${FEATUREEXTRACTION_TESTS11} + otbLineSegmentDetectorNew) + +ADD_TEST(feTvLineSegmentDetector ${FEATUREEXTRACTION_TESTS11} +--compare-image ${EPS} + ${BASELINE}/feTvLineSegmentdetectorOutputImage.tif + ${TEMP}/feTvLineSegmentdetectorOutputImage.tif + otbLineSegmentDetector + ${INPUTDATA}/prison_toulouse.tif + ${TEMP}/feTvLineSegmentdetectorOutputImage.tif +) + + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbFeatureExtractionTests12 ~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # ------- otb::TextureFunctorBase ------------- -ADD_TEST(feTvTextureFunctorBase ${FEATUREEXTRACTION_TESTS11} +ADD_TEST(feTvTextureFunctorBase ${FEATUREEXTRACTION_TESTS12} --compare-image ${EPS} ${INPUTDATA}/poupees_sub.png ${TEMP}/feTvTextureFunctorBase.tif @@ -1055,7 +1077,7 @@ ADD_TEST(feTvTextureFunctorBase ${FEATUREEXTRACTION_TESTS11} # ------- otb::EnergyTextureFunctor ------------- -ADD_TEST(feTvEnergyTextureFunctor ${FEATUREEXTRACTION_TESTS11} +ADD_TEST(feTvEnergyTextureFunctor ${FEATUREEXTRACTION_TESTS12} --compare-image ${EPS} ${BASELINE}/feTvEnergyTextureFunctor.tif ${TEMP}/feTvEnergyTextureFunctor.tif @@ -1069,7 +1091,7 @@ ADD_TEST(feTvEnergyTextureFunctor ${FEATUREEXTRACTION_TESTS11} ) # ------- otb::EntropyTextureFunctor ------------- -ADD_TEST(feTvEntropyTextureFunctor ${FEATUREEXTRACTION_TESTS11} +ADD_TEST(feTvEntropyTextureFunctor ${FEATUREEXTRACTION_TESTS12} --compare-image ${EPS} ${BASELINE}/feTvEntropyTextureFunctor.tif ${TEMP}/feTvEntropyTextureFunctor.tif @@ -1083,7 +1105,7 @@ ADD_TEST(feTvEntropyTextureFunctor ${FEATUREEXTRACTION_TESTS11} ) # ------- otb::InverseDifferenceMomentTextureFunctor ------------- -ADD_TEST(feTvInverseDifferenceMomentTextureFunctor ${FEATUREEXTRACTION_TESTS11} +ADD_TEST(feTvInverseDifferenceMomentTextureFunctor ${FEATUREEXTRACTION_TESTS12} --compare-image ${EPS} ${BASELINE}/feTvInverseDifferenceMomentTextureFunctor.tif ${TEMP}/feTvInverseDifferenceMomentTextureFunctor.tif @@ -1097,7 +1119,7 @@ ADD_TEST(feTvInverseDifferenceMomentTextureFunctor ${FEATUREEXTRACTION_TESTS11} ) # ------- otb::AngularSecondMomentumTextureFunctor ------------- -ADD_TEST(feTvAngularSecondMomentumTextureFunctor ${FEATUREEXTRACTION_TESTS11} +ADD_TEST(feTvAngularSecondMomentumTextureFunctor ${FEATUREEXTRACTION_TESTS12} --compare-image ${EPS} ${BASELINE}/feTvAngularSecondMomentumTextureFunctor.tif ${TEMP}/feTvAngularSecondMomentumTextureFunctor.tif @@ -1111,7 +1133,7 @@ ADD_TEST(feTvAngularSecondMomentumTextureFunctor ${FEATUREEXTRACTION_TESTS11} ) # ------- otb::VarianceTextureFunctor ------------- -ADD_TEST(feTvVarianceTextureFunctor ${FEATUREEXTRACTION_TESTS11} +ADD_TEST(feTvVarianceTextureFunctor ${FEATUREEXTRACTION_TESTS12} --compare-image ${EPS} ${BASELINE}/feTvVarianceTextureFunctor.tif ${TEMP}/feTvVarianceTextureFunctor.tif @@ -1125,7 +1147,7 @@ ADD_TEST(feTvVarianceTextureFunctor ${FEATUREEXTRACTION_TESTS11} ) # ------- otb::CorrelationTextureFunctor ------------- -ADD_TEST(feTvCorrelationTextureFunctor ${FEATUREEXTRACTION_TESTS11} +ADD_TEST(feTvCorrelationTextureFunctor ${FEATUREEXTRACTION_TESTS12} --compare-image ${EPS} ${BASELINE}/feTvCorrelationTextureFunctor.tif ${TEMP}/feTvCorrelationTextureFunctor.tif @@ -1139,7 +1161,7 @@ ADD_TEST(feTvCorrelationTextureFunctor ${FEATUREEXTRACTION_TESTS11} ) # ------- otb::ContrastTextureFunctor ------------- -ADD_TEST(feTvContrastTextureFunctor ${FEATUREEXTRACTION_TESTS11} +ADD_TEST(feTvContrastTextureFunctor ${FEATUREEXTRACTION_TESTS12} --compare-image ${EPS} ${BASELINE}/feTvContrastTextureFunctor.tif ${TEMP}/feTvContrastTextureFunctor.tif @@ -1152,8 +1174,41 @@ ADD_TEST(feTvContrastTextureFunctor ${FEATUREEXTRACTION_TESTS11} 2 # offset[1] ) + +# ------- otb::SumAverageTextureFunctor ------------- +ADD_TEST(feTvSumAverageTextureFunctor ${FEATUREEXTRACTION_TESTS12} +--compare-image ${EPS} + ${BASELINE}/feTvSumAverageTextureFunctor.tif + ${TEMP}/feTvSumAverageTextureFunctor.tif + otbTextureFunctor + SAV #sum average + ${INPUTDATA}/poupees_sub.png + ${TEMP}/feTvSumAverageTextureFunctor.tif + 5 # radius + -2 # offset[0] + 2 # offset[1] +) + +# ------- otb::DifferenceEntropyTextureFunctor ------------- +ADD_TEST(feTvDifferenceEntropyTextureFunctor ${FEATUREEXTRACTION_TESTS12} +--compare-image ${EPS} + ${BASELINE}/feTvDifferenceEntropyTextureFunctor.tif + ${TEMP}/feTvDifferenceEntropyTextureFunctor.tif + otbTextureFunctor + DEN #difference entropy + ${INPUTDATA}/poupees_sub.png + ${TEMP}/feTvDifferenceEntropyTextureFunctor.tif + 5 # radius + -2 # offset[0] + 2 # offset[1] +) + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbFeatureExtractionTests13 ~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # ------- otb::EnergyTextureImageFunction ------------- -ADD_TEST(feTvEnergyTextureImageFunction ${FEATUREEXTRACTION_TESTS12} +ADD_TEST(feTvEnergyTextureImageFunction ${FEATUREEXTRACTION_TESTS13} --compare-image ${EPS} ${BASELINE}/feTvEnergyTextureImageFunction.tif ${TEMP}/feTvEnergyTextureImageFunction.tif @@ -1169,7 +1224,7 @@ ADD_TEST(feTvEnergyTextureImageFunction ${FEATUREEXTRACTION_TESTS12} # ------- otb::EntropyTextureImageFunction ------------- -ADD_TEST(feTvEntropyTextureImageFunction ${FEATUREEXTRACTION_TESTS12} +ADD_TEST(feTvEntropyTextureImageFunction ${FEATUREEXTRACTION_TESTS13} --compare-image ${EPS} ${BASELINE}/feTvEntropyTextureImageFunction.tif ${TEMP}/feTvEntropyTextureImageFunction.tif @@ -1185,7 +1240,7 @@ ADD_TEST(feTvEntropyTextureImageFunction ${FEATUREEXTRACTION_TESTS12} # ------- otb::InverseDifferenceMomentTextureImageFunction ------------- -ADD_TEST(feTvInverseDifferenceMomentTextureImageFunction ${FEATUREEXTRACTION_TESTS12} +ADD_TEST(feTvInverseDifferenceMomentTextureImageFunction ${FEATUREEXTRACTION_TESTS13} --compare-image ${EPS} ${BASELINE}/feTvInverseDifferenceMomentTextureImageFunction.tif ${TEMP}/feTvInverseDifferenceMomentTextureImageFunction.tif @@ -1200,7 +1255,7 @@ ADD_TEST(feTvInverseDifferenceMomentTextureImageFunction ${FEATUREEXTRACTION_TES ) # ------- otb::AngularSecondMomentumTextureImageFunction ------------- -ADD_TEST(feTvAngularSecondMomentumTextureImageFunction ${FEATUREEXTRACTION_TESTS12} +ADD_TEST(feTvAngularSecondMomentumTextureImageFunction ${FEATUREEXTRACTION_TESTS13} --compare-image ${EPS} ${BASELINE}/feTvAngularSecondMomentumTextureImageFunction.tif ${TEMP}/feTvAngularSecondMomentumTextureImageFunction.tif @@ -1215,7 +1270,7 @@ ADD_TEST(feTvAngularSecondMomentumTextureImageFunction ${FEATUREEXTRACTION_TESTS ) # ------- otb::VarianceTextureImageFunction ------------- -ADD_TEST(feTvVarianceTextureImageFunction ${FEATUREEXTRACTION_TESTS12} +ADD_TEST(feTvVarianceTextureImageFunction ${FEATUREEXTRACTION_TESTS13} --compare-image ${EPS} ${BASELINE}/feTvVarianceTextureImageFunction.tif ${TEMP}/feTvVarianceTextureImageFunction.tif @@ -1230,7 +1285,7 @@ ADD_TEST(feTvVarianceTextureImageFunction ${FEATUREEXTRACTION_TESTS12} ) # ------- otb::CorrelationTextureImageFunction ------------- -ADD_TEST(feTvCorrelationTextureImageFunction ${FEATUREEXTRACTION_TESTS12} +ADD_TEST(feTvCorrelationTextureImageFunction ${FEATUREEXTRACTION_TESTS13} --compare-image ${EPS} ${BASELINE}/feTvCorrelationTextureImageFunction.tif ${TEMP}/feTvCorrelationTextureImageFunction.tif @@ -1245,7 +1300,7 @@ ADD_TEST(feTvCorrelationTextureImageFunction ${FEATUREEXTRACTION_TESTS12} ) # ------- otb::ContrastTextureImageFunction ------------- -ADD_TEST(feTvContrastTextureImageFunction ${FEATUREEXTRACTION_TESTS12} +ADD_TEST(feTvContrastTextureImageFunction ${FEATUREEXTRACTION_TESTS13} --compare-image ${EPS} ${BASELINE}/feTvContrastTextureImageFunction.tif ${TEMP}/feTvContrastTextureImageFunction.tif @@ -1259,6 +1314,35 @@ ADD_TEST(feTvContrastTextureImageFunction ${FEATUREEXTRACTION_TESTS12} 2 # offset[1] ) +# ------- otb::SumAverageTextureImageFunction ------------- +ADD_TEST(feTvSumAverageTextureImageFunction ${FEATUREEXTRACTION_TESTS13} +--compare-image ${EPS} + ${BASELINE}/feTvSumAverageTextureImageFunction.tif + ${TEMP}/feTvSumAverageTextureImageFunction.tif + otbTextureImageFunction + SAV #sum average + ${INPUTDATA}/poupees_sub_c1.png + ${TEMP}/feTvSumAverageTextureImageFunction.tif + 5 # radius[0] + 5 # radius[1] + -2 # offset[0] + 2 # offset[1] +) + +# ------- otb::DifferenceEntropyTextureImageFunction ------------- +ADD_TEST(feTvDifferenceEntropyTextureImageFunction ${FEATUREEXTRACTION_TESTS13} +--compare-image ${EPS} + ${BASELINE}/feTvDifferenceEntropyTextureImageFunction.tif + ${TEMP}/feTvDifferenceEntropyTextureImageFunction.tif + otbTextureImageFunction + DEN #difference entropy + ${INPUTDATA}/poupees_sub_c1.png + ${TEMP}/feTvDifferenceEntropyTextureImageFunction.tif + 5 # radius[0] + 5 # radius[1] + -2 # offset[0] + 2 # offset[1] + ) # A enrichir SET(BasicFeatureExtraction_SRCS1 @@ -1390,11 +1474,15 @@ otbCloudEstimatorFilter.cxx otbCloudDetectionFilterNew.cxx otbCloudDetectionFilter.cxx otbSimplifyManyPathListFilter.cxx +otbLineSegmentDetectorNew.cxx +otbLineSegmentDetector.cxx +) +SET(BasicFeatureExtraction_SRCS12 otbTextureFunctorBase.cxx otbTextureFunctor.cxx ) -SET(BasicFeatureExtraction_SRCS12 +SET(BasicFeatureExtraction_SRCS13 otbTextureImageFunction.cxx ) @@ -1424,6 +1512,8 @@ ADD_EXECUTABLE(otbFeatureExtractionTests11 otbFeatureExtractionTests11.cxx ${Bas TARGET_LINK_LIBRARIES(otbFeatureExtractionTests11 OTBFeatureExtraction OTBIO) ADD_EXECUTABLE(otbFeatureExtractionTests12 otbFeatureExtractionTests12.cxx ${BasicFeatureExtraction_SRCS12}) TARGET_LINK_LIBRARIES(otbFeatureExtractionTests12 OTBFeatureExtraction OTBIO) +ADD_EXECUTABLE(otbFeatureExtractionTests13 otbFeatureExtractionTests13.cxx ${BasicFeatureExtraction_SRCS13}) +TARGET_LINK_LIBRARIES(otbFeatureExtractionTests13 OTBFeatureExtraction OTBIO) # ADD_EXECUTABLE(roadDetect roadDetect.cxx) # TARGET_LINK_LIBRARIES(roadDetect OTBFeatureExtraction OTBIO) diff --git a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests11.cxx b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests11.cxx index edc5f7bd1235c97e31572d3bd3e094d798fbeb06..97062cb345d01e3ab105a015f4852228df7f3b4c 100644 --- a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests11.cxx +++ b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests11.cxx @@ -33,6 +33,6 @@ REGISTER_TEST(otbCloudEstimatorFilter); REGISTER_TEST(otbCloudDetectionFilterNew); REGISTER_TEST(otbCloudDetectionFilter); REGISTER_TEST(otbSimplifyManyPathListFilter); -REGISTER_TEST(otbTextureFunctorBase); -REGISTER_TEST(otbTextureFunctor); +REGISTER_TEST(otbLineSegmentDetectorNew); +REGISTER_TEST(otbLineSegmentDetector); } diff --git a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests12.cxx b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests12.cxx index 3203b9172a9996bd74a3f85e3502785275610f93..d8fd6fd81868f7ecfb488b9964c516773ec5bc20 100644 --- a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests12.cxx +++ b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests12.cxx @@ -27,5 +27,6 @@ void RegisterTests() { -REGISTER_TEST(otbTextureImageFunction); +REGISTER_TEST(otbTextureFunctorBase); +REGISTER_TEST(otbTextureFunctor); } diff --git a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests13.cxx b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests13.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3203b9172a9996bd74a3f85e3502785275610f93 --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests13.cxx @@ -0,0 +1,31 @@ +/*========================================================================= + + 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. + +=========================================================================*/ + +// this file defines the otbCommonTest for the test driver +// and all it expects is that you have a function called RegisterTests +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include <iostream> +#include "otbTestMain.h" + +void RegisterTests() +{ +REGISTER_TEST(otbTextureImageFunction); +} diff --git a/Testing/Code/FeatureExtraction/otbLineSegmentDetector.cxx b/Testing/Code/FeatureExtraction/otbLineSegmentDetector.cxx new file mode 100644 index 0000000000000000000000000000000000000000..502400140f479eab03b62b944d292ce660aeec0a --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbLineSegmentDetector.cxx @@ -0,0 +1,108 @@ +/*========================================================================= + + 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 "otbImage.h" +#include "otbLineSegmentDetector.h" +#include "otbDrawLineSpatialObjectListFilter.h" +#include "otbLineSpatialObjectList.h" +#include "itkLineIterator.h" + +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" + +int otbLineSegmentDetector( int argc, char * argv[] ) +{ + const char * infname = argv[1]; + const char * outfname = argv[2]; + + typedef double InputPixelType; + const unsigned int Dimension = 2; + + /** Typedefs */ + typedef otb::Image< InputPixelType, Dimension > InputImageType; + typedef InputImageType::IndexType IndexType; + typedef otb::ImageFileReader<InputImageType> ReaderType; + typedef otb::ImageFileWriter<InputImageType> WriterType; + typedef otb::DrawLineSpatialObjectListFilter< InputImageType ,InputImageType > DrawLineListType; + typedef otb::LineSegmentDetector<InputImageType , InputPixelType> lsdFilterType; + typedef itk::LineIterator<InputImageType> LineIteratorFilter; + + + /** Instanciation of smart pointer*/ + lsdFilterType::Pointer lsdFilter = lsdFilterType::New(); + DrawLineListType::Pointer drawLineFilter = DrawLineListType::New(); + ReaderType::Pointer reader = ReaderType::New(); + + + /** */ + typedef otb::LineSpatialObjectList LinesListType; + typedef LinesListType::LineType LineType; + LinesListType::Pointer list = LinesListType::New(); + + LineType::PointListType pointList; + LineType::LinePointType pointBegin , pointEnd; + IndexType IndexBegin , IndexEnd; + + /***/ + + reader->SetFileName(infname); + lsdFilter->SetInput(reader->GetOutput()); + lsdFilter->Update(); + + + LinesListType::const_iterator it = lsdFilter->GetOutput()->begin(); + LinesListType::const_iterator itEnd = lsdFilter->GetOutput()->end(); + + while(it != itEnd) + { + LineType::PointListType & pointsList = (*it)->GetPoints(); + LineType::PointListType::const_iterator itPoints = pointsList.begin(); + + float x = (*itPoints).GetPosition()[0]; + float y = (*itPoints).GetPosition()[1]; + IndexBegin[0] = x ; IndexBegin[1] = y; + + itPoints++; + + float x1 = (*itPoints).GetPosition()[0]; + float y1 = (*itPoints).GetPosition()[1]; + IndexEnd[0]= x1 ; IndexEnd[1] = y1; + + LineIteratorFilter itLine(reader->GetOutput(),IndexBegin, IndexEnd); + itLine.GoToBegin(); + while(!itLine.IsAtEnd()) + { + itLine.Set(255.); + ++itLine; + } + ++it; + } + + std::cout << " lsdFilter Ouput Size" << lsdFilter->GetOutput()->size() <<std::endl; + + /** Write The Output Image*/ + WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(outfname); + writer->SetInput(reader->GetOutput()); + writer->Update(); + + + + return EXIT_SUCCESS; +} + diff --git a/Testing/Code/FeatureExtraction/otbLineSegmentDetectorNew.cxx b/Testing/Code/FeatureExtraction/otbLineSegmentDetectorNew.cxx new file mode 100644 index 0000000000000000000000000000000000000000..dc41dca272dade11e44b2ca590e4741678836150 --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbLineSegmentDetectorNew.cxx @@ -0,0 +1,42 @@ +/*========================================================================= + + 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 "otbImage.h" +#include "otbLineSegmentDetector.h" + +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" + + + +int otbLineSegmentDetectorNew( int argc, char * argv[] ) +{ + + typedef float InputPixelType; + const unsigned int Dimension = 2; + + /** Typedefs */ + typedef otb::Image< InputPixelType, Dimension > InputImageType; + typedef otb::LineSegmentDetector<InputImageType , InputPixelType> lsdFilterType; + + + lsdFilterType::Pointer lsdFilter = lsdFilterType::New(); + + return EXIT_SUCCESS; +} + diff --git a/Testing/Code/FeatureExtraction/otbTextureFunctor.cxx b/Testing/Code/FeatureExtraction/otbTextureFunctor.cxx index 9c56c64a0bd4772788700832384725a65dfc7598..2ac85ea17750682eba037522bbd6da7fb7d004cb 100644 --- a/Testing/Code/FeatureExtraction/otbTextureFunctor.cxx +++ b/Testing/Code/FeatureExtraction/otbTextureFunctor.cxx @@ -31,7 +31,8 @@ #include "otbVarianceTextureFunctor.h" #include "otbCorrelationTextureFunctor.h" #include "otbContrastTextureFunctor.h" - +#include "otbSumAverageTextureFunctor.h" +#include "otbDifferenceEntropyTextureFunctor.h" template<class TInputImage, class TOutputImage, class TFunctor> int generic_TextureFunctor(int argc, char * argv[]) @@ -114,6 +115,16 @@ int otbTextureFunctor(int argc, char * argv[]) typedef otb::Functor::ContrastTextureFunctor<IteratorType, IteratorType, PixelType> FunctorType; return( generic_TextureFunctor<ImageType, ImageType, FunctorType>(argc,argv) ); } + else if ( strArgv == "SAV" ) + { + typedef otb::Functor::SumAverageTextureFunctor<IteratorType, IteratorType, PixelType> FunctorType; + return( generic_TextureFunctor<ImageType, ImageType, FunctorType>(argc,argv) ); + } + else if ( strArgv == "DEN" ) + { + typedef otb::Functor::DifferenceEntropyTextureFunctor<IteratorType, IteratorType, PixelType> FunctorType; + return( generic_TextureFunctor<ImageType, ImageType, FunctorType>(argc,argv) ); + } else { return EXIT_FAILURE; diff --git a/Testing/Code/FeatureExtraction/otbTextureImageFunction.cxx b/Testing/Code/FeatureExtraction/otbTextureImageFunction.cxx index 88e581770454c2f1ed648d465cb70c990c489114..45bc396d2a1d624a559f51e9c53b5af598b1184f 100644 --- a/Testing/Code/FeatureExtraction/otbTextureImageFunction.cxx +++ b/Testing/Code/FeatureExtraction/otbTextureImageFunction.cxx @@ -34,6 +34,8 @@ #include "otbVarianceTextureFunctor.h" #include "otbCorrelationTextureFunctor.h" #include "otbContrastTextureFunctor.h" +#include "otbSumAverageTextureFunctor.h" +#include "otbDifferenceEntropyTextureFunctor.h" template<class TInputImage, class TOutputImage, class TFunctor> @@ -130,6 +132,16 @@ int otbTextureImageFunction(int argc, char * argv[]) typedef otb::Functor::ContrastTextureFunctor<IteratorType, IteratorType, VectorType> FunctorType; return( generic_TextureImageFunction<ImageType, ImageType, FunctorType>(argc,argv) ); } + else if ( strArgv == "SAV" ) + { + typedef otb::Functor::SumAverageTextureFunctor<IteratorType, IteratorType, VectorType> FunctorType; + return( generic_TextureImageFunction<ImageType, ImageType, FunctorType>(argc,argv) ); + } + else if ( strArgv == "DEN" ) + { + typedef otb::Functor::DifferenceEntropyTextureFunctor<IteratorType, IteratorType, VectorType> FunctorType; + return( generic_TextureImageFunction<ImageType, ImageType, FunctorType>(argc,argv) ); + } else { return EXIT_FAILURE; diff --git a/Testing/Code/Radiometry/CMakeLists.txt b/Testing/Code/Radiometry/CMakeLists.txt index aa698653a4bda55e689f0bebebb4673268527eac..cc937cdb08eafba5d53e3032ae65269d9006730d 100644 --- a/Testing/Code/Radiometry/CMakeLists.txt +++ b/Testing/Code/Radiometry/CMakeLists.txt @@ -16,73 +16,12 @@ SET(RADIOMETRY_TESTS2 ${CXX_TEST_PATH}/otbRadiometryTests2) SET(RADIOMETRY_TESTS3 ${CXX_TEST_PATH}/otbRadiometryTests3) SET(RADIOMETRY_TESTS4 ${CXX_TEST_PATH}/otbRadiometryTests4) SET(RADIOMETRY_TESTS5 ${CXX_TEST_PATH}/otbRadiometryTests5) +SET(RADIOMETRY_TESTS6 ${CXX_TEST_PATH}/otbRadiometryTests6) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbRADIOMETRY_TESTS1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# ------- otb::RAndNIRVegetationIndexImageFilter ------------------------------ -ADD_TEST(raTuRAndNIRVegetationIndexImageFilterNew ${RADIOMETRY_TESTS1} - otbRAndNIRVegetationIndexImageFilterNew ) - -ADD_TEST(raTvNDVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} - --compare-image ${TOL} ${BASELINE}/raRAndNIRVegetationIndex_NDVI_poupees_subc1c2.tif - ${TEMP}/raRAndNIRVegetationIndex_NDVI_poupees_subc1c2.tif - otbRAndNIRVegetationIndexImageFilter - NDVI - ${INPUTDATA}/poupees_sub_c1.png - ${INPUTDATA}/poupees_sub_c2.png - ${TEMP}/raRAndNIRVegetationIndex_NDVI_poupees_subc1c2.tif - ) -ADD_TEST(raTvRVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} - --compare-image ${TOL} ${BASELINE}/raRAndNIRVegetationIndex_RVI_poupees_subc1c2.tif - ${TEMP}/raRAndNIRVegetationIndex_RVI_poupees_subc1c2.tif - otbRAndNIRVegetationIndexImageFilter - RVI - ${INPUTDATA}/poupees_sub_c1.png - ${INPUTDATA}/poupees_sub_c2.png - ${TEMP}/raRAndNIRVegetationIndex_RVI_poupees_subc1c2.tif - ) -ADD_TEST(raTvPVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} - --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif - ${TEMP}/raRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif - otbSetASetBRAndNIRVegetationIndexImageFilter - PVI - 0.7 - 0.9 - ${INPUTDATA}/poupees_sub_c1.png - ${INPUTDATA}/poupees_sub_c2.png - ${TEMP}/raRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif - ) -ADD_TEST(raTvSAVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} - --compare-image ${TOL} ${BASELINE}/raRAndNIRVegetationIndex_SAVI_poupees_subc1c2.tif - ${TEMP}/raRAndNIRVegetationIndex_SAVI_poupees_subc1c2.tif - otbRAndNIRVegetationIndexImageFilter - SAVI - ${INPUTDATA}/poupees_sub_c1.png - ${INPUTDATA}/poupees_sub_c2.png - ${TEMP}/raRAndNIRVegetationIndex_SAVI_poupees_subc1c2.tif - ) -ADD_TEST(raTvTSAVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} - --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif - ${TEMP}/raRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif - otbSetASetBRAndNIRVegetationIndexImageFilter - TSAVI - 0.7 - 0.9 - ${INPUTDATA}/poupees_sub_c1.png - ${INPUTDATA}/poupees_sub_c2.png - ${TEMP}/raRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif - ) -ADD_TEST(raTvMSAVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} - --compare-image ${TOL} ${BASELINE}/raRAndNIRVegetationIndex_MSAVI_poupees_subc1c2.tif - ${TEMP}/raRAndNIRVegetationIndex_MSAVI_poupees_subc1c2.tif - otbRAndNIRVegetationIndexImageFilter - MSAVI - ${INPUTDATA}/poupees_sub_c1.png - ${INPUTDATA}/poupees_sub_c2.png - ${TEMP}/raRAndNIRVegetationIndex_MSAVI_poupees_subc1c2.tif - ) # ------- otb::MultiChannelRAndNIRVegetationIndexImageFilter ------------------------------ @@ -107,17 +46,7 @@ ADD_TEST(raTvRVI_MultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TEST ${TEMP}/raMultiChannelRAndNIRVegetationIndex_RVI_poupees_subc1c2.tif 1 2 ) -ADD_TEST(raTvPVI_MultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} - --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif - ${TEMP}/raMultiChannelRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif - otbSetASetBMultiChannelRAndNIRVegetationIndexImageFilter - PVI - 0.7 - 0.9 - ${INPUTDATA}/poupees_sub.png - ${TEMP}/raMultiChannelRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif - 1 2 - ) + ADD_TEST(raTvSAVI_MultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} --compare-image ${TOL} ${BASELINE}/raRAndNIRVegetationIndex_SAVI_poupees_subc1c2.tif ${TEMP}/raMultiChannelRAndNIRVegetationIndex_SAVI_poupees_subc1c2.tif @@ -127,17 +56,7 @@ ADD_TEST(raTvSAVI_MultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TES ${TEMP}/raMultiChannelRAndNIRVegetationIndex_SAVI_poupees_subc1c2.tif 1 2 ) -ADD_TEST(raTvTSAVI_MultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} - --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif - ${TEMP}/raMultiChannelRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif - otbSetASetBMultiChannelRAndNIRVegetationIndexImageFilter - TSAVI - 0.7 - 0.9 - ${INPUTDATA}/poupees_sub.png - ${TEMP}/raMultiChannelRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif - 1 2 - ) + ADD_TEST(raTvMSAVI_MultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} --compare-image ${TOL} ${BASELINE}/raRAndNIRVegetationIndex_MSAVI_poupees_subc1c2.tif ${TEMP}/raMultiChannelRAndNIRVegetationIndex_MSAVI_poupees_subc1c2.tif @@ -148,6 +67,40 @@ ADD_TEST(raTvMSAVI_MultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TE 1 2 ) +# ------- IPVI MultiChannelRAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTvIPVIMultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_IPVI_qb_RoadExtract.tif + ${TEMP}/raRAndNIRVegetationIndex_IPVI_qb_RoadExtract.tif + otbMultiChannelRAndNIRVegetationIndexImageFilter + IPVI + ${INPUTDATA}/qb_RoadExtract2sub200x200.tif + ${TEMP}/raRAndNIRVegetationIndex_IPVI_qb_RoadExtract.tif + 3 4 # red nir +) + +# ------- TNDVI MultiChannelRAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTvTNDVIMultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_TNDVI_qb_RoadExtract.tif + ${TEMP}/raRAndNIRVegetationIndex_TNDVI_qb_RoadExtract.tif + otbMultiChannelRAndNIRVegetationIndexImageFilter + TNDVI + ${INPUTDATA}/qb_RoadExtract2sub200x200.tif + ${TEMP}/raRAndNIRVegetationIndex_TNDVI_qb_RoadExtract.tif + 3 4 +) + +# ------- GEMI MultiChannelRAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTvGEMIMultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS1} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_GEMI_qb_RoadExtract.tif + ${TEMP}/raRAndNIRVegetationIndex_GEMI_qb_RoadExtract.tif + otbMultiChannelRAndNIRVegetationIndexImageFilter + GEMI + ${INPUTDATA}/qb_RoadExtract.img + ${TEMP}/raRAndNIRVegetationIndex_GEMI_qb_RoadExtract.tif + 3 4 # red nir +) + + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbRADIOMETRY_TESTS2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -552,8 +505,80 @@ ADD_TEST(raTvTSARVIMultiChannelRAndBAndNIRVegetationIndexImageFilter ${RADIOMETR 0.5 # gamma ) + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbRADIOMETRY_TESTS5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# ------- otb::RAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTuRAndNIRVegetationIndexImageFilterNew ${RADIOMETRY_TESTS5} + otbRAndNIRVegetationIndexImageFilterNew ) + +ADD_TEST(raTvNDVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} + --compare-image ${TOL} ${BASELINE}/raRAndNIRVegetationIndex_NDVI_poupees_subc1c2.tif + ${TEMP}/raRAndNIRVegetationIndex_NDVI_poupees_subc1c2.tif + otbRAndNIRVegetationIndexImageFilter + NDVI + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${TEMP}/raRAndNIRVegetationIndex_NDVI_poupees_subc1c2.tif + ) +ADD_TEST(raTvRVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} + --compare-image ${TOL} ${BASELINE}/raRAndNIRVegetationIndex_RVI_poupees_subc1c2.tif + ${TEMP}/raRAndNIRVegetationIndex_RVI_poupees_subc1c2.tif + otbRAndNIRVegetationIndexImageFilter + RVI + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${TEMP}/raRAndNIRVegetationIndex_RVI_poupees_subc1c2.tif + ) + +ADD_TEST(raTvSAVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} + --compare-image ${TOL} ${BASELINE}/raRAndNIRVegetationIndex_SAVI_poupees_subc1c2.tif + ${TEMP}/raRAndNIRVegetationIndex_SAVI_poupees_subc1c2.tif + otbRAndNIRVegetationIndexImageFilter + SAVI + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${TEMP}/raRAndNIRVegetationIndex_SAVI_poupees_subc1c2.tif + ) + +ADD_TEST(raTvMSAVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} + --compare-image ${TOL} ${BASELINE}/raRAndNIRVegetationIndex_MSAVI_poupees_subc1c2.tif + ${TEMP}/raRAndNIRVegetationIndex_MSAVI_poupees_subc1c2.tif + otbRAndNIRVegetationIndexImageFilter + MSAVI + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${TEMP}/raRAndNIRVegetationIndex_MSAVI_poupees_subc1c2.tif + ) + +# ------- IPVI RAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTvIPVIRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_IPVI_poupees_subc1c2c3.tif + ${TEMP}/raRAndNIRVegetationIndex_IPVI_poupees_subc1c2c3.tif + otbRAndNIRVegetationIndexImageFilter + IPVI + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${TEMP}/raRAndNIRVegetationIndex_IPVI_poupees_subc1c2c3.tif +) + + +# ------- TNDVI RAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTvTNDVIRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_TNDVI_poupees_subc1c2c3.tif + ${TEMP}/raRAndNIRVegetationIndex_TNDVI_poupees_subc1c2c3.tif + otbRAndNIRVegetationIndexImageFilter + TNDVI + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${TEMP}/raRAndNIRVegetationIndex_TNDVI_poupees_subc1c2c3.tif +) + + # ------- GEMI RAndNIRVegetationIndexImageFilter ------------------------------ -ADD_TEST(raTvGEMIRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS4} +ADD_TEST(raTvGEMIRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_GEMI_poupees_subc1c2c3.tif ${TEMP}/raRAndNIRVegetationIndex_GEMI_poupees_subc1c2c3.tif otbRAndNIRVegetationIndexImageFilter @@ -563,135 +588,127 @@ ADD_TEST(raTvGEMIRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS4} ${TEMP}/raRAndNIRVegetationIndex_GEMI_poupees_subc1c2c3.tif ) -# ------- GEMI MultiChannelRAndNIRVegetationIndexImageFilter ------------------------------ -ADD_TEST(raTvGEMIMultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS4} - --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_GEMI_qb_RoadExtract.tif - ${TEMP}/raRAndNIRVegetationIndex_GEMI_qb_RoadExtract.tif - otbMultiChannelRAndNIRVegetationIndexImageFilter - GEMI - ${INPUTDATA}/qb_RoadExtract.img - ${TEMP}/raRAndNIRVegetationIndex_GEMI_qb_RoadExtract.tif - 3 4 # red nir -) - # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbRADIOMETRY_TESTS5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbRADIOMETRY_TESTS6 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - # ------- otb::RAndGAndNIRVegetationIndexImageFilter ------------------------------ -ADD_TEST(raTuRAndGAndNIRVegetationIndexImageFilterNew ${RADIOMETRY_TESTS5} +ADD_TEST(raTuRAndGAndNIRVegetationIndexImageFilterNew ${RADIOMETRY_TESTS6} otbRAndGAndNIRVegetationIndexImageFilterNew ) # ------- otb::MultiChannelRAndGAndNIRVegetationIndexImageFilter ------------------------------ -ADD_TEST(raTuMultiChannelRAndGAndNIRVegetationIndexImageFilterNew ${RADIOMETRY_TESTS5} +ADD_TEST(raTuMultiChannelRAndGAndNIRVegetationIndexImageFilterNew ${RADIOMETRY_TESTS6} otbMultiChannelRAndGAndNIRVegetationIndexImageFilterNew ) +ADD_TEST(raTvPVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS6} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif + ${TEMP}/raRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif + otbSetASetBRAndNIRVegetationIndexImageFilter + PVI + 0.7 + 0.9 + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${TEMP}/raRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif +) + +ADD_TEST(raTvPVI_MultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS6} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif + ${TEMP}/raMultiChannelRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif + otbSetASetBMultiChannelRAndNIRVegetationIndexImageFilter + PVI + 0.7 + 0.9 + ${INPUTDATA}/poupees_sub.png + ${TEMP}/raMultiChannelRAndNIRVegetationIndex_PVI_poupees_subc1c2.tif + 1 2 +) + + +ADD_TEST(raTvTSAVI_MultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS6} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif + ${TEMP}/raMultiChannelRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif + otbSetASetBMultiChannelRAndNIRVegetationIndexImageFilter + TSAVI + 0.7 + 0.9 + ${INPUTDATA}/poupees_sub.png + ${TEMP}/raMultiChannelRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif + 1 2 +) + +ADD_TEST(raTvTSAVI_RAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS6} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif + ${TEMP}/raRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif + otbSetASetBRAndNIRVegetationIndexImageFilter + TSAVI + 0.7 + 0.9 + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${TEMP}/raRAndNIRVegetationIndex_TSAVI_poupees_subc1c2.tif +) + # ------- AVI RAndGAndNIRVegetationIndexImageFilter ------------------------------ -# ADD_TEST(raTvAVIRAndGAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} -# --compare-image ${EPSILON} ${BASELINE}/raRAndGAndNIRVegetationIndex_AVI_poupees_subc1c2c3.tif -# ${TEMP}/raRAndGAndNIRVegetationIndex_AVI_poupees_subc1c2c3.tif -# otbAVIRAndGAndNIRVegetationIndexImageFilter -# ${INPUTDATA}/poupees_sub_c1.png -# ${INPUTDATA}/poupees_sub_c2.png -# ${INPUTDATA}/poupees_sub_c3.png -# ${TEMP}/raRAndGAndNIRVegetationIndex_AVI_poupees_subc1c2c3.tif -# 0.7 # lambda1 -# 0.9 # lambda2 -# 0.8 # lambda3 -# ) -# -# # ------- AVI MultiChannelRAndGAndNIRVegetationIndexImageFilter ------------------------------ -# ADD_TEST(raTvAVIMultiChannelRAndGAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} -# --compare-image ${EPSILON} ${BASELINE}/raRAndGAndNIRVegetationIndex_AVI_qb_RoadExtract.tif -# ${TEMP}/raRAndGAndNIRVegetationIndex_AVI_qb_RoadExtract.tif -# otbAVIMultiChannelRAndGAndNIRVegetationIndexImageFilter -# ${INPUTDATA}/qb_RoadExtract2sub200x200.tif -# ${TEMP}/raRAndGAndNIRVegetationIndex_AVI_qb_RoadExtract.tif -# 3 # red -# 2 # green -# 4 # nir -# 0.7 # lambda1 -# 0.9 # lambda2 -# 0.8 # lambda3 -# ) -# -# # ------- WDVI RAndNIRVegetationIndexImageFilter ------------------------------ -# ADD_TEST(raTvWDVIRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} -# --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_WDVI_poupees_subc1c2c3.tif -# ${TEMP}/raRAndNIRVegetationIndex_WDVI_poupees_subc1c2c3.tif -# otbWDVIRAndNIRVegetationIndexImageFilter -# ${INPUTDATA}/poupees_sub_c1.png -# ${INPUTDATA}/poupees_sub_c2.png -# ${TEMP}/raRAndNIRVegetationIndex_WDVI_poupees_subc1c2c3.tif -# 1.0 # g : slope of soil line -# ) -# -# # ------- WDVI MultiChannelRAndNIRVegetationIndexImageFilter ------------------------------ -# ADD_TEST(raTvWDVIMultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} -# --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_WDVI_qb_RoadExtract.tif -# ${TEMP}/raRAndNIRVegetationIndex_WDVI_qb_RoadExtract.tif -# otbWDVIMultiChannelRAndNIRVegetationIndexImageFilter -# ${INPUTDATA}/qb_RoadExtract2sub200x200.tif -# ${TEMP}/raRAndNIRVegetationIndex_WDVI_qb_RoadExtract.tif -# 3 # red -# 4 # nir -# 1.0 # g : slope of soil line -# ) -# -# # ------- IPVI RAndNIRVegetationIndexImageFilter ------------------------------ -# ADD_TEST(raTvIPVIRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} -# --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_IPVI_poupees_subc1c2c3.tif -# ${TEMP}/raRAndNIRVegetationIndex_IPVI_poupees_subc1c2c3.tif -# otbRAndNIRVegetationIndexImageFilter -# ${INPUTDATA}/poupees_sub_c1.png -# ${INPUTDATA}/poupees_sub_c2.png -# ${TEMP}/raRAndNIRVegetationIndex_IPVI_poupees_subc1c2c3.tif -# ) -# -# # ------- IPVI MultiChannelRAndNIRVegetationIndexImageFilter ------------------------------ -# ADD_TEST(raTvIPVIMultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} -# --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_IPVI_qb_RoadExtract.tif -# ${TEMP}/raRAndNIRVegetationIndex_IPVI_qb_RoadExtract.tif -# otbMultiChannelRAndNIRVegetationIndexImageFilter -# ${INPUTDATA}/qb_RoadExtract2sub200x200.tif -# ${TEMP}/raRAndNIRVegetationIndex_IPVI_qb_RoadExtract.tif -# 3 # red -# 1 # blue -# 4 # nir -# ) -# -# # ------- TNDVI RAndNIRVegetationIndexImageFilter ------------------------------ -# ADD_TEST(raTvTNDVIRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} -# --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_TNDVI_poupees_subc1c2c3.tif -# ${TEMP}/raRAndNIRVegetationIndex_TNDVI_poupees_subc1c2c3.tif -# otbRAndNIRVegetationIndexImageFilter -# ${INPUTDATA}/poupees_sub_c1.png -# ${INPUTDATA}/poupees_sub_c2.png -# ${TEMP}/raRAndNIRVegetationIndex_TNDVI_poupees_subc1c2c3.tif -# ) -# -# # ------- TNDVI MultiChannelRAndNIRVegetationIndexImageFilter ------------------------------ -# ADD_TEST(raTvTNDVIMultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS5} -# --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_TNDVI_qb_RoadExtract.tif -# ${TEMP}/raRAndNIRVegetationIndex_TNDVI_qb_RoadExtract.tif -# otbMultiChannelRAndNIRVegetationIndexImageFilter -# ${INPUTDATA}/qb_RoadExtract2sub200x200.tif -# ${TEMP}/raRAndNIRVegetationIndex_TNDVI_qb_RoadExtract.tif -# 3 # red -# 1 # blue -# 4 # nir -# ) +ADD_TEST(raTvAVIRAndGAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS6} + --compare-image ${EPSILON} ${BASELINE}/raRAndGAndNIRVegetationIndex_AVI_poupees_subc1c2c3.tif + ${TEMP}/raRAndGAndNIRVegetationIndex_AVI_poupees_subc1c2c3.tif + otbAVIRAndGAndNIRVegetationIndexImageFilter + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${INPUTDATA}/poupees_sub_c3.png + ${TEMP}/raRAndGAndNIRVegetationIndex_AVI_poupees_subc1c2c3.tif + 660. # lambda r + 560. # lambda g + 830. # lambda nir +) + +# ------- AVI MultiChannelRAndGAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTvAVIMultiChannelRAndGAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS6} + --compare-image ${EPSILON} ${BASELINE}/raRAndGAndNIRVegetationIndex_AVI_qb_RoadExtract.tif + ${TEMP}/raRAndGAndNIRVegetationIndex_AVI_qb_RoadExtract.tif + otbAVIMultiChannelRAndGAndNIRVegetationIndexImageFilter + ${INPUTDATA}/qb_RoadExtract2sub200x200.tif + ${TEMP}/raRAndGAndNIRVegetationIndex_AVI_qb_RoadExtract.tif + 3 # red + 2 # green + 4 # nir + 660. # lambda r + 560. # lambda g + 830. # lambda nir +) + +# ------- WDVI RAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTvWDVIRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS6} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_WDVI_poupees_subc1c2c3.tif + ${TEMP}/raRAndNIRVegetationIndex_WDVI_poupees_subc1c2c3.tif + otbWDVIRAndNIRVegetationIndexImageFilter + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${TEMP}/raRAndNIRVegetationIndex_WDVI_poupees_subc1c2c3.tif + 2.0 # g : slope of soil line +) +# ------- WDVI MultiChannelRAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTvWDVIMultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS6} + --compare-image ${EPSILON} ${BASELINE}/raRAndNIRVegetationIndex_WDVI_qb_RoadExtract.tif + ${TEMP}/raRAndNIRVegetationIndex_WDVI_qb_RoadExtract.tif + otbWDVIMultiChannelRAndNIRVegetationIndexImageFilter + ${INPUTDATA}/qb_RoadExtract2sub200x200.tif + ${TEMP}/raRAndNIRVegetationIndex_WDVI_qb_RoadExtract.tif + 3 # red + 4 # nir + 2.0 # g : slope of soil line +) + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbRADIOMETRY_TESTS7 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # A enrichir SET(Radiometry_SRCS1 -otbRAndNIRVegetationIndexImageFilterNew.cxx -otbRAndNIRVegetationIndexImageFilter.cxx -otbSetASetBRAndNIRVegetationIndexImageFilter.cxx otbMultiChannelRAndNIRVegetationIndexImageFilterNew.cxx otbMultiChannelRAndNIRVegetationIndexImageFilter.cxx -otbSetASetBMultiChannelRAndNIRVegetationIndexImageFilter.cxx ) SET(Radiometry_SRCS2 otbRAndBAndNIRVegetationIndexImageFilterNew.cxx @@ -726,26 +743,26 @@ otbEVIRAndBAndNIRVegetationIndexImageFilter.cxx otbEVIMultiChannelRAndBAndNIRVegetationIndexImageFilter.cxx otbTSARVIRAndBAndNIRVegetationIndexImageFilter.cxx otbTSARVIMultiChannelRAndBAndNIRVegetationIndexImageFilter.cxx +) -# je remets ça ? DUPLICATION pas bon +SET(Radiometry_SRCS5 +otbRAndNIRVegetationIndexImageFilterNew.cxx otbRAndNIRVegetationIndexImageFilter.cxx -otbMultiChannelRAndNIRVegetationIndexImageFilter.cxx ) -SET(Radiometry_SRCS5 + +SET(Radiometry_SRCS6 +otbSetASetBRAndNIRVegetationIndexImageFilter.cxx +otbSetASetBMultiChannelRAndNIRVegetationIndexImageFilter.cxx otbRAndGAndNIRVegetationIndexImageFilterNew.cxx otbMultiChannelRAndGAndNIRVegetationIndexImageFilterNew.cxx otbAVIRAndGAndNIRVegetationIndexImageFilter.cxx otbAVIMultiChannelRAndGAndNIRVegetationIndexImageFilter.cxx otbWDVIRAndNIRVegetationIndexImageFilter.cxx otbWDVIMultiChannelRAndNIRVegetationIndexImageFilter.cxx - - -# je remets ça ? DUPLICATION pas bon -otbRAndNIRVegetationIndexImageFilter.cxx -otbMultiChannelRAndNIRVegetationIndexImageFilter.cxx ) + INCLUDE_DIRECTORIES("${OTBTesting_BINARY_DIR}") ADD_EXECUTABLE(otbRadiometryTests1 otbRadiometryTests1.cxx ${Radiometry_SRCS1}) @@ -758,5 +775,7 @@ ADD_EXECUTABLE(otbRadiometryTests4 otbRadiometryTests4.cxx ${Radiometry_SRCS4}) TARGET_LINK_LIBRARIES(otbRadiometryTests4 OTBRadiometry OTBIO) ADD_EXECUTABLE(otbRadiometryTests5 otbRadiometryTests5.cxx ${Radiometry_SRCS5}) TARGET_LINK_LIBRARIES(otbRadiometryTests5 OTBRadiometry OTBIO) +ADD_EXECUTABLE(otbRadiometryTests6 otbRadiometryTests6.cxx ${Radiometry_SRCS6}) +TARGET_LINK_LIBRARIES(otbRadiometryTests6 OTBRadiometry OTBIO) ENDIF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING ) diff --git a/Testing/Code/Radiometry/otbAVIRAndGAndNIRVegetationIndexImageFilter.cxx b/Testing/Code/Radiometry/otbAVIRAndGAndNIRVegetationIndexImageFilter.cxx index 37b956d4ec802fa51afdced5c910f3e5e8dd8af3..9fe2026bdccb34aa4e21ca9e16f86fdbd35c9f9d 100644 --- a/Testing/Code/Radiometry/otbAVIRAndGAndNIRVegetationIndexImageFilter.cxx +++ b/Testing/Code/Radiometry/otbAVIRAndGAndNIRVegetationIndexImageFilter.cxx @@ -75,8 +75,8 @@ int otbAVIRAndGAndNIRVegetationIndexImageFilter(int argc, char * argv[]) filter->SetInputG( readerG->GetOutput() ); filter->SetInputNIR( readerNIR->GetOutput() ); - filter->GetFunctor().SetLambdaG(lg); filter->GetFunctor().SetLambdaR(lr); + filter->GetFunctor().SetLambdaG(lg); filter->GetFunctor().SetLambdaNir(lnir); writer->SetInput( filter->GetOutput() ); diff --git a/Testing/Code/Radiometry/otbRadiometryTests1.cxx b/Testing/Code/Radiometry/otbRadiometryTests1.cxx index 1cf6c46021d8ad161bbe16aae72c16dbca6fd865..f0f43ec9a36a6dc8e93e0bacd7a75b6049d59c0f 100644 --- a/Testing/Code/Radiometry/otbRadiometryTests1.cxx +++ b/Testing/Code/Radiometry/otbRadiometryTests1.cxx @@ -27,11 +27,7 @@ void RegisterTests() { - REGISTER_TEST(otbRAndNIRVegetationIndexImageFilterNew); - REGISTER_TEST(otbRAndNIRVegetationIndexImageFilter); - REGISTER_TEST(otbSetASetBRAndNIRVegetationIndexImageFilter); REGISTER_TEST(otbMultiChannelRAndNIRVegetationIndexImageFilterNew); REGISTER_TEST(otbMultiChannelRAndNIRVegetationIndexImageFilter); - REGISTER_TEST(otbSetASetBMultiChannelRAndNIRVegetationIndexImageFilter); } diff --git a/Testing/Code/Radiometry/otbRadiometryTests4.cxx b/Testing/Code/Radiometry/otbRadiometryTests4.cxx index 8b5c0624f72d21807488ba7d6520299d8f17abf5..406d589c40f86d222a6efb829b852805a3b85235 100644 --- a/Testing/Code/Radiometry/otbRadiometryTests4.cxx +++ b/Testing/Code/Radiometry/otbRadiometryTests4.cxx @@ -34,9 +34,5 @@ void RegisterTests() REGISTER_TEST(otbEVIMultiChannelRAndBAndNIRVegetationIndexImageFilter); REGISTER_TEST(otbTSARVIRAndBAndNIRVegetationIndexImageFilter); REGISTER_TEST(otbTSARVIMultiChannelRAndBAndNIRVegetationIndexImageFilter); - -/* A TRIER */ - REGISTER_TEST(otbRAndNIRVegetationIndexImageFilter); - REGISTER_TEST(otbMultiChannelRAndNIRVegetationIndexImageFilter); } diff --git a/Testing/Code/Radiometry/otbRadiometryTests5.cxx b/Testing/Code/Radiometry/otbRadiometryTests5.cxx index 17e2d280023b860d33f22d83edfb7fc978e6675b..3811d0e22216cae087feff4d1eadb1674f410a4d 100644 --- a/Testing/Code/Radiometry/otbRadiometryTests5.cxx +++ b/Testing/Code/Radiometry/otbRadiometryTests5.cxx @@ -27,11 +27,8 @@ void RegisterTests() { - REGISTER_TEST(otbRAndGAndNIRVegetationIndexImageFilterNew); - REGISTER_TEST(otbMultiChannelRAndGAndNIRVegetationIndexImageFilterNew); - REGISTER_TEST(otbAVIRAndGAndNIRVegetationIndexImageFilter); - REGISTER_TEST(otbAVIMultiChannelRAndGAndNIRVegetationIndexImageFilter); - REGISTER_TEST(otbWDVIRAndNIRVegetationIndexImageFilter); - REGISTER_TEST(otbWDVIMultiChannelRAndNIRVegetationIndexImageFilter); + + REGISTER_TEST(otbRAndNIRVegetationIndexImageFilterNew); + REGISTER_TEST(otbRAndNIRVegetationIndexImageFilter); } diff --git a/Testing/Code/Radiometry/otbRadiometryTests6.cxx b/Testing/Code/Radiometry/otbRadiometryTests6.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d19592af53baf27cdf8754c872c05dd596066587 --- /dev/null +++ b/Testing/Code/Radiometry/otbRadiometryTests6.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. + + + 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. + +=========================================================================*/ + +// this file defines the otbCommonTest for the test driver +// and all it expects is that you have a function called RegisterTests +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include <iostream> +#include "otbTestMain.h" + +void RegisterTests() +{ + REGISTER_TEST(otbSetASetBRAndNIRVegetationIndexImageFilter); + REGISTER_TEST(otbSetASetBMultiChannelRAndNIRVegetationIndexImageFilter); + REGISTER_TEST(otbRAndGAndNIRVegetationIndexImageFilterNew); + REGISTER_TEST(otbMultiChannelRAndGAndNIRVegetationIndexImageFilterNew); + REGISTER_TEST(otbAVIRAndGAndNIRVegetationIndexImageFilter); + REGISTER_TEST(otbAVIMultiChannelRAndGAndNIRVegetationIndexImageFilter); + REGISTER_TEST(otbWDVIRAndNIRVegetationIndexImageFilter); + REGISTER_TEST(otbWDVIMultiChannelRAndNIRVegetationIndexImageFilter); +} +