diff --git a/Code/FeatureExtraction/otbGenericRoadExtractionFilter.h b/Code/FeatureExtraction/otbGenericRoadExtractionFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..05cb574810b2bf58452a63e65fe0fb19c939f2c9 --- /dev/null +++ b/Code/FeatureExtraction/otbGenericRoadExtractionFilter.h @@ -0,0 +1,244 @@ +/*========================================================================= + +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 __otbGenericRoadExtractionFilter_h +#define __otbGenericRoadExtractionFilter_h + +#include "itkCovariantVector.h" +#include "itkGradientRecursiveGaussianImageFilter.h" + +#include "otbImage.h" +#include "otbVectorImage.h" +#include "otbImageToPathListFilter.h" +#include "itkSqrtImageFilter.h" +#include "otbNeighborhoodScalarProductFilter.h" +#include "otbNonMaxRemovalByDirectionFilter.h" +#include "otbVectorizationPathListFilter.h" +#include "otbSimplifyPathListFilter.h" +#include "otbBreakAngularPathListFilter.h" +#include "otbRemoveTortuousPathListFilter.h" +#include "otbLinkPathListFilter.h" +#include "otbRemoveIsolatedByDirectionFilter.h" +#include "otbRemoveWrongDirectionFilter.h" +#include "otbLikehoodPathListFilter.h" + +namespace otb +{ +/** + * \class GenericRoadExtractionFilter + * \brief This class performs the extraction of roads from an image. + * + * This composite filter implements a fast and robust road extraction + * for high resolution satellite images. The line + * detection is done using a Gaussian gradient with a scalar product to find + * the road directions. Finally, extracted roads are vectorized and + * processed to improve the results removing some occultations and false + * detections. + * + * This filter is fast, as the detection typically takes 3 seconds for a + * 1000 \f$ \times \f$ 1000 images with four spectral bands. Results can be + * used as an initialization for more complex algorithms. + * + * \sa itk::SqrtImageFilter + * \sa itk::GradientRecursiveGaussianImageFilter + * \sa NeighborhoodScalarProductFilter + * \sa RemoveIsolatedByDirectionFilter + * \sa RemoveWrongDirectionFilter + * \sa NonMaxRemovalByDirectionFilter + * \sa VectorizationPathListFilter + * \sa SimplifyPathListFilter + * \sa BreakAngularPathListFilter + * \sa RemoveTortuousPathListFilter + * \sa LinkPathListFilter + * \sa LikehoodPathListFilter + */ +template <class TInputImage, class TOutputPath> + class ITK_EXPORT GenericRoadExtractionFilter + : public ImageToPathListFilter<TInputImage,TOutputPath> + { + public : + /** Standard typedefs */ + typedef GenericRoadExtractionFilter Self; + typedef ImageToPathListFilter<TInputImage,TOutputPath> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + /** Creation through object factory macro */ + itkNewMacro(Self); + /** Type macro */ + itkTypeMacro(GenericRoadExtractionFilter,ImageToPathListFilter); + /** Template parameters typedefs */ + typedef typename Superclass::InputImageType InputImageType; + typedef typename Superclass::OutputPathType OutputPathType; + typedef typename Superclass::OutputPathListType OutputPathListType; + typedef typename InputImageType::PixelType InputPixelType; + typedef double InternalPixelType; + + typedef otb::VectorImage<InternalPixelType,InputImageType::ImageDimension> VectorImageType; + typedef otb::Image<InternalPixelType,InputImageType::ImageDimension> ModulusType; + typedef otb::Image<InternalPixelType,InputImageType::ImageDimension> DirectionType; + + typedef itk::CovariantVector<InternalPixelType,InputImageType::ImageDimension> + VectorPixelType; + typedef otb::Image<VectorPixelType,InputImageType::ImageDimension> CovariantVectorImageType; + + + typedef itk::SqrtImageFilter< + InputImageType, + InputImageType> SquareRootImageFilterType; + + typedef itk::GradientRecursiveGaussianImageFilter< + InputImageType, + CovariantVectorImageType> GradientFilterType; + + typedef NeighborhoodScalarProductFilter< + CovariantVectorImageType, + ModulusType, + DirectionType> NeighborhoodScalarProductFilterType; + + typedef RemoveIsolatedByDirectionFilter< + ModulusType, + DirectionType, + ModulusType > RemoveIsolatedByDirectionFilterType; + + typedef RemoveWrongDirectionFilter< + ModulusType, + DirectionType, + ModulusType> RemoveWrongDirectionFilterType; + + typedef NonMaxRemovalByDirectionFilter< + ModulusType, + DirectionType, + ModulusType > NonMaxRemovalByDirectionFilterType; + + typedef VectorizationPathListFilter< + ModulusType, + DirectionType, + OutputPathType > VectorizationPathListFilterType; + + typedef SimplifyPathListFilter<OutputPathType> SimplifyPathListFilterType; + typedef BreakAngularPathListFilter<OutputPathType> BreakAngularPathListFilterType; + typedef RemoveTortuousPathListFilter<OutputPathType> RemoveTortuousPathListFilterType; + typedef LinkPathListFilter<OutputPathType> LinkPathListFilterType; + typedef LikehoodPathListFilter<OutputPathType, ModulusType> LikehoodPathListFilterType; + + /** Template parameters typedefs for internals filters */ + typedef typename GradientFilterType::RealType SigmaType; + typedef typename VectorizationPathListFilterType::InputPixelType AmplitudeThresholdType; + typedef typename SimplifyPathListFilterType::ToleranceType ToleranceType; + typedef typename BreakAngularPathListFilterType::MaxAngleType MaxAngleType; + typedef typename RemoveTortuousPathListFilterType::MeanDistanceThresholdType MeanDistanceThresholdType; + typedef typename LinkPathListFilterType::RealType LinkRealType; + + + /** Get/Set the alpha value */ + itkGetConstReferenceMacro(Alpha,double); + itkSetMacro(Alpha,double); + + /** Get/Set the amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/ + itkSetMacro(AmplitudeThreshold,AmplitudeThresholdType); + itkGetMacro(AmplitudeThreshold,AmplitudeThresholdType); + + /** Get/Set the tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathListFilter)*/ + itkGetMacro(Tolerance,ToleranceType); + itkSetMacro(Tolerance,ToleranceType); + + /** Set/Get the max angle (use bye the BreakAngularPathListFilter)*/ + itkSetMacro(MaxAngle,MaxAngleType); + itkGetConstMacro(MaxAngle,MaxAngleType); + + /** Get/Set the tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathListFilter)*/ + itkGetMacro(FirstMeanDistanceThreshold,MeanDistanceThresholdType); + itkSetMacro(FirstMeanDistanceThreshold,MeanDistanceThresholdType); + itkGetMacro(SecondMeanDistanceThreshold,MeanDistanceThresholdType); + itkSetMacro(SecondMeanDistanceThreshold,MeanDistanceThresholdType); + + /** Get/Set the angular threshold (use by LinkPathFilter)*/ + itkSetMacro(AngularThreshold,LinkRealType); + itkGetMacro(AngularThreshold,LinkRealType); + /** Get/Set the distance threshold (use by LinkPathFilter)*/ + itkSetMacro(DistanceThreshold,LinkRealType); + itkGetMacro(DistanceThreshold,LinkRealType); + + + protected: + /** Constructor */ + GenericRoadExtractionFilter(); + /** Destructor */ + ~GenericRoadExtractionFilter() {}; + + /** Prepare main computation method */ + void BeforeGenerateData(void); + + /** Main computation method */ + void GenerateData(void); + /** PrintSelf method */ + void PrintSelf(std::ostream& os, itk::Indent indent) const; + + private : + + GenericRoadExtractionFilter(const Self&); // purposely not implemented + void operator=(const Self&); // purposely not implemented + + + typename SquareRootImageFilterType::Pointer m_SquareRootImageFilter; + typename GradientFilterType::Pointer m_GradientFilter; + typename NeighborhoodScalarProductFilterType::Pointer m_NeighborhoodScalarProductFilter; + typename RemoveIsolatedByDirectionFilterType::Pointer m_RemoveIsolatedByDirectionFilter; + typename RemoveWrongDirectionFilterType::Pointer m_RemoveWrongDirectionFilter; + typename NonMaxRemovalByDirectionFilterType::Pointer m_NonMaxRemovalByDirectionFilter; + typename VectorizationPathListFilterType::Pointer m_VectorizationPathListFilter; + typename SimplifyPathListFilterType::Pointer m_FirstSimplifyPathListFilter; + typename SimplifyPathListFilterType::Pointer m_SecondSimplifyPathListFilter; + typename BreakAngularPathListFilterType::Pointer m_BreakAngularPathListFilter; + typename RemoveTortuousPathListFilterType::Pointer m_FirstRemoveTortuousPathListFilter; + typename RemoveTortuousPathListFilterType::Pointer m_SecondRemoveTortuousPathListFilter; + typename LinkPathListFilterType::Pointer m_LinkPathListFilter; + typename LikehoodPathListFilterType::Pointer m_LikehoodPathListFilter; + + + /** Amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/ + AmplitudeThresholdType m_AmplitudeThreshold; + /** Tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathListFilter)*/ + ToleranceType m_Tolerance; + /** Max angle (use bye the BreakAngularPathListFilter)*/ + MaxAngleType m_MaxAngle; + /** Tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathListFilter)*/ + MeanDistanceThresholdType m_FirstMeanDistanceThreshold; + MeanDistanceThresholdType m_SecondMeanDistanceThreshold; + /** The angular threshold (use by LinkPathListFilter) */ + LinkRealType m_AngularThreshold; + + /** The distance threshold (use by LinkPathListFilter) */ + double m_DistanceThreshold; + + /** Alpha. Use to calculate the sigma value used by the GradientRecursiveGaussianImageFilter */ + double m_Alpha; + + /** Resolution of the image. Use to calculate the sigma value used by the GradientRecursiveGaussianImageFilter + and the m_DistanceThreshold value used by the LinkPathListFilter + This value is set bye the image's spacing.*/ + double m_Resolution; + + }; + +}// End namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbGenericRoadExtractionFilter.txx" +#endif + +#endif diff --git a/Code/FeatureExtraction/otbGenericRoadExtractionFilter.txx b/Code/FeatureExtraction/otbGenericRoadExtractionFilter.txx new file mode 100644 index 0000000000000000000000000000000000000000..5ad1b49f699b1a090ceb5ade4091552ea46dbd2f --- /dev/null +++ b/Code/FeatureExtraction/otbGenericRoadExtractionFilter.txx @@ -0,0 +1,188 @@ +/*========================================================================= + + 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 __otbGenericRoadExtractionFilter_txx +#define __otbGenericRoadExtractionFilter_txx + +#include "otbGenericRoadExtractionFilter.h" +#include "otbMath.h" + +namespace otb +{ +/** + * Constructor + */ +template <class TInputImage,class TOutputPath> +GenericRoadExtractionFilter<TInputImage, TOutputPath> +::GenericRoadExtractionFilter() +{ + this->SetNumberOfRequiredInputs(1); + this->SetNumberOfRequiredOutputs(1); + + m_SquareRootImageFilter = SquareRootImageFilterType::New(); + m_GradientFilter = GradientFilterType::New(); + m_NeighborhoodScalarProductFilter = NeighborhoodScalarProductFilterType::New(); + m_RemoveIsolatedByDirectionFilter = RemoveIsolatedByDirectionFilterType::New(); + m_RemoveWrongDirectionFilter = RemoveWrongDirectionFilterType::New(); + m_NonMaxRemovalByDirectionFilter = NonMaxRemovalByDirectionFilterType::New(); + m_VectorizationPathListFilter = VectorizationPathListFilterType::New(); + m_FirstSimplifyPathListFilter = SimplifyPathListFilterType::New(); + m_SecondSimplifyPathListFilter = SimplifyPathListFilterType::New(); + m_BreakAngularPathListFilter = BreakAngularPathListFilterType::New(); + m_FirstRemoveTortuousPathListFilter = RemoveTortuousPathListFilterType::New(); + m_SecondRemoveTortuousPathListFilter = RemoveTortuousPathListFilterType::New(); + m_LinkPathListFilter = LinkPathListFilterType::New(); + m_LikehoodPathListFilter = LikehoodPathListFilterType::New(); + + /** Amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/ + m_AmplitudeThreshold = static_cast<AmplitudeThresholdType>(1.); + /** Tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathFilter)*/ + m_Tolerance = static_cast<ToleranceType>(1.); + /** Max angle (use bye the BreakAngularPathListFilter)*/ + m_MaxAngle = static_cast<MaxAngleType>(M_PI/8.); + /** Tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathFilter)*/ + m_FirstMeanDistanceThreshold = static_cast<MeanDistanceThresholdType>(1.); + m_SecondMeanDistanceThreshold = static_cast<MeanDistanceThresholdType>(10.); + /** The angular threshold (use by LinkPathFilter) */ + m_AngularThreshold = static_cast<LinkRealType>(M_PI/8.); + + /** The distance threshold (use by LinkPathFilter) */ + m_DistanceThreshold = 25.; + + /** Alpha value */ + /** Use to calculate the sigma value use by the GradientRecursiveGaussianImageFilter */ + m_Alpha = 0.; + + /** Resolution of the image */ + m_Resolution = 1.; +} +/** + * Prepare main computation method + */ +template <class TInputImage,class TOutputPath> +void +GenericRoadExtractionFilter<TInputImage, TOutputPath> +::BeforeGenerateData() +{ + /** Calculation of resolution value */ + typename InputImageType::SpacingType spacing = this->GetInput()->GetSpacing(); + // Getting x Spacing for the resolution + m_Resolution = static_cast<double>(spacing[0]); + if( m_Resolution == 0. ) + { + itkWarningMacro(<< "The image spacing is zero. So the resolution used in the filter is forced to 1."); + m_Resolution = 1.; + } + +} + +/** + * Main computation method + */ +template <class TInputImage,class TOutputPath> +void +GenericRoadExtractionFilter<TInputImage, TOutputPath> +::GenerateData() +{ + // // Input images pointers + typename InputImageType::ConstPointer inputImage = this->GetInput(); + typename OutputPathListType::Pointer outputPathList = this->GetOutput(); + + /////////////////////////////////////// + //// Algorithm for road extraction //// + /////////////////////////////////////// + + // + + m_SquareRootImageFilter->SetInput(inputImage); + + m_GradientFilter->SetInput(m_SquareRootImageFilter->GetOutput()); + /** Sigma calculated with the alpha and image resolution parameters */ + m_GradientFilter->SetSigma(static_cast<SigmaType>(m_Alpha * (1.2/m_Resolution + 1.) )); + + m_NeighborhoodScalarProductFilter->SetInput(m_GradientFilter->GetOutput()); + + m_RemoveIsolatedByDirectionFilter->SetInput(m_NeighborhoodScalarProductFilter->GetOutput()); + m_RemoveIsolatedByDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection()); + + m_RemoveWrongDirectionFilter->SetInput(m_RemoveIsolatedByDirectionFilter->GetOutput()); + m_RemoveWrongDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection()); + + m_NonMaxRemovalByDirectionFilter->SetInput(m_RemoveWrongDirectionFilter->GetOutput()); + m_NonMaxRemovalByDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection()); + + m_VectorizationPathListFilter->SetInput(m_NonMaxRemovalByDirectionFilter->GetOutput()); + m_VectorizationPathListFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection()); + m_VectorizationPathListFilter->SetAmplitudeThreshold(m_AmplitudeThreshold); + + m_FirstSimplifyPathListFilter->SetInput(m_VectorizationPathListFilter->GetOutput()); + m_FirstSimplifyPathListFilter->SetTolerance(m_Tolerance); + + m_BreakAngularPathListFilter->SetInput(m_FirstSimplifyPathListFilter->GetOutput()); + m_BreakAngularPathListFilter->SetMaxAngle(m_MaxAngle); + + m_FirstRemoveTortuousPathListFilter->SetInput(m_BreakAngularPathListFilter->GetOutput()); + m_FirstRemoveTortuousPathListFilter->SetMeanDistanceThreshold(m_FirstMeanDistanceThreshold); + + m_LinkPathListFilter->SetInput(m_FirstRemoveTortuousPathListFilter->GetOutput()); + m_LinkPathListFilter->SetAngularThreshold(m_AngularThreshold); + m_LinkPathListFilter->SetDistanceThreshold( static_cast<LinkRealType>(m_DistanceThreshold/m_Resolution) ); + + m_SecondSimplifyPathListFilter->SetInput(m_LinkPathListFilter->GetOutput()); + m_SecondSimplifyPathListFilter->SetTolerance(m_Tolerance); + + m_SecondRemoveTortuousPathListFilter->SetInput(m_SecondSimplifyPathListFilter->GetOutput()); + m_SecondRemoveTortuousPathListFilter->SetMeanDistanceThreshold(m_SecondMeanDistanceThreshold); + + m_LikehoodPathListFilter->SetInput(m_SecondRemoveTortuousPathListFilter->GetOutput()); + m_LikehoodPathListFilter->SetInputImage(m_NonMaxRemovalByDirectionFilter->GetOutput()); + + // Graft output seems to be broken for PolylineParametricPath + // So we use update, and copy the path to the output path list. + // m_LikehoodPathListFilter->GraftOutput(this->GetOutput()); + m_LikehoodPathListFilter->Update(); + // outputPathList = m_LikehoodPathListFilter->GetOutput(); + for(typename LikehoodPathListFilterType::PathListType::ConstIterator it + = m_LikehoodPathListFilter->GetOutput()->Begin(); + it!=m_LikehoodPathListFilter->GetOutput()->End(); + ++it) + { + outputPathList->PushBack(it.Get()); + } +} +/** + * PrintSelf method + */ +template <class TInputImage,class TOutputPath> +void +GenericRoadExtractionFilter<TInputImage, TOutputPath> +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os,indent); + os << indent << "m_Alpha:"<< m_Alpha << std::endl; + os << indent << "m_Resolution:"<< m_Resolution << std::endl; + os << indent << "m_AmplitudeThreshold: "<< m_AmplitudeThreshold << std::endl; + os << indent << "m_Tolerance: "<< m_Tolerance << std::endl; + os << indent << "m_MaxAngle: "<< m_MaxAngle << std::endl; + os << indent << "m_FirstMeanDistanceThreshold: "<< m_FirstMeanDistanceThreshold << std::endl; + os << indent << "m_SecondMeanDistanceThreshold: "<< m_SecondMeanDistanceThreshold << std::endl; + os << indent << "m_DistanceThreshold: "<<m_DistanceThreshold<< std::endl; + os << indent << "m_AngularThreshold: "<<m_AngularThreshold<< std::endl; + +} +} // End namespace otb +#endif diff --git a/Code/FeatureExtraction/otbRoadExtractionFilter.h b/Code/FeatureExtraction/otbRoadExtractionFilter.h index 600081c3b01efdafc409c72e2c3b55a041992d81..f4ee3db0e126df89ba73483e7763b4df593fe1e9 100644 --- a/Code/FeatureExtraction/otbRoadExtractionFilter.h +++ b/Code/FeatureExtraction/otbRoadExtractionFilter.h @@ -25,17 +25,7 @@ PURPOSE. See the above copyright notices for more information. #include "otbVectorImage.h" #include "otbImageToPathListFilter.h" #include "otbSpectralAngleDistanceImageFilter.h" -#include "itkSqrtImageFilter.h" -#include "otbNeighborhoodScalarProductFilter.h" -#include "otbNonMaxRemovalByDirectionFilter.h" -#include "otbVectorizationPathListFilter.h" -#include "otbSimplifyPathListFilter.h" -#include "otbBreakAngularPathListFilter.h" -#include "otbRemoveTortuousPathListFilter.h" -#include "otbLinkPathListFilter.h" -#include "otbRemoveIsolatedByDirectionFilter.h" -#include "otbRemoveWrongDirectionFilter.h" -#include "otbLikehoodPathListFilter.h" +#include "otbGenericRoadExtractionFilter.h" namespace otb { @@ -68,6 +58,7 @@ namespace otb * \sa RemoveTortuousPathListFilter * \sa LinkPathListFilter * \sa LikehoodPathListFilter + * \sa GenericRoadExtractionFilter */ template <class TInputImage, class TOutputPath> class ITK_EXPORT RoadExtractionFilter @@ -104,86 +95,50 @@ template <class TInputImage, class TOutputPath> InputImageType, SpectralAngleType> SpectralAngleDistanceImageFilterType; - typedef itk::SqrtImageFilter< - SpectralAngleType, - SpectralAngleType> SquareRootImageFilterType; - - typedef itk::GradientRecursiveGaussianImageFilter< - SpectralAngleType, - CovariantVectorImageType> GradientFilterType; - - typedef NeighborhoodScalarProductFilter< - CovariantVectorImageType, - ModulusType, - DirectionType> NeighborhoodScalarProductFilterType; - - typedef RemoveIsolatedByDirectionFilter< - ModulusType, - DirectionType, - ModulusType > RemoveIsolatedByDirectionFilterType; - - typedef RemoveWrongDirectionFilter< - ModulusType, - DirectionType, - ModulusType> RemoveWrongDirectionFilterType; - - typedef NonMaxRemovalByDirectionFilter< - ModulusType, - DirectionType, - ModulusType > NonMaxRemovalByDirectionFilterType; - - typedef VectorizationPathListFilter< - ModulusType, - DirectionType, - OutputPathType > VectorizationPathListFilterType; - - typedef SimplifyPathListFilter<OutputPathType> SimplifyPathListFilterType; - typedef BreakAngularPathListFilter<OutputPathType> BreakAngularPathListFilterType; - typedef RemoveTortuousPathListFilter<OutputPathType> RemoveTortuousPathListFilterType; - typedef LinkPathListFilter<OutputPathType> LinkPathListFilterType; - typedef LikehoodPathListFilter<OutputPathType, ModulusType> LikehoodPathListFilterType; + typedef GenericRoadExtractionFilter<SpectralAngleType, OutputPathType> + GenericRoadExtractionFilterType; + /** Template parameters typedefs for internals filters */ - typedef typename GradientFilterType::RealType SigmaType; - typedef typename VectorizationPathListFilterType::InputPixelType AmplitudeThresholdType; - typedef typename SimplifyPathListFilterType::ToleranceType ToleranceType; - typedef typename BreakAngularPathListFilterType::MaxAngleType MaxAngleType; - typedef typename RemoveTortuousPathListFilterType::MeanDistanceThresholdType MeanDistanceThresholdType; - typedef typename LinkPathListFilterType::RealType LinkRealType; + typedef typename GenericRoadExtractionFilterType::SigmaType SigmaType; + typedef typename GenericRoadExtractionFilterType::AmplitudeThresholdType AmplitudeThresholdType; + typedef typename GenericRoadExtractionFilterType::ToleranceType ToleranceType; + typedef typename GenericRoadExtractionFilterType::MaxAngleType MaxAngleType; + typedef typename GenericRoadExtractionFilterType::MeanDistanceThresholdType MeanDistanceThresholdType; + typedef typename GenericRoadExtractionFilterType::LinkRealType LinkRealType; /** Get/Set the reference pixel (use by the SpectralAngleDistanceImageFilter)*/ - itkGetConstReferenceMacro(ReferencePixel,InputPixelType); - itkSetMacro(ReferencePixel,InputPixelType); + otbGetObjectMemberConstReferenceMacro(SpectralAngleDistanceImageFilter,ReferencePixel,InputPixelType); + otbSetObjectMemberMacro(SpectralAngleDistanceImageFilter,ReferencePixel,InputPixelType); /** Get/Set the alpha value */ - itkGetConstReferenceMacro(Alpha,double); - itkSetMacro(Alpha,double); + otbGetObjectMemberConstReferenceMacro(GenericRoadExtractionFilter,Alpha,double); + otbSetObjectMemberMacro(GenericRoadExtractionFilter,Alpha,double); /** Get/Set the amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/ - itkSetMacro(AmplitudeThreshold,AmplitudeThresholdType); - itkGetMacro(AmplitudeThreshold,AmplitudeThresholdType); + otbSetObjectMemberMacro(GenericRoadExtractionFilter,AmplitudeThreshold,AmplitudeThresholdType); + otbGetObjectMemberMacro(GenericRoadExtractionFilter,AmplitudeThreshold,AmplitudeThresholdType); /** Get/Set the tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathListFilter)*/ - itkGetMacro(Tolerance,ToleranceType); - itkSetMacro(Tolerance,ToleranceType); + otbGetObjectMemberMacro(GenericRoadExtractionFilter,Tolerance,ToleranceType); + otbSetObjectMemberMacro(GenericRoadExtractionFilter,Tolerance,ToleranceType); /** Set/Get the max angle (use bye the BreakAngularPathListFilter)*/ - itkSetMacro(MaxAngle,MaxAngleType); - itkGetConstMacro(MaxAngle,MaxAngleType); + otbSetObjectMemberMacro(GenericRoadExtractionFilter,MaxAngle,MaxAngleType); + otbGetObjectMemberConstMacro(GenericRoadExtractionFilter,MaxAngle,MaxAngleType); /** Get/Set the tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathListFilter)*/ - itkGetMacro(FirstMeanDistanceThreshold,MeanDistanceThresholdType); - itkSetMacro(FirstMeanDistanceThreshold,MeanDistanceThresholdType); - itkGetMacro(SecondMeanDistanceThreshold,MeanDistanceThresholdType); - itkSetMacro(SecondMeanDistanceThreshold,MeanDistanceThresholdType); + otbGetObjectMemberMacro(GenericRoadExtractionFilter,FirstMeanDistanceThreshold,MeanDistanceThresholdType); + otbSetObjectMemberMacro(GenericRoadExtractionFilter,FirstMeanDistanceThreshold,MeanDistanceThresholdType); + otbGetObjectMemberMacro(GenericRoadExtractionFilter,SecondMeanDistanceThreshold,MeanDistanceThresholdType); + otbSetObjectMemberMacro(GenericRoadExtractionFilter,SecondMeanDistanceThreshold,MeanDistanceThresholdType); /** Get/Set the angular threshold (use by LinkPathFilter)*/ - itkSetMacro(AngularThreshold,LinkRealType); - itkGetMacro(AngularThreshold,LinkRealType); + otbSetObjectMemberMacro(GenericRoadExtractionFilter,AngularThreshold,LinkRealType); + otbGetObjectMemberMacro(GenericRoadExtractionFilter,AngularThreshold,LinkRealType); /** Get/Set the distance threshold (use by LinkPathFilter)*/ - itkSetMacro(DistanceThreshold,LinkRealType); - itkGetMacro(DistanceThreshold,LinkRealType); - + otbSetObjectMemberMacro(GenericRoadExtractionFilter,DistanceThreshold,LinkRealType); + otbGetObjectMemberMacro(GenericRoadExtractionFilter,DistanceThreshold,LinkRealType); protected: /** Constructor */ @@ -206,45 +161,11 @@ template <class TInputImage, class TOutputPath> /** SpectralAngleDistanceImageFilter use by the composite filter */ typename SpectralAngleDistanceImageFilterType::Pointer m_SpectralAngleDistanceImageFilter; - typename SquareRootImageFilterType::Pointer m_SquareRootImageFilter; - typename GradientFilterType::Pointer m_GradientFilter; - typename NeighborhoodScalarProductFilterType::Pointer m_NeighborhoodScalarProductFilter; - typename RemoveIsolatedByDirectionFilterType::Pointer m_RemoveIsolatedByDirectionFilter; - typename RemoveWrongDirectionFilterType::Pointer m_RemoveWrongDirectionFilter; - typename NonMaxRemovalByDirectionFilterType::Pointer m_NonMaxRemovalByDirectionFilter; - typename VectorizationPathListFilterType::Pointer m_VectorizationPathListFilter; - typename SimplifyPathListFilterType::Pointer m_FirstSimplifyPathListFilter; - typename SimplifyPathListFilterType::Pointer m_SecondSimplifyPathListFilter; - typename BreakAngularPathListFilterType::Pointer m_BreakAngularPathListFilter; - typename RemoveTortuousPathListFilterType::Pointer m_FirstRemoveTortuousPathListFilter; - typename RemoveTortuousPathListFilterType::Pointer m_SecondRemoveTortuousPathListFilter; - typename LinkPathListFilterType::Pointer m_LinkPathListFilter; - typename LikehoodPathListFilterType::Pointer m_LikehoodPathListFilter; + typename GenericRoadExtractionFilterType::Pointer m_GenericRoadExtractionFilter; /** The reference pixel (use by the SpectralAngleDistanceImageFilter)*/ - InputPixelType m_ReferencePixel; - /** Amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/ - AmplitudeThresholdType m_AmplitudeThreshold; - /** Tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathListFilter)*/ - ToleranceType m_Tolerance; - /** Max angle (use bye the BreakAngularPathListFilter)*/ - MaxAngleType m_MaxAngle; - /** Tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathListFilter)*/ - MeanDistanceThresholdType m_FirstMeanDistanceThreshold; - MeanDistanceThresholdType m_SecondMeanDistanceThreshold; - /** The angular threshold (use by LinkPathListFilter) */ - LinkRealType m_AngularThreshold; - - /** The distance threshold (use by LinkPathListFilter) */ - double m_DistanceThreshold; - - /** Alpha. Use to calculate the sigma value used by the GradientRecursiveGaussianImageFilter */ - double m_Alpha; +// InputPixelType m_ReferencePixel; - /** Resolution of the image. Use to calculate the sigma value used by the GradientRecursiveGaussianImageFilter - and the m_DistanceThreshold value used by the LinkPathListFilter - This value is set bye the image's spacing.*/ - double m_Resolution; }; diff --git a/Code/FeatureExtraction/otbRoadExtractionFilter.txx b/Code/FeatureExtraction/otbRoadExtractionFilter.txx index 037e46ec29e155001644ba7d12533a9cbf08e453..7a7f5728677aee6ea59c5fae19415993deca253f 100644 --- a/Code/FeatureExtraction/otbRoadExtractionFilter.txx +++ b/Code/FeatureExtraction/otbRoadExtractionFilter.txx @@ -34,62 +34,10 @@ RoadExtractionFilter<TInputImage, TOutputPath> this->SetNumberOfRequiredOutputs(1); m_SpectralAngleDistanceImageFilter = SpectralAngleDistanceImageFilterType::New(); - m_SquareRootImageFilter = SquareRootImageFilterType::New(); - m_GradientFilter = GradientFilterType::New(); - m_NeighborhoodScalarProductFilter = NeighborhoodScalarProductFilterType::New(); - m_RemoveIsolatedByDirectionFilter = RemoveIsolatedByDirectionFilterType::New(); - m_RemoveWrongDirectionFilter = RemoveWrongDirectionFilterType::New(); - m_NonMaxRemovalByDirectionFilter = NonMaxRemovalByDirectionFilterType::New(); - m_VectorizationPathListFilter = VectorizationPathListFilterType::New(); - m_FirstSimplifyPathListFilter = SimplifyPathListFilterType::New(); - m_SecondSimplifyPathListFilter = SimplifyPathListFilterType::New(); - m_BreakAngularPathListFilter = BreakAngularPathListFilterType::New(); - m_FirstRemoveTortuousPathListFilter = RemoveTortuousPathListFilterType::New(); - m_SecondRemoveTortuousPathListFilter = RemoveTortuousPathListFilterType::New(); - m_LinkPathListFilter = LinkPathListFilterType::New(); - m_LikehoodPathListFilter = LikehoodPathListFilterType::New(); + m_GenericRoadExtractionFilter = GenericRoadExtractionFilterType::New(); - /** Amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/ - m_AmplitudeThreshold = static_cast<AmplitudeThresholdType>(1.); - /** Tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathFilter)*/ - m_Tolerance = static_cast<ToleranceType>(1.); - /** Max angle (use bye the BreakAngularPathListFilter)*/ - m_MaxAngle = static_cast<MaxAngleType>(M_PI/8.); - /** Tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathFilter)*/ - m_FirstMeanDistanceThreshold = static_cast<MeanDistanceThresholdType>(1.); - m_SecondMeanDistanceThreshold = static_cast<MeanDistanceThresholdType>(10.); - /** The angular threshold (use by LinkPathFilter) */ - m_AngularThreshold = static_cast<LinkRealType>(M_PI/8.); - - /** The distance threshold (use by LinkPathFilter) */ - m_DistanceThreshold = 25.; - - /** Alpha value */ - /** Use to calculate the sigma value use by the GradientRecursiveGaussianImageFilter */ - m_Alpha = 0.; - - /** Resolution of the image */ - m_Resolution = 1.; } -/** - * Prepare main computation method - */ -template <class TInputImage,class TOutputPath> -void -RoadExtractionFilter<TInputImage, TOutputPath> -::BeforeGenerateData() -{ - /** Calculation of resolution value */ - typename InputImageType::SpacingType spacing = this->GetInput()->GetSpacing(); - // Getting x Spacing for the resolution - m_Resolution = static_cast<double>(spacing[0]); - if( m_Resolution == 0. ) - { - itkWarningMacro(<< "The image spacing is zero. So the resolution used in the filter is forced to 1."); - m_Resolution = 1.; - } -} /** * Main computation method @@ -99,69 +47,20 @@ void RoadExtractionFilter<TInputImage, TOutputPath> ::GenerateData() { - // // Input images pointers + // Input images pointers typename InputImageType::ConstPointer inputImage = this->GetInput(); typename OutputPathListType::Pointer outputPathList = this->GetOutput(); - /////////////////////////////////////// - //// Algorithm for road extraction //// - /////////////////////////////////////// - // m_SpectralAngleDistanceImageFilter->SetInput(inputImage); - m_SpectralAngleDistanceImageFilter->SetReferencePixel(m_ReferencePixel); +// m_SpectralAngleDistanceImageFilter->SetReferencePixel(m_ReferencePixel); - m_SquareRootImageFilter->SetInput(m_SpectralAngleDistanceImageFilter->GetOutput()); - - m_GradientFilter->SetInput(m_SquareRootImageFilter->GetOutput()); - /** Sigma calculated with the alpha and image resolution parameters */ - m_GradientFilter->SetSigma(static_cast<SigmaType>(m_Alpha * (1.2/m_Resolution + 1.) )); - - m_NeighborhoodScalarProductFilter->SetInput(m_GradientFilter->GetOutput()); + m_GenericRoadExtractionFilter->SetInput(m_SpectralAngleDistanceImageFilter->GetOutput()); - m_RemoveIsolatedByDirectionFilter->SetInput(m_NeighborhoodScalarProductFilter->GetOutput()); - m_RemoveIsolatedByDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection()); - - m_RemoveWrongDirectionFilter->SetInput(m_RemoveIsolatedByDirectionFilter->GetOutput()); - m_RemoveWrongDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection()); - - m_NonMaxRemovalByDirectionFilter->SetInput(m_RemoveWrongDirectionFilter->GetOutput()); - m_NonMaxRemovalByDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection()); - - m_VectorizationPathListFilter->SetInput(m_NonMaxRemovalByDirectionFilter->GetOutput()); - m_VectorizationPathListFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection()); - m_VectorizationPathListFilter->SetAmplitudeThreshold(m_AmplitudeThreshold); - - m_FirstSimplifyPathListFilter->SetInput(m_VectorizationPathListFilter->GetOutput()); - m_FirstSimplifyPathListFilter->SetTolerance(m_Tolerance); - - m_BreakAngularPathListFilter->SetInput(m_FirstSimplifyPathListFilter->GetOutput()); - m_BreakAngularPathListFilter->SetMaxAngle(m_MaxAngle); - - m_FirstRemoveTortuousPathListFilter->SetInput(m_BreakAngularPathListFilter->GetOutput()); - m_FirstRemoveTortuousPathListFilter->SetMeanDistanceThreshold(m_FirstMeanDistanceThreshold); - - m_LinkPathListFilter->SetInput(m_FirstRemoveTortuousPathListFilter->GetOutput()); - m_LinkPathListFilter->SetAngularThreshold(m_AngularThreshold); - m_LinkPathListFilter->SetDistanceThreshold( static_cast<LinkRealType>(m_DistanceThreshold/m_Resolution) ); - - m_SecondSimplifyPathListFilter->SetInput(m_LinkPathListFilter->GetOutput()); - m_SecondSimplifyPathListFilter->SetTolerance(m_Tolerance); - - m_SecondRemoveTortuousPathListFilter->SetInput(m_SecondSimplifyPathListFilter->GetOutput()); - m_SecondRemoveTortuousPathListFilter->SetMeanDistanceThreshold(m_SecondMeanDistanceThreshold); - - m_LikehoodPathListFilter->SetInput(m_SecondRemoveTortuousPathListFilter->GetOutput()); - m_LikehoodPathListFilter->SetInputImage(m_NonMaxRemovalByDirectionFilter->GetOutput()); - - // Graft output seems to be broken for PolylineParametricPath - // So we use update, and copy the path to the output path list. - // m_LikehoodPathListFilter->GraftOutput(this->GetOutput()); - m_LikehoodPathListFilter->Update(); - // outputPathList = m_LikehoodPathListFilter->GetOutput(); - for(typename LikehoodPathListFilterType::PathListType::ConstIterator it - = m_LikehoodPathListFilter->GetOutput()->Begin(); - it!=m_LikehoodPathListFilter->GetOutput()->End(); + m_GenericRoadExtractionFilter->Update(); + for(typename GenericRoadExtractionFilterType::OutputPathListType::ConstIterator it + = m_GenericRoadExtractionFilter->GetOutput()->Begin(); + it!=m_GenericRoadExtractionFilter->GetOutput()->End(); ++it) { outputPathList->PushBack(it.Get()); @@ -176,17 +75,8 @@ RoadExtractionFilter<TInputImage, TOutputPath> ::PrintSelf(std::ostream& os, itk::Indent indent) const { Superclass::PrintSelf(os,indent); - os << indent << "m_Alpha:"<< m_Alpha << std::endl; - os << indent << "m_Resolution:"<< m_Resolution << std::endl; - os << indent << "m_ReferencePixel: "<< m_ReferencePixel << std::endl; - os << indent << "m_AmplitudeThreshold: "<< m_AmplitudeThreshold << std::endl; - os << indent << "m_Tolerance: "<< m_Tolerance << std::endl; - os << indent << "m_MaxAngle: "<< m_MaxAngle << std::endl; - os << indent << "m_FirstMeanDistanceThreshold: "<< m_FirstMeanDistanceThreshold << std::endl; - os << indent << "m_SecondMeanDistanceThreshold: "<< m_SecondMeanDistanceThreshold << std::endl; - os << indent << "m_DistanceThreshold: "<<m_DistanceThreshold<< std::endl; - os << indent << "m_AngularThreshold: "<<m_AngularThreshold<< std::endl; - + os << indent << "m_ReferencePixel: "<< m_SpectralAngleDistanceImageFilter->GetReferencePixel() << std::endl; } + } // End namespace otb #endif