diff --git a/Code/FeatureExtraction/otbMaskedScalarImageToGreyLevelCoocurenceMatrixGenerator.h b/Code/FeatureExtraction/otbMaskedScalarImageToGreyLevelCoocurenceMatrixGenerator.h new file mode 100644 index 0000000000000000000000000000000000000000..4c787065f2bcf6d99247d1b4bee0bf17049b2325 --- /dev/null +++ b/Code/FeatureExtraction/otbMaskedScalarImageToGreyLevelCoocurenceMatrixGenerator.h @@ -0,0 +1,91 @@ +/*========================================================================= + + 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 __otbMaskedScalarImageToGreyLevelCoocurrenceMatrixGenerator_h +#define __otbMaskedScalarImageToGreyLevelCoocurrenceMatrixGenerator_h + +#include "itkMaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator.h" +#include "otbMacro.h" + +namespace otb +{ + /** \class MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator + * \brief This class extends the ITK version by providing matrix estimation on a sub-region. + * + * This class compute the co-occurence matrix over a given region of the image. The region can be set + * using the SetRegion()/GetRegion() methods. + * + * \sa itk::MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator + */ +template <class TImage, class THistogramFrequencyContainer = itk::Statistics::DenseFrequencyContainer > +class MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator + : public itk::Statistics::MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator<TImage,THistogramFrequencyContainer> +{ +public: + /** Standard class typedef */ + typedef MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator Self; + typedef itk::Statistics::MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator + <TImage,THistogramFrequencyContainer> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Creation through object factory */ + itkNewMacro(Self); + + /** RTTI */ + itkTypeMacro(MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator, + itk::MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator); + + /** Superclass typedefs */ + typedef TImage ImageType; + typedef typename ImageType::RegionType RegionType; + typedef typename Superclass::RadiusType RadiusType; + + /** Set/Get the region on which the co-occurence matrix is computed */ + itkSetMacro(Region,RegionType); + itkGetMacro(Region,RegionType); + +protected: + /** Constructor */ + MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator() : m_Region() {} + /** Destructor */ + ~MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator(){} + + /** Overload this method to restrict co-occurence to the given region */ + virtual void FillHistogram(RadiusType radius, RegionType region) + { + // Check that region is inside the requested region + RegionType subregion = m_Region; + + if(subregion.Crop(region)) + { + // If so, call superclass FillHistogram implementation + this->Superclass::FillHistogram(radius,subregion); + } + } + +private: + MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + /** Region on which to compute co-occurence */ + RegionType m_Region; + + +}; +} // End namespace otb + #endif diff --git a/Code/FeatureExtraction/otbScalarImageToTexturesFilter.h b/Code/FeatureExtraction/otbScalarImageToTexturesFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..f534fecc079916b32dc0d4cba9bdd309293dd103 --- /dev/null +++ b/Code/FeatureExtraction/otbScalarImageToTexturesFilter.h @@ -0,0 +1,160 @@ +/*========================================================================= + + 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 __otb_ScalarImageToTexturesFilter_h +#define __otb_ScalarImageToTexturesFilter_h + +#include "itkImageToImageFilter.h" + +#include "otbMaskedScalarImageToGreyLevelCoocurenceMatrixGenerator.h" +#include "itkGreyLevelCooccurrenceMatrixTextureCoefficientsCalculator.h" + +namespace otb +{ +/** \class ScalarImageToTexturesFilter + * \brief + */ + +template<class TInpuImage, class TOutputImage> +class ScalarImageToTexturesFilter : public itk::ImageToImageFilter + <TInpuImage, TOutputImage> +{ +public: + /** Standard class typedefs */ + typedef ScalarImageToTexturesFilter Self; + typedef itk::ImageToImageFilter<TInpuImage, TOutputImage> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Creation through the object factory */ + itkNewMacro(Self); + + /** RTTI */ + itkTypeMacro(ScalarImageToTexturesFilter,ImageToImageFilter); + + /** Template class typedefs */ + typedef TInpuImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointerType; + typedef typename InputImageType::PixelType InputPixelType; + typedef typename InputImageType::RegionType InputRegionType; + typedef typename InputRegionType::SizeType SizeType; + typedef TOutputImage OutputImageType; + typedef typename OutputImageType::Pointer OutputImagePointerType; + typedef typename OutputImageType::RegionType OutputRegionType; + + /** Co-occurence matrix and textures calculator */ + typedef otb::MaskedScalarImageToGreyLevelCooccurrenceMatrixGenerator + <InputImageType> CoocurrenceMatrixGeneratorType; + typedef typename CoocurrenceMatrixGeneratorType::Pointer CoocurrenceMatrixGeneratorPointerType; + typedef typename CoocurrenceMatrixGeneratorType::OffsetType OffsetType; + typedef typename CoocurrenceMatrixGeneratorType::HistogramType HistogramType; + typedef itk::Statistics::GreyLevelCooccurrenceMatrixTextureCoefficientsCalculator + <HistogramType> TextureCoefficientsCalculatorType; + typedef typename TextureCoefficientsCalculatorType::Pointer TextureCoefficientsCalculatorPointerType; + + /** Set the radius of the window on which textures will be computed */ + itkSetMacro(Radius,SizeType); + /** Get the radius of the window on which textures will be computed */ + itkGetMacro(Radius,SizeType); + + /** Set the offset for co-occurence computation */ + itkSetMacro(Offset,OffsetType); + + /** Get the offset for co-occurence computation */ + itkGetMacro(Offset,OffsetType); + + /** Set the number of bin per axis for histogram generation */ + itkSetMacro(NumberOfBinsPerAxis,unsigned int); + + /** Get the number of bin per axis for histogram generation */ + itkGetMacro(NumberOfBinsPerAxis,unsigned int); + + /** Set the input image minimum */ + itkSetMacro(InputImageMinimum,InputPixelType); + + /** Get the input image minimum */ + itkGetMacro(InputImageMinimum,InputPixelType); + + /** Set the input image maximum */ + itkSetMacro(InputImageMaximum,InputPixelType); + + /** Get the input image maximum */ + itkGetMacro(InputImageMaximum,InputPixelType); + + /** Get the energy output image */ + OutputImageType * GetEnergyOutput(); + + /** Get the entropy output image */ + OutputImageType * GetEntropyOutput(); + + /** Get the correlation output image */ + OutputImageType * GetCorrelationOutput(); + + /** Get the inverse difference moment output image */ + OutputImageType * GetInverseDifferenceMomentOutput(); + + /** Get the inertia output image */ + OutputImageType * GetInertiaOutput(); + + /** Get the cluster shade output image */ + OutputImageType * GetClusterShadeOutput(); + + /** Get the cluster prominence image */ + OutputImageType * GetClusterProminenceOutput(); + + /** Get the Haralick correlation output image */ + OutputImageType * GetHaralickCorrelationOutput(); + +protected: + /** Constructor */ + ScalarImageToTexturesFilter(); + /** Destructor */ + ~ScalarImageToTexturesFilter(); + /** Generate the input requested region */ + virtual void GenerateInputRequestedRegion(); + /** Parallel textures extraction */ + virtual void ThreadedGenerateData(const OutputRegionType & outputRegion, int threadId); + +private: + ScalarImageToTexturesFilter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + /** Convenient method to compute union of 2 regions */ + static OutputRegionType RegionUnion(const OutputRegionType & region1, const OutputRegionType & region2); + + /** Radius of the window on which to compute textures */ + SizeType m_Radius; + + /** Offset for co-occurence */ + OffsetType m_Offset; + + /** Number of bins per axis for histogram generation */ + unsigned int m_NumberOfBinsPerAxis; + + /** Input image minimum */ + InputPixelType m_InputImageMinimum; + + /** Input image maximum */ + InputPixelType m_InputImageMaximum; +}; +} // End namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbScalarImageToTexturesFilter.txx" +#endif + +#endif diff --git a/Code/FeatureExtraction/otbScalarImageToTexturesFilter.txx b/Code/FeatureExtraction/otbScalarImageToTexturesFilter.txx new file mode 100644 index 0000000000000000000000000000000000000000..5293abf07ec1ef14a2d2056e617d24bdc6100e6b --- /dev/null +++ b/Code/FeatureExtraction/otbScalarImageToTexturesFilter.txx @@ -0,0 +1,331 @@ +/*========================================================================= + + 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 __otb_ScalarImageToTexturesFilter_txx +#define __otb_ScalarImageToTexturesFilter_txx + +#include "otbScalarImageToTexturesFilter.h" +#include "itkImageRegionIteratorWithIndex.h" +#include "itkImageRegionIterator.h" +#include "itkProgressReporter.h" + +namespace otb +{ +template <class TInputImage,class TOutputImage> +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::ScalarImageToTexturesFilter() : m_Radius(), + m_Offset(), + m_NumberOfBinsPerAxis(), + m_InputImageMinimum(0), + m_InputImageMaximum(256) +{ + // There are 8 outputs corresponding to the 8 textures indices + this->SetNumberOfOutputs(8); + + // Create the 8 outputs + this->SetNthOutput(0,OutputImageType::New()); + this->SetNthOutput(1,OutputImageType::New()); + this->SetNthOutput(2,OutputImageType::New()); + this->SetNthOutput(3,OutputImageType::New()); + this->SetNthOutput(4,OutputImageType::New()); + this->SetNthOutput(5,OutputImageType::New()); + this->SetNthOutput(6,OutputImageType::New()); + this->SetNthOutput(7,OutputImageType::New()); +} + +template <class TInputImage,class TOutputImage> +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::~ScalarImageToTexturesFilter() +{} + +template <class TInputImage,class TOutputImage> +typename ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::OutputImageType * +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::GetEnergyOutput() +{ + if(this->GetNumberOfOutputs()<1) + { + return 0; + } + return static_cast<OutputImageType *>(this->GetOutput(0)); +} + +template <class TInputImage,class TOutputImage> +typename ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::OutputImageType * +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::GetEntropyOutput() +{ + if(this->GetNumberOfOutputs()<2) + { + return 0; + } + return static_cast<OutputImageType *>(this->GetOutput(1)); +} + +template <class TInputImage,class TOutputImage> +typename ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::OutputImageType * +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::GetCorrelationOutput() +{ + if(this->GetNumberOfOutputs()<3) + { + return 0; + } + return static_cast<OutputImageType *>(this->GetOutput(2)); +} + +template <class TInputImage,class TOutputImage> +typename ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::OutputImageType * +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::GetInverseDifferenceMomentOutput() +{ + if(this->GetNumberOfOutputs()<4) + { + return 0; + } + return static_cast<OutputImageType *>(this->GetOutput(3)); +} + +template <class TInputImage,class TOutputImage> +typename ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::OutputImageType * +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::GetInertiaOutput() +{ + if(this->GetNumberOfOutputs()<5) + { + return 0; + } + return static_cast<OutputImageType *>(this->GetOutput(4)); +} + +template <class TInputImage,class TOutputImage> +typename ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::OutputImageType * +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::GetClusterShadeOutput() +{ + if(this->GetNumberOfOutputs()<6) + { + return 0; + } + return static_cast<OutputImageType *>(this->GetOutput(5)); +} + +template <class TInputImage,class TOutputImage> +typename ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::OutputImageType * +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::GetClusterProminenceOutput() +{ + if(this->GetNumberOfOutputs()<7) + { + return 0; + } + return static_cast<OutputImageType *>(this->GetOutput(6)); +} + +template <class TInputImage,class TOutputImage> +typename ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::OutputImageType * +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::GetHaralickCorrelationOutput() +{ + if(this->GetNumberOfOutputs()<8) + { + return 0; + } + return static_cast<OutputImageType *>(this->GetOutput(7)); +} + +template <class TInputImage,class TOutputImage> +void +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::GenerateInputRequestedRegion() +{ + // First, call superclass implementation + Superclass::GenerateInputRequestedRegion(); + + // Retrieve the input and output pointers + InputImagePointerType inputPtr = const_cast<InputImageType *>(this->GetInput()); + OutputImagePointerType outputPtr = this->GetOutput(); + + if(!inputPtr || !outputPtr) + { + return; + } + + // Retrieve the output requested region + // We use only the first output since requested regions for all outputs are enforced to be equal + // by the default GenerateOutputRequestedRegiont() implementation + OutputRegionType outputRequestedRegion = outputPtr->GetRequestedRegion(); + + typename OutputRegionType::IndexType outputIndex = outputRequestedRegion.GetIndex(); + typename OutputRegionType::SizeType outputSize = outputRequestedRegion.GetSize(); + typename InputRegionType::IndexType inputIndex; + typename InputRegionType::SizeType inputSize; + + // First, apply offset + for(unsigned int dim = 0; dim<InputImageType::ImageDimension;++dim) + { + inputIndex[dim]=std::min(outputIndex[dim],outputIndex[dim]+m_Offset[dim]); + inputSize[dim] =std::max(outputIndex[dim]+outputSize[dim],outputIndex[dim]+outputSize[dim]+m_Offset[dim])-inputIndex[dim]; + } + + // Build the input requested region + InputRegionType inputRequestedRegion; + inputRequestedRegion.SetIndex(inputIndex); + inputRequestedRegion.SetSize(inputSize); + + // Apply the radius + inputRequestedRegion.PadByRadius(m_Radius); + + // Try to apply the requested region to the input image + if(inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion())) + { + inputPtr->SetRequestedRegion(inputRequestedRegion); + } + else + { + // Build an exception + itk::InvalidRequestedRegionError e(__FILE__,__LINE__); + e.SetLocation(ITK_LOCATION); + e.SetDescription("Requested region is (at least partially) outside the largest possible region."); + e.SetDataObject(inputPtr); + throw e; + } +} + +template <class TInputImage,class TOutputImage> +void +ScalarImageToTexturesFilter<TInputImage,TOutputImage> +::ThreadedGenerateData(const OutputRegionType & outputRegionForThread, int threadId) +{ + // Retrieve the input and output pointers + InputImagePointerType inputPtr = const_cast<InputImageType *>(this->GetInput()); + OutputImagePointerType energyPtr = this->GetEnergyOutput(); + OutputImagePointerType entropyPtr = this->GetEntropyOutput(); + OutputImagePointerType correlationPtr = this->GetCorrelationOutput(); + OutputImagePointerType invDiffMomentPtr = this->GetInverseDifferenceMomentOutput(); + OutputImagePointerType inertiaPtr = this->GetInertiaOutput(); + OutputImagePointerType clusterShadePtr = this->GetClusterShadeOutput(); + OutputImagePointerType clusterProminencePtr = this->GetClusterProminenceOutput(); + OutputImagePointerType haralickCorPtr = this->GetHaralickCorrelationOutput(); + + // Build output iterators + itk::ImageRegionIteratorWithIndex<OutputImageType> energyIt(energyPtr,outputRegionForThread); + itk::ImageRegionIterator<OutputImageType> entropyIt(entropyPtr,outputRegionForThread); + itk::ImageRegionIterator<OutputImageType> correlationIt(correlationPtr,outputRegionForThread); + itk::ImageRegionIterator<OutputImageType> invDiffMomentIt(invDiffMomentPtr,outputRegionForThread); + itk::ImageRegionIterator<OutputImageType> inertiaIt(inertiaPtr,outputRegionForThread); + itk::ImageRegionIterator<OutputImageType> clusterShadeIt(clusterShadePtr,outputRegionForThread); + itk::ImageRegionIterator<OutputImageType> clusterProminenceIt(clusterProminencePtr,outputRegionForThread); + itk::ImageRegionIterator<OutputImageType> haralickCorIt(haralickCorPtr,outputRegionForThread); + + // Go to begin + energyIt.GoToBegin(); + entropyIt.GoToBegin(); + correlationIt.GoToBegin(); + invDiffMomentIt.GoToBegin(); + inertiaIt.GoToBegin(); + clusterShadeIt.GoToBegin(); + clusterProminenceIt.GoToBegin(); + haralickCorIt.GoToBegin(); + + // Build the co-occurence matrix generator + CoocurrenceMatrixGeneratorPointerType coOccurenceMatrixGenerator = CoocurrenceMatrixGeneratorType::New(); + coOccurenceMatrixGenerator->SetInput(inputPtr); + coOccurenceMatrixGenerator->SetOffset(m_Offset); + coOccurenceMatrixGenerator->SetNumberOfBinsPerAxis(m_NumberOfBinsPerAxis); + coOccurenceMatrixGenerator->SetPixelValueMinMax(m_InputImageMinimum,m_InputImageMaximum); + + // Build the texture calculator + TextureCoefficientsCalculatorPointerType texturesCalculator = TextureCoefficientsCalculatorType::New(); + + // Set-up progress reporting + itk::ProgressReporter progress(this,threadId,outputRegionForThread.GetNumberOfPixels()); + + // Iterate on outputs to compute textures + while(!energyIt.IsAtEnd() + &&!entropyIt.IsAtEnd() + &&!correlationIt.IsAtEnd() + &&!invDiffMomentIt.IsAtEnd() + &&!inertiaIt.IsAtEnd() + &&!clusterShadeIt.IsAtEnd() + &&!clusterProminenceIt.IsAtEnd() + &&!haralickCorIt.IsAtEnd()) + { + // Find the input region on which texture will be computed + InputRegionType currentRegion; + typename InputRegionType::IndexType currentIndex = energyIt.GetIndex()-m_Radius; + typename InputRegionType::SizeType currentSize; + + for(unsigned int dim = 0; dim<InputImageType::ImageDimension;++dim) + { + // Compute current size before applying offset + currentSize[dim] = 2*m_Radius[dim]+1; + + // Apply offset + currentIndex[dim] = std::min(currentIndex[dim],currentIndex[dim]+m_Offset[dim]); + currentSize[dim] = std::max(currentIndex[dim]+currentSize[dim],currentIndex[dim]+currentSize[dim]+m_Offset[dim])-currentIndex[dim]; + } + + // Fill current region + currentRegion.SetIndex(currentIndex); + currentRegion.SetSize(currentSize); + + // Compute the co-occurence matrix + coOccurenceMatrixGenerator->SetRegion(currentRegion); + coOccurenceMatrixGenerator->Compute(); + + // Compute textures indices + texturesCalculator->SetHistogram(coOccurenceMatrixGenerator->GetOutput()); + texturesCalculator->Compute(); + + // Fill outputs + energyIt.Set(texturesCalculator->GetEnergy()); + entropyIt.Set(texturesCalculator->GetEntropy()); + correlationIt.Set(texturesCalculator->GetCorrelation()); + invDiffMomentIt.Set(texturesCalculator->GetInverseDifferenceMoment()); + inertiaIt.Set(texturesCalculator->GetInertia()); + clusterShadeIt.Set(texturesCalculator->GetClusterShade()); + clusterProminenceIt.Set(texturesCalculator->GetClusterProminence()); + haralickCorIt.Set(texturesCalculator->GetHaralickCorrelation()); + + // Update progress + progress.CompletedPixel(); + + // Increment iterators + ++energyIt; + ++entropyIt; + ++correlationIt; + ++invDiffMomentIt; + ++inertiaIt; + ++clusterShadeIt; + ++clusterProminenceIt; + ++haralickCorIt; + } + +} + +} // End namespace otb + +#endif diff --git a/Testing/Code/FeatureExtraction/CMakeLists.txt b/Testing/Code/FeatureExtraction/CMakeLists.txt index a60d28cf4b0c178918c8110c8213cb351dd200f6..f63642788d7263c0cd731ad4cf3319c0a5a2331b 100644 --- a/Testing/Code/FeatureExtraction/CMakeLists.txt +++ b/Testing/Code/FeatureExtraction/CMakeLists.txt @@ -1776,6 +1776,21 @@ ADD_TEST(feTvSqrtSpectralAngleImageFilter ${FEATUREEXTRACTION_TESTS15} 185 270 150 619 #reference pixel ) +# ------- otb::ScalarImageToTexturesFilter (Ossman)------------------------------ +ADD_TEST(feTuScalarImageToTexturesFilterNew ${FEATUREEXTRACTION_TESTS15} + otbScalarImageToTexturesfilterNew +) + +ADD_TEST(feTvScalarImageToTexturesFilter ${FEATUREEXTRACTION_TESTS15} + otbScalarImageToTexturesFilter + ${INPUTDATA}/Mire_Cosinus_500_500.png + ${TEMP}/feTvScalarImageToTexturesFilterOutput + 256 + 5 + 1 + 1 +) + # A enrichir SET(BasicFeatureExtraction_SRCS1 @@ -1955,6 +1970,8 @@ otbFeatureExtractionTests15.cxx otbImageToLineSegmentVectorDataNew.cxx otbImageToLineSegmentVectorData.cxx otbSqrtSpectralAngleImageFilter.cxx +otbScalarImageToTexturesFilterNew.cxx +otbScalarImageToTexturesFilter.cxx ) OTB_ADD_EXECUTABLE(otbFeatureExtractionTests1 "${BasicFeatureExtraction_SRCS1}" "OTBFeatureExtraction;OTBIO;OTBTesting") diff --git a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests15.cxx b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests15.cxx index adee6ddccb6b2e42b6e06b3dc21df6bb6ac5800d..0176e2601552b8b272de0b5abc1be23106099afe 100644 --- a/Testing/Code/FeatureExtraction/otbFeatureExtractionTests15.cxx +++ b/Testing/Code/FeatureExtraction/otbFeatureExtractionTests15.cxx @@ -29,4 +29,6 @@ void RegisterTests() REGISTER_TEST(otbImageToLineSegmentVectorDataNew); REGISTER_TEST(otbImageToLineSegmentVectorData); REGISTER_TEST(otbSqrtSpectralAngleImageFilter); + REGISTER_TEST(otbScalarImageToTexturesFilterNew); + REGISTER_TEST(otbScalarImageToTexturesFilter); } diff --git a/Testing/Code/FeatureExtraction/otbScalarImageToTexturesFilter.cxx b/Testing/Code/FeatureExtraction/otbScalarImageToTexturesFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..dadae54aef03e8216fb7cbf06d97dc1a92ae930a --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbScalarImageToTexturesFilter.cxx @@ -0,0 +1,135 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "itkExceptionObject.h" + +#include "otbScalarImageToTexturesFilter.h" +#include "itkMinimumMaximumImageCalculator.h" +#include "otbImage.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" +#include "otbStandardFilterWatcher.h" + +int otbScalarImageToTexturesFilter(int argc, char * argv[]) +{ + if(argc != 7) + { + std::cerr<<"Usage: "<<argv[0]<<" infname outprefix nbBins radius offsetx offsety"<<std::endl; + return EXIT_FAILURE; + } + const char * infname = argv[1]; + const char * outprefix = argv[2]; + const unsigned int nbBins = atoi(argv[3]); + const unsigned int radius = atoi(argv[4]); + const int offsetx = atoi(argv[5]); + const int offsety = atoi(argv[6]); + + const unsigned int Dimension = 2; + typedef float PixelType; + typedef otb::Image<PixelType, Dimension> ImageType; + typedef otb::ScalarImageToTexturesFilter + <ImageType,ImageType> TexturesFilterType; + typedef otb::ImageFileReader<ImageType> ReaderType; + typedef otb::ImageFileWriter<ImageType> WriterType; + typedef itk::MinimumMaximumImageCalculator + <ImageType> MinMaxCalculatorType; + + ReaderType::Pointer reader = ReaderType::New(); + TexturesFilterType::Pointer filter = TexturesFilterType::New(); + WriterType::Pointer writer = WriterType::New(); + + // Read image + reader->SetFileName(infname); + reader->Update(); + + // Build radius + TexturesFilterType::SizeType sradius; + sradius.Fill(radius); + + // Build offset + TexturesFilterType::OffsetType offset; + offset[0] = offsetx; + offset[1] = offsety; + + filter->SetInput(reader->GetOutput()); + filter->SetNumberOfBinsPerAxis(nbBins); + filter->SetRadius(sradius); + filter->SetOffset(offset); + + otb::StandardFilterWatcher watcher(filter,"Textures filter"); + + // Compute min/max + MinMaxCalculatorType::Pointer minMax = MinMaxCalculatorType::New(); + minMax->SetImage(reader->GetOutput()); + minMax->Compute(); + + filter->SetInputImageMinimum(minMax->GetMinimum()); + filter->SetInputImageMaximum(minMax->GetMaximum()); + filter->Update(); + + // Write outputs + itk::OStringStream oss; + + oss.str(""); + oss<<outprefix<<"Energy.tif"; + writer->SetInput(filter->GetEnergyOutput()); + writer->SetFileName(oss.str()); + + oss.str(""); + oss<<outprefix<<"Entropy.tif"; + writer->SetInput(filter->GetEntropyOutput()); + writer->SetFileName(oss.str()); + writer->Update(); + + oss.str(""); + oss<<outprefix<<"Correlation.tif"; + writer->SetInput(filter->GetCorrelationOutput()); + writer->SetFileName(oss.str()); + writer->Update(); + + oss.str(""); + oss<<outprefix<<"InverseDifferenceMoment.tif"; + writer->SetInput(filter->GetInverseDifferenceMomentOutput()); + writer->SetFileName(oss.str()); + writer->Update(); + + oss.str(""); + oss<<outprefix<<"Inertia.tif"; + writer->SetInput(filter->GetInertiaOutput()); + writer->SetFileName(oss.str()); + writer->Update(); + + oss.str(""); + oss<<outprefix<<"ClusterShade.tif"; + writer->SetInput(filter->GetClusterShadeOutput()); + writer->SetFileName(oss.str()); + writer->Update(); + + oss.str(""); + oss<<outprefix<<"ClusterProminence.tif"; + writer->SetInput(filter->GetClusterProminenceOutput()); + writer->SetFileName(oss.str()); + writer->Update(); + + oss.str(""); + oss<<outprefix<<"HaralickCorrelation.tif"; + writer->SetInput(filter->GetHaralickCorrelationOutput()); + writer->SetFileName(oss.str()); + writer->Update(); + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/FeatureExtraction/otbScalarImageToTexturesFilterNew.cxx b/Testing/Code/FeatureExtraction/otbScalarImageToTexturesFilterNew.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0aefa067057358c0632ac42e3ae963f067abc438 --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbScalarImageToTexturesFilterNew.cxx @@ -0,0 +1,33 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "itkExceptionObject.h" + +#include "otbScalarImageToTexturesFilter.h" +#include "otbImage.h" + +int otbScalarImageToTexturesFilterNew(int argc, char * argv[]) +{ + const unsigned int Dimension = 2; + typedef double PixelType; + typedef otb::Image<PixelType, Dimension> ImageType; + typedef otb::ScalarImageToTexturesFilter<ImageType,ImageType> FilterType; + + FilterType::Pointer filter = FilterType::New(); + + return EXIT_SUCCESS; +}