diff --git a/Code/OBIA/otbMinMaxAttributesLabelMapFilter.h b/Code/OBIA/otbMinMaxAttributesLabelMapFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..032b92609adaeed6cea29458b5636b307c540536 --- /dev/null +++ b/Code/OBIA/otbMinMaxAttributesLabelMapFilter.h @@ -0,0 +1,116 @@ +/*========================================================================= + +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 __otbMinMaxAttributesLabelMapFilter_h +#define __otbMinMaxAttributesLabelMapFilter_h + +#include <vector> +#include "itkLabelMapFilter.h" +#include "itkSimpleDataObjectDecorator.h" + +namespace otb { + +/** \class MinMaxAttributesLabelMapFilter + * \brief Computes the min/max of all attributes of a otb::LabelMap<AttributesMapLabelObject> + */ +template<class TInputImage, class TOutputImage> +class ITK_EXPORT MinMaxAttributesLabelMapFilter : + public itk::LabelMapFilter<TInputImage, TOutputImage> +{ +public: + /** Standard class typedefs. */ + typedef MinMaxAttributesLabelMapFilter Self; + typedef itk::LabelMapFilter<TInputImage, TOutputImage> + Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Some convenient typedefs. */ + typedef TInputImage InputImageType; + typedef TOutputImage OutputImageType; + typedef typename InputImageType::Pointer InputImagePointer; + typedef typename InputImageType::ConstPointer InputImageConstPointer; + typedef typename InputImageType::RegionType InputImageRegionType; + typedef typename InputImageType::PixelType InputImagePixelType; + typedef typename InputImageType::LabelObjectType LabelObjectType; + + typedef typename OutputImageType::Pointer OutputImagePointer; + typedef typename OutputImageType::ConstPointer OutputImageConstPointer; + typedef typename OutputImageType::RegionType OutputImageRegionType; + typedef typename OutputImageType::PixelType OutputImagePixelType; + typedef typename OutputImageType::IndexType IndexType; + + typedef typename LabelObjectType::AttributesValueType AttributesValueType; + typedef std::vector<AttributesValueType> AttributesValueVectorType; + typedef itk::SimpleDataObjectDecorator<AttributesValueVectorType> AttributesValueVectorObjectType; + + /** ImageDimension constants */ + itkStaticConstMacro(InputImageDimension, unsigned int, + TInputImage::ImageDimension); + itkStaticConstMacro(OutputImageDimension, unsigned int, + TOutputImage::ImageDimension); + + /** Standard New method. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(MinMaxAttributesLabelMapFilter, + LabelMapFilter); + + + /** Return the computed Minimum. */ + AttributesValueVectorType GetMinimum() const + { + return this->GetMinimumOutput()->Get(); + } + AttributesValueVectorObjectType* GetMinimumOutput(); + const AttributesValueVectorObjectType* GetMinimumOutput() const; + + /** Return the computed Maximum. */ + AttributesValueVectorType GetMaximum() const + { + return this->GetMaximumOutput()->Get(); + } + AttributesValueVectorObjectType* GetMaximumOutput(); + const AttributesValueVectorObjectType* GetMaximumOutput() const; + + +protected: + MinMaxAttributesLabelMapFilter(); + ~MinMaxAttributesLabelMapFilter() {}; + + virtual void GenerateData(); + +private: + MinMaxAttributesLabelMapFilter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + typedef typename InputImageType::LabelObjectContainerType LabelObjectContainerType; + typedef typename LabelObjectContainerType::const_iterator LabelObjectContainerConstIterator; + + +}; // end of class + +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbMinMaxAttributesLabelMapFilter.txx" +#endif + +#endif + + diff --git a/Code/OBIA/otbMinMaxAttributesLabelMapFilter.txx b/Code/OBIA/otbMinMaxAttributesLabelMapFilter.txx new file mode 100644 index 0000000000000000000000000000000000000000..f6ab1d055631ef2f87b8c35bb318b2e4d7654fd0 --- /dev/null +++ b/Code/OBIA/otbMinMaxAttributesLabelMapFilter.txx @@ -0,0 +1,109 @@ +/*========================================================================= + +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 __otbMinMaxAttributesLabelMapFilter_txx +#define __otbMinMaxAttributesLabelMapFilter_txx + +#include "otbMinMaxAttributesLabelMapFilter.h" +#include "itkNumericTraits.h" +#include "itkProgressReporter.h" +#include "itkImageRegionConstIteratorWithIndex.h" + +namespace otb { + +template <class TInputImage, class TOutputImage> +MinMaxAttributesLabelMapFilter<TInputImage, TOutputImage> +::MinMaxAttributesLabelMapFilter() +{ + typename AttributesValueVectorObjectType::Pointer min = AttributesValueVectorObjectType::New(); + typename AttributesValueVectorObjectType::Pointer max = AttributesValueVectorObjectType::New(); + + this->itk::ProcessObject::SetNthOutput(1, min.GetPointer()); + this->itk::ProcessObject::SetNthOutput(2, max.GetPointer()); +} + +template<class TInputImage, class TOutputImage> +typename MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>::AttributesValueVectorObjectType* +MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage> +::GetMinimumOutput() +{ + return static_cast<AttributesValueVectorObjectType*>(this->itk::ProcessObject::GetOutput(1)); +} + +template<class TInputImage, class TOutputImage> +const typename MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>::AttributesValueVectorObjectType* +MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage> +::GetMinimumOutput() const +{ + return static_cast<const AttributesValueVectorObjectType*>(this->itk::ProcessObject::GetOutput(1)); +} + +template<class TInputImage, class TOutputImage> +typename MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>::AttributesValueVectorObjectType* +MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage> +::GetMaximumOutput() +{ + return static_cast<AttributesValueVectorObjectType*>(this->itk::ProcessObject::GetOutput(2)); +} + +template<class TInputImage, class TOutputImage> +const typename MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>::AttributesValueVectorObjectType* +MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage> +::GetMaximumOutput() const +{ + return static_cast<const AttributesValueVectorObjectType*>(this->itk::ProcessObject::GetOutput(2)); +} + +template<class TInputImage, class TOutputImage> +void +MinMaxAttributesLabelMapFilter<TInputImage, TOutputImage> +::GenerateData() +{ + LabelObjectContainerConstIterator it = this->GetLabelMap()->GetLabelObjectContainer().begin(); + LabelObjectContainerConstIterator end = this->GetLabelMap()->GetLabelObjectContainer().end(); + + unsigned int nbAttr = this->GetLabelMap()->GetLabelObject(0)->GetNumberOfAttributes(); + std::vector<std::string> attributes = this->GetLabelMap()->GetLabelObject(0)->GetAvailableAttributes(); + + AttributesValueVectorType& minAttr = this->GetMinimumOutput()->Get(); + AttributesValueVectorType& maxAttr = this->GetMaximumOutput()->Get(); + + minAttr.resize(nbAttr); + maxAttr.resize(nbAttr); + std::fill(minAttr.begin(), minAttr.end(), itk::NumericTraits<AttributesValueType>::max()); + std::fill(maxAttr.begin(), maxAttr.end(), itk::NumericTraits<AttributesValueType>::NonpositiveMin()); + + for (; it != end; ++it) + { + // get the label object + LabelObjectType * labelObject = it->second; + + for (unsigned int i = 0; i < attributes.size(); ++i) + { + AttributesValueType val = labelObject->GetAttribute(attributes[i].c_str()); + // Update min + if (val < minAttr[i]) + minAttr[i] = val; + //Update max + if (val > maxAttr[i]) + maxAttr[i] = val; + } + } +} + +}// end namespace otb +#endif diff --git a/Testing/Code/OBIA/CMakeLists.txt b/Testing/Code/OBIA/CMakeLists.txt index 38e73d575153ecb639278727972bf4d6540e0b29..1b748bb90df8b889ab1be80c23b16d03670c29d6 100644 --- a/Testing/Code/OBIA/CMakeLists.txt +++ b/Testing/Code/OBIA/CMakeLists.txt @@ -94,6 +94,15 @@ ADD_TEST(obTuLabelObjectToPolygonFunctorNew ${OBIA_TESTS1} otbLabelObjectToPolygonFunctorNew ) +ADD_TEST(obTuMinMaxAttributesLabelMapFilterNew ${OBIA_TESTS1} +otbMinMaxAttributesLabelMapFilterNew +) + +ADD_TEST(obTvMinMaxAttributesLabelMapFilter ${OBIA_TESTS1} + otbMinMaxAttributesLabelMapFilter + ${INPUTDATA}/calanques.tif + ${INPUTDATA}/cala_labelled.tif) + ADD_TEST(obTuRadiometricAttributesLabelMapFilterNew ${OBIA_TESTS1} otbRadiometricAttributesLabelMapFilterNew ) @@ -147,6 +156,7 @@ otbLabelMapWithClassLabelToLabeledSampleListFilter.cxx otbLabelMapWithClassLabelToLabeledSampleListFilterNew.cxx otbLabelObjectMapVectorizer.cxx otbLabelObjectToPolygonFunctorNew.cxx +otbMinMaxAttributesLabelMapFilter.cxx otbRadiometricAttributesLabelMapFilterNew.cxx otbShapeAttributesLabelMapFilterNew.cxx otbStatisticsAttributesLabelMapFilterNew.cxx diff --git a/Testing/Code/OBIA/otbMinMaxAttributesLabelMapFilter.cxx b/Testing/Code/OBIA/otbMinMaxAttributesLabelMapFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..6cac377276f492893fdb748cb03c191dc9f90bd1 --- /dev/null +++ b/Testing/Code/OBIA/otbMinMaxAttributesLabelMapFilter.cxx @@ -0,0 +1,96 @@ +/*========================================================================= + + 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 "otbImageFileReader.h" + +#include <fstream> +#include <iostream> + +#include "otbImage.h" +#include "otbVectorImage.h" +#include "otbAttributesMapLabelObject.h" +#include "otbLabelImageToLabelMapWithAdjacencyFilter.h" +#include "otbImageToLabelMapWithAttributesFilter.h" +#include "otbMinMaxAttributesLabelMapFilter.h" + +const unsigned int Dimension = 2; +typedef unsigned short LabelType; +typedef double PixelType; + +typedef otb::AttributesMapLabelObject<LabelType, Dimension, double> LabelObjectType; +typedef otb::LabelMapWithAdjacency<LabelObjectType> LabelMapType; +typedef otb::VectorImage<PixelType, Dimension> VectorImageType; +typedef otb::Image<unsigned int,2> LabeledImageType; + +typedef otb::ImageFileReader<VectorImageType> ReaderType; +typedef otb::ImageFileReader<LabeledImageType> LabeledReaderType; +typedef otb::LabelImageToLabelMapWithAdjacencyFilter<LabeledImageType,LabelMapType> LabelMapFilterType; +typedef otb::ShapeAttributesLabelMapFilter<LabelMapType> ShapeFilterType; +typedef otb::MinMaxAttributesLabelMapFilter<LabelMapType, VectorImageType> MinMaxAttributesLabelMapFilterType; + +int otbMinMaxAttributesLabelMapFilterNew(int argc, char * argv[]) +{ + MinMaxAttributesLabelMapFilterType::Pointer radiometricLabelMapFilter = MinMaxAttributesLabelMapFilterType::New(); + return EXIT_SUCCESS; +} + +int otbMinMaxAttributesLabelMapFilter(int argc, char * argv[]) +{ + const char * infname = argv[1]; + const char * lfname = argv[2]; + + // SmartPointer instanciation + ReaderType::Pointer reader = ReaderType::New(); + LabeledReaderType::Pointer labeledReader = LabeledReaderType::New(); + LabelMapFilterType::Pointer filter = LabelMapFilterType::New(); + ShapeFilterType::Pointer shapeFilter = ShapeFilterType::New(); + MinMaxAttributesLabelMapFilterType::Pointer minmaxLabelMapFilter = MinMaxAttributesLabelMapFilterType::New(); + + // Inputs + reader->SetFileName(infname); + reader->UpdateOutputInformation(); + labeledReader->SetFileName(lfname); + labeledReader->UpdateOutputInformation(); + + // Filter + filter->SetInput(labeledReader->GetOutput()); + filter->SetBackgroundValue(itk::NumericTraits<LabelType>::max()); + + shapeFilter->SetInput(filter->GetOutput()); + + minmaxLabelMapFilter->SetInput(shapeFilter->GetOutput()); + minmaxLabelMapFilter->Update(); + + MinMaxAttributesLabelMapFilterType::AttributesValueVectorType minimum = minmaxLabelMapFilter->GetMinimum(); + std::cout << "Minimum : " << std::endl; + for (unsigned int i = 0; i < minimum.size(); ++i) + { + std::cout << minimum[i] << " ; "; + } + std::cout << std::endl; + + MinMaxAttributesLabelMapFilterType::AttributesValueVectorType maximum = minmaxLabelMapFilter->GetMaximum(); + std::cout << "Maximum : " << std::endl; + for (unsigned int i = 0; i < maximum.size(); ++i) + { + std::cout << maximum[i] << " ; "; + } + std::cout << std::endl; + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/OBIA/otbOBIATests1.cxx b/Testing/Code/OBIA/otbOBIATests1.cxx index 08ba2b4445904b4a794d21146533d0cb79008a1e..b4b3e7cf1e0f2f80dc3e98e356c9a6f8d6c338e4 100644 --- a/Testing/Code/OBIA/otbOBIATests1.cxx +++ b/Testing/Code/OBIA/otbOBIATests1.cxx @@ -41,6 +41,8 @@ REGISTER_TEST(otbLabelMapWithClassLabelToLabeledSampleListFilterNew); REGISTER_TEST(otbLabelMapWithClassLabelToLabeledSampleListFilter); REGISTER_TEST(otbLabelObjectMapVectorizer); REGISTER_TEST(otbLabelObjectToPolygonFunctorNew); +REGISTER_TEST(otbMinMaxAttributesLabelMapFilterNew); +REGISTER_TEST(otbMinMaxAttributesLabelMapFilter); REGISTER_TEST(otbRadiometricAttributesLabelMapFilterNew); REGISTER_TEST(otbShapeAttributesLabelMapFilterNew); REGISTER_TEST(otbStatisticsAttributesLabelMapFilterNew);