diff --git a/Code/Projections/otbRationalTransform.h b/Code/Projections/otbRationalTransform.h new file mode 100644 index 0000000000000000000000000000000000000000..1fd1b150fa3bac46c57936c03b943395bb9b536d --- /dev/null +++ b/Code/Projections/otbRationalTransform.h @@ -0,0 +1,180 @@ +/*========================================================================= + + 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 __otbRationalTransform_h +#define __otbRationalTransform_h + +#include "itkTransform.h" +#include "itkExceptionObject.h" +#include "itkMacro.h" + +namespace otb +{ +/** \class RationalTransform + * \brief This class implements a rational transfom + * + * A rational transform is a quotient of two polynomial functions. + * + * The degree of the numerator and denominator polynomial functions + * can be set using the appropriate setters. + * + * The number of parameters is then the number of dimensions times + * the numerator degree plus one times the denominator degree plus + * one. + * + * Parameters in the parameters vector are in the following order: + * dim0num0 dim0num1 ... dim0numN dim0denom0 dim0denom1 + * ... dim0denomM ... dim1num0 ... dimDdenomM. + * + * \ingroup Transform + **/ + +template <class TScalarType = double, + unsigned int Dimension = 2> +class ITK_EXPORT RationalTransform : public itk::Transform<TScalarType,Dimension,Dimension> +{ +public: + /** Standard class typedefs. */ + typedef itk::Transform<TScalarType,Dimension, + Dimension> Superclass; + typedef RationalTransform Self; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + typedef typename Superclass::ScalarType ScalarType; + typedef itk::Point<ScalarType, Dimension> InputPointType; + typedef itk::Point<ScalarType, Dimension> OutputPointType; + + typedef typename Superclass::InverseTransformBasePointer InverseTransformBasePointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(RationalTransform, itk::Transform); + + itkStaticConstMacro(SpaceDimension, unsigned int, Dimension); + + /** Set the numerator degree */ + itkSetMacro(NumeratorDegree,unsigned int); + + /** Get the numerator degree */ + itkGetMacro(NumeratorDegree,unsigned int); + + /** Set the numerator degree */ + itkSetMacro(DenominatorDegree,unsigned int); + + /** Get the denominator degree */ + itkGetMacro(DenominatorDegree,unsigned int); + + + /** The transform point method */ + virtual OutputPointType TransformPoint(const InputPointType& point) const + { + // Check for consistency + if(this->GetNumberOfParameters() != this->m_Parameters.size()) + { + { + itkExceptionMacro(<<"Wrong number of parameters: found "<<this->m_Parameters.Size()<<", expected "<<this->GetNumberOfParameters()); + } + } + + // Build output + OutputPointType outputPoint; + + unsigned int dimensionStride = (m_DenominatorDegree+1)+(m_NumeratorDegree+1); + + // Compute RPC transform + for(unsigned int dim = 0; dim < SpaceDimension; ++dim) + { + // Initialize numerator and denominator + TScalarType num = itk::NumericTraits<TScalarType>::Zero; + TScalarType denom = itk::NumericTraits<TScalarType>::Zero; + TScalarType currentPower = 1.; + + // Compute numerator + for(unsigned int numDegree = 0; numDegree <= m_NumeratorDegree; ++numDegree) + { + num+=this->m_Parameters[dim*dimensionStride+numDegree]*currentPower; + currentPower*=point[dim]; + } + + // Compute denominator + currentPower = 1.; + for(unsigned int denomDegree = 0; denomDegree <= m_DenominatorDegree; ++denomDegree) + { + denom+=this->m_Parameters[dim*dimensionStride+m_NumeratorDegree+denomDegree+1]*currentPower; + currentPower*=point[dim]; + } + + // Finally, fill the output + outputPoint[dim]=num/denom; + } + + // Return the output point + return outputPoint; + } + + // Get the number of parameters + virtual unsigned int GetNumberOfParameters() const + { + return (m_NumeratorDegree +1 + m_DenominatorDegree+1)*SpaceDimension; + } + + // Set parameter method + virtual void SetParameters(const typename Superclass::ParametersType & params) + { + // Check for the appropriate size + if(params.Size() != this->GetNumberOfParameters()) + { + itkExceptionMacro(<<"Wrong number of parameters: found "<<params.Size()<<", expected "<<this->GetNumberOfParameters()); + } + + // Set parameters + this->m_Parameters = params; + } + +protected: + RationalTransform() : Superclass(SpaceDimension,16), m_NumeratorDegree(3), m_DenominatorDegree(3) + { + this->m_Parameters.SetSize(this->GetNumberOfParameters()); + this->m_Parameters.Fill(0); + this->m_Parameters[1] = 1.; + this->m_Parameters[4] = 1.; + } + + virtual ~RationalTransform() {} + + void PrintSelf(std::ostream& os, itk::Indent indent) const + { + Superclass::PrintSelf(os,indent); + } + +private: + RationalTransform(const Self &); //purposely not implemented + void operator =(const Self&); //purposely not implemented + + // Degree of numerator + unsigned int m_NumeratorDegree; + + // Degree of denominator + unsigned int m_DenominatorDegree; +}; + +} // namespace otb + +#endif diff --git a/Testing/Code/Projections/CMakeLists.txt b/Testing/Code/Projections/CMakeLists.txt index e3999f4f8b8024e148ad9c4e215fab916888e1e0..764f56b11b30737e777cdec3bffba9deb9c5953f 100644 --- a/Testing/Code/Projections/CMakeLists.txt +++ b/Testing/Code/Projections/CMakeLists.txt @@ -1006,7 +1006,21 @@ ADD_TEST(prTvImageToGenericRSOutputParameters ${PROJECTIONS_TESTS4} ) ENDIF(OTB_DATA_USE_LARGEINPUT) +#----- otb::RationalTransform ------------------------ +ADD_TEST(prTuRationalTransformNew ${PROJECTIONS_TESTS4} +otbRationalTransformNew) +ADD_TEST(prTvRationalTransform ${PROJECTIONS_TESTS4} + --compare-ascii ${NOTOL} + ${BASELINE_FILES}/otbRationalTransformOutput.txt + ${TEMP}/otbRationalTransformOutput.txt +otbRationalTransform +${TEMP}/otbRationalTransformOutput.txt +0 0 +1 1 +10 10 +-10 -10 +) #======================================================================================= @@ -1067,6 +1081,7 @@ otbGenericRSResampleImageFilter.cxx otbElevDatabaseHeightAboveMSLFunction.cxx otbImageToEnvelopeVectorDataFilter.cxx otbImageToGenericRSOutputParameters.cxx +otbRationalTransform.cxx ) OTB_ADD_EXECUTABLE(otbProjectionsTests1 "${Projections_SRCS1}" "OTBProjections;OTBIO;OTBTesting") diff --git a/Testing/Code/Projections/otbProjectionsTests4.cxx b/Testing/Code/Projections/otbProjectionsTests4.cxx index 54d72c19f153b428f000d11687d3b477244dc2e8..de3ea5481bd1c572266fc24df1f7c15242b23531 100644 --- a/Testing/Code/Projections/otbProjectionsTests4.cxx +++ b/Testing/Code/Projections/otbProjectionsTests4.cxx @@ -35,4 +35,6 @@ void RegisterTests() REGISTER_TEST(otbImageToEnvelopeVectorDataFilter); REGISTER_TEST(otbImageToGenericRSOutputParametersNew); REGISTER_TEST(otbImageToGenericRSOutputParameters); + REGISTER_TEST(otbRationalTransformNew); + REGISTER_TEST(otbRationalTransform); } diff --git a/Testing/Code/Projections/otbRationalTransform.cxx b/Testing/Code/Projections/otbRationalTransform.cxx new file mode 100644 index 0000000000000000000000000000000000000000..21d721dbc28935a64680da56168f37844b03373b --- /dev/null +++ b/Testing/Code/Projections/otbRationalTransform.cxx @@ -0,0 +1,101 @@ +/*========================================================================= + + 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. + +=========================================================================*/ +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbRationalTransform.h" +#include <fstream> + +int otbRationalTransformNew(int argc, char* argv[]) +{ + typedef otb::RationalTransform<> RationalTransformType; + + // Instantiation + RationalTransformType::Pointer rt = RationalTransformType::New(); + + return EXIT_SUCCESS; +} + +int otbRationalTransform(int argc, char* argv[]) +{ + typedef otb::RationalTransform<> RationalTransformType; + + // Instantiation + RationalTransformType::Pointer rt = RationalTransformType::New(); + rt->SetNumeratorDegree(4); + rt->SetDenominatorDegree(4); + + RationalTransformType::ParametersType params(rt->GetNumberOfParameters()); + params.Fill(1.); + + // Rational is + // fx(x,y) = (1+2*x+3*x^2+4*x^3+5*x^4)/(6+7*x+8*x^2+9*x^3+10*x^4) + // fy(x,y) = (11+12*y+13*y^2+14*y^3+15*y^4)/(16+17*y+18*y^2+19*y^3+20*y^4) + params[0]=1; + params[1]=2; + params[2]=3; + params[3]=4; + params[4]=5; + params[5]=6; + params[6]=7; + params[7]=8; + params[8]=9; + params[9]=10; + params[10]=11; + params[11]=12; + params[12]=13; + params[13]=14; + params[14]=15; + params[15]=16; + params[16]=17; + params[17]=18; + params[18]=19; + params[19]=20; + + rt->SetParameters(params); + + RationalTransformType::InputPointType inputPoint; + RationalTransformType::OutputPointType outputPoint; + + std::ofstream ofs; + ofs.open(argv[1]); + + // Set floatfield to format writing properly + ofs.setf(std::ios::fixed, std::ios::floatfield); + ofs.precision(10); + + unsigned int idx = 2; + + ofs<<"Rational function is: "<<std::endl; + ofs<<"fx(x,y) = (1+2*x+3*x^2+4*x^3+5*x^4)/(6+7*x+8*x^2+9*x^3+10*x^4)"<<std::endl; + ofs<<"fy(x,y) = (11+12*y+13*y^2+14*y^3+15*y^4)/(16+17*y+18*y^2+19*y^3+20*y^4)"<<std::endl; + while(idx+1<(unsigned int)argc) + { + inputPoint[0] = atof(argv[idx]); + inputPoint[1] = atof(argv[idx+1]); + outputPoint = rt->TransformPoint(inputPoint); + ofs<<inputPoint<<" -> "<<outputPoint<<std::endl; + idx+=2; + } + + ofs.close(); + + return EXIT_SUCCESS; +} +