diff --git a/Code/Common/otbVariableLengthVectorConverter.h b/Code/Common/otbVariableLengthVectorConverter.h new file mode 100644 index 0000000000000000000000000000000000000000..fac00cf55ed0b8705217681a2e26394c81a94e13 --- /dev/null +++ b/Code/Common/otbVariableLengthVectorConverter.h @@ -0,0 +1,258 @@ +/*========================================================================= + + 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 __otbVariableLengthVectorConverter_h +#define __otbVariableLengthVectorConverter_h + +#include "itkProcessObject.h" +#include "itkVariableLengthVector.h" +#include "itkNumericTraits.h" +#include "itkExceptionObject.h" +#include "itkFixedArray.h" +#include "itkHistogram.h" + + +namespace otb +{ +/** + * \class VariableLengthVectorConverter + * \brief Convert any data container type into a VariableLengthVector. + * + * To be usable, the desired convertion must be implemented through + * partial specialisation mecanism. + * + */ + +//Base +template< class TInputType, class TPrecisionType = double > +class ITK_EXPORT VariableLengthVectorConverter : +public itk::ProcessObject +{ +public: + /** Standard class typedefs */ + typedef VariableLengthVectorConverter Self; + typedef itk::ProcessObject Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(VariableLengthVectorConverter, ProcessObject); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + typedef TPrecisionType OutputPrecisionType; + typedef typename itk::VariableLengthVector<OutputPrecisionType> OutputType; + typedef TInputType InputType; + + OutputType Convert (InputType input) + { + itkGenericExceptionMacro( << "Type Convertion Not Implemented." << std::endl ); + } + +protected: + VariableLengthVectorConverter(){} + virtual ~VariableLengthVectorConverter(){} + virtual void PrintSelf(std::ostream& os, itk::Indent indent) const + { + Superclass::PrintSelf(os, indent); + os << "Attempt to use inexistant implementation of the converter!" + << std::endl; + } + +private: + VariableLengthVectorConverter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented +}; + + + +// Real Matrix +template< class TInternalInputType, class TPrecisionType > +class ITK_EXPORT VariableLengthVectorConverter<std::vector<std::vector<TInternalInputType> >, + TPrecisionType> : +public itk::ProcessObject +{ +public: + /** Standard class typedefs */ + typedef VariableLengthVectorConverter Self; + typedef itk::ProcessObject Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(VariableLengthVectorConverter, ProcessObject); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + typedef TPrecisionType OutputPrecisionType; + typedef typename itk::VariableLengthVector<OutputPrecisionType> OutputType; + typedef typename std::vector<std::vector<TInternalInputType> > InputType; + + OutputType Convert(InputType input); + +protected: + VariableLengthVectorConverter(){} + virtual ~VariableLengthVectorConverter(){} + virtual void PrintSelf(std::ostream& os, itk::Indent indent) const + { + Superclass::PrintSelf(os, indent); + os << "Converter: std::vector<std::vector<RealType>> => VariableLengthVector<RealType>" + << std::endl; + } + +private: + VariableLengthVectorConverter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented +}; + + + +//Complex Matrix +template< class TInternalInputType, class TPrecisionType > +class ITK_EXPORT VariableLengthVectorConverter<std::vector<std::vector<std::complex<TInternalInputType> > >, + TPrecisionType> : +public itk::ProcessObject +{ +public: + /** Standard class typedefs */ + typedef VariableLengthVectorConverter Self; + typedef itk::ProcessObject Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(VariableLengthVectorConverter, ProcessObject); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + typedef TPrecisionType OutputPrecisionType; + typedef typename itk::VariableLengthVector<OutputPrecisionType> OutputType; + typedef typename std::vector<std::vector<std::complex<TInternalInputType> > > InputType; + + OutputType Convert(InputType input); + +protected: + VariableLengthVectorConverter(){} + virtual ~VariableLengthVectorConverter(){} + virtual void PrintSelf(std::ostream& os, itk::Indent indent) const + { + Superclass::PrintSelf(os, indent); + os << "Converter: std::vector<std::vector<std::complex<RealType>>> => VariableLengthVector<RealType>" + << std::endl; + } + +private: + VariableLengthVectorConverter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented +}; + + + +//Fixed Array +template< class TInternalInputType, unsigned int VArrayDimension, class TPrecisionType > +class ITK_EXPORT VariableLengthVectorConverter<itk::FixedArray<TInternalInputType, VArrayDimension>, + TPrecisionType> : +public itk::ProcessObject +{ +public: + /** Standard class typedefs */ + typedef VariableLengthVectorConverter Self; + typedef itk::ProcessObject Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(VariableLengthVectorConverter, ProcessObject); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + typedef TPrecisionType OutputPrecisionType; + typedef typename itk::VariableLengthVector<OutputPrecisionType> OutputType; + typedef typename itk::FixedArray<TInternalInputType, VArrayDimension> InputType; + + OutputType Convert(InputType input); + +protected: + VariableLengthVectorConverter(){} + virtual ~VariableLengthVectorConverter(){} + virtual void PrintSelf(std::ostream& os, itk::Indent indent) const + { + Superclass::PrintSelf(os, indent); + os << "Converter: itk::FixedArray<RealType, VArrayDimension> => VariableLengthVector<RealType>" + << std::endl; + } + +private: + VariableLengthVectorConverter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented +}; + +//Histogram +template< class TMeasurement, unsigned int VMeasurementVectorSize, class TFrequencyContainer, class TPrecisionType > +class ITK_EXPORT VariableLengthVectorConverter<itk::Statistics::Histogram<TMeasurement, + VMeasurementVectorSize, + TFrequencyContainer>, + TPrecisionType> : +public itk::ProcessObject +{ +public: + /** Standard class typedefs */ + typedef VariableLengthVectorConverter Self; + typedef itk::ProcessObject Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Run-time type information (and related methods). */ + itkTypeMacro(VariableLengthVectorConverter, ProcessObject); + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + typedef TPrecisionType OutputPrecisionType; + typedef typename itk::VariableLengthVector<OutputPrecisionType> OutputType; + typedef typename itk::Statistics::Histogram<TMeasurement, + VMeasurementVectorSize, + TFrequencyContainer> InputType; + + OutputType Convert(InputType input); + +protected: + VariableLengthVectorConverter(){} + virtual ~VariableLengthVectorConverter(){} + virtual void PrintSelf(std::ostream& os, itk::Indent indent) const + { + Superclass::PrintSelf(os, indent); + os << "Converter: itk::Statistics::Histogram<RealType, VMeasurementVectorSize, TFrequencyContainer> => VariableLengthVector<RealType>" + << std::endl; + } + +private: + VariableLengthVectorConverter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented +}; + +}// namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbVariableLengthVectorConverter.txx" +#endif + +#endif diff --git a/Code/Common/otbVariableLengthVectorConverter.txx b/Code/Common/otbVariableLengthVectorConverter.txx new file mode 100644 index 0000000000000000000000000000000000000000..16a84fd82a5fa6aedf4cb6100ddb4bd03ee1c7a4 --- /dev/null +++ b/Code/Common/otbVariableLengthVectorConverter.txx @@ -0,0 +1,133 @@ +/*========================================================================= + + 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 __otbVariableLengthVectorConverter_txx +#define __otbVariableLengthVectorConverter_txx + +#include "otbVariableLengthVectorConverter.h" +#include "itkNumericTraits.h" +#include <complex> + + +namespace otb +{ + +// Real Matrix +template< class TInternalInputType, class TPrecisionType > +typename VariableLengthVectorConverter< std::vector<std::vector<TInternalInputType> >, TPrecisionType> +::OutputType +VariableLengthVectorConverter< std::vector<std::vector<TInternalInputType> >, TPrecisionType> +::Convert(InputType input) +{ + unsigned int p, q, rsltIdx = 0; + OutputType result; + + p = input.size(); + q = input.at(0).size(); + + result.SetSize(p*q); + + for (unsigned int i=0; i<p; i++) + { + for (unsigned int j=0; j<q; j++) + { + result[rsltIdx] = static_cast<OutputPrecisionType>(input.at(i).at(j)); + rsltIdx ++; + } + } + + return result; +} + +// Complex Matrix +template< class TInternalInputType, class TPrecisionType > +typename VariableLengthVectorConverter< std::vector<std::vector<std::complex<TInternalInputType> > >, + TPrecisionType> +::OutputType +VariableLengthVectorConverter< std::vector<std::vector<std::complex<TInternalInputType> > >, + TPrecisionType> +::Convert(InputType input) +{ + unsigned int p, q, rsltIdx = 0; + OutputType result; + + p = input.size(); + q = input.at(0).size(); + + result.SetSize(p*q*2); + + for (unsigned int i=0; i<p; i++) + { + for (unsigned int j=0; j<q; j++) + { + result[rsltIdx] = static_cast<OutputPrecisionType>(input.at(i).at(j).real()); + rsltIdx ++; + result[rsltIdx] = static_cast<OutputPrecisionType>(input.at(i).at(j).imag()); + rsltIdx ++; + } + } + + return result; +} + +// Fixed Array +template< class TInternalInputType, unsigned int VArrayDimension, class TPrecisionType > +typename VariableLengthVectorConverter< itk::FixedArray<TInternalInputType, VArrayDimension>, TPrecisionType> +::OutputType +VariableLengthVectorConverter< itk::FixedArray<TInternalInputType, VArrayDimension>, TPrecisionType> +::Convert(InputType input) +{ + unsigned int p, q, rsltIdx = 0; + OutputType result; + + result.SetSize(VArrayDimension); + + for (unsigned int i=0; i<VArrayDimension; i++) + { + result[rsltIdx] = static_cast<OutputPrecisionType>(input[i]); + rsltIdx ++; + } + + return result; +} + +// Histogram +template< class TMeasurement, unsigned int VMeasurementVectorSize, class TFrequencyContainer, class TPrecisionType > +typename VariableLengthVectorConverter< itk::Statistics::Histogram<TMeasurement, VMeasurementVectorSize, TFrequencyContainer>, TPrecisionType> +::OutputType +VariableLengthVectorConverter< itk::Statistics::Histogram<TMeasurement, VMeasurementVectorSize, TFrequencyContainer>, TPrecisionType> +::Convert(InputType input) +{ + unsigned int nbBins, rsltIdx = 0; + OutputType result; + + nbBins = input.GetSize(); + + result.SetSize(nbBins); + + for (unsigned int i=0; i<nbBins; i++) + { + result[rsltIdx] = static_cast<OutputPrecisionType>(input.GetFrequency(i)); + rsltIdx ++; + } + + return result; +} + +} // namespace otb + +#endif diff --git a/Testing/Code/Common/CMakeLists.txt b/Testing/Code/Common/CMakeLists.txt index f5ba7d62e4afc98478ed0ea00a33e1f1c5fdb3b3..9630fc3714d515ffa323c91e629e4a349469e294 100644 --- a/Testing/Code/Common/CMakeLists.txt +++ b/Testing/Code/Common/CMakeLists.txt @@ -919,7 +919,7 @@ otbUnaryFunctorWithIndexImageFilter # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbCommonTests12 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# ---------------- otbParser ---------------------# +# ---------------- otbParser --------------------- # ADD_TEST(coTuParser ${COMMON_TESTS12} otbParserTestNew ) @@ -928,6 +928,14 @@ otbUnaryFunctorWithIndexImageFilter otbParserTest ) +# ---------------- otbVariableLengthVectorConverter --------------------- # +ADD_TEST(coTuVariableLengthVectorConverter ${COMMON_TESTS12} + otbVariableLengthVectorConverterNew + ) + +#ADD_TEST(coTvVariableLengthVectorConverter ${COMMON_TESTS12} +# otbVariableLengthVectorConverter +# ) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbCommonTests13 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1087,6 +1095,7 @@ otbUnaryFunctorWithIndexImageFilter.cxx SET(BasicCommon_SRCS12 otbCommonTests12.cxx otbParserTest.cxx +otbVariableLengthVectorConverter.cxx ) diff --git a/Testing/Code/Common/otbCommonTests12.cxx b/Testing/Code/Common/otbCommonTests12.cxx index f11a9e0d157059ec6a313038d2676948567b9706..28e89d576352973d8852aa9f44ef765e42109a30 100644 --- a/Testing/Code/Common/otbCommonTests12.cxx +++ b/Testing/Code/Common/otbCommonTests12.cxx @@ -28,4 +28,6 @@ void RegisterTests() { REGISTER_TEST(otbParserTestNew); REGISTER_TEST(otbParserTest); + REGISTER_TEST(otbVariableLengthVectorConverterNew); + //REGISTER_TEST(otbVariableLengthVectorConverter); } diff --git a/Testing/Code/Common/otbVariableLengthVectorConverter.cxx b/Testing/Code/Common/otbVariableLengthVectorConverter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d3e9a32ce1a0610f70ef9199274d91cc0bace2a1 --- /dev/null +++ b/Testing/Code/Common/otbVariableLengthVectorConverter.cxx @@ -0,0 +1,54 @@ +/*========================================================================= + + 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 <cstdlib> +#include <cmath> + +#include "otbVariableLengthVectorConverter.h" + +int otbVariableLengthVectorConverterNew(int argc, char * argv[]) +{ + typedef itk::VariableLengthVector<double> InputType0; + typedef std::vector< std::vector< double > > InputType1; + typedef std::vector< std::vector< std::complex< double > > > InputType2; + typedef itk::FixedArray<double> InputType3; + + typedef float PrecisionType; + + typedef otb::VariableLengthVectorConverter<InputType0, PrecisionType> + ConverterType0; + typedef otb::VariableLengthVectorConverter<InputType1, PrecisionType> + ConverterType1; + typedef otb::VariableLengthVectorConverter<InputType2, PrecisionType> + ConverterType2; + typedef otb::VariableLengthVectorConverter<InputType3, PrecisionType> + ConverterType3; + + // Instantiating object + ConverterType0::Pointer converter0 = ConverterType0::New(); + ConverterType1::Pointer converter1 = ConverterType1::New(); + ConverterType2::Pointer converter2 = ConverterType2::New(); + ConverterType3::Pointer converter3 = ConverterType3::New(); + + std::cout << converter0 << std::endl; + std::cout << converter1 << std::endl; + std::cout << converter2 << std::endl; + std::cout << converter3 << std::endl; + + return EXIT_SUCCESS; +}