All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SecondDegreePolynomialGT.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/geometry/SecondDegreePolynomialGT.cpp
22 
23  \brief Second Degree Polynomial Geometric transformation.
24 */
25 
26 // TerraLib
27 #include "../common/MatrixUtils.h"
29 
30 // STL
31 #include <cmath>
32 
33 
35 {
36 }
37 
39 {
40 }
41 
43 {
44  static std::string name( "SecondDegreePolynomial" );
45  return name;
46 }
47 
49 {
50  return ( ( params.m_directParameters.size() == 12 ) &&
51  ( params.m_inverseParameters.size() == 12 ) );
52 }
53 
54 void te::gm::SecondDegreePolynomialGT::directMap( const GTParameters& params, const double& pt1X,
55  const double& pt1Y, double& pt2X, double& pt2Y ) const
56 {
57  assert( isValid( params ) );
58 
59  pt2X =
60  params.m_directParameters[ 0 ] +
61  ( params.m_directParameters[ 1 ] * pt1X ) +
62  ( params.m_directParameters[ 2 ] * pt1Y ) +
63  ( params.m_directParameters[ 3 ] * pt1X * pt1Y ) +
64  ( params.m_directParameters[ 4 ] * pt1X * pt1X ) +
65  ( params.m_directParameters[ 5 ] * pt1Y * pt1Y );
66 
67  pt2Y =
68  params.m_directParameters[ 6 ] +
69  ( params.m_directParameters[ 7 ] * pt1X ) +
70  ( params.m_directParameters[ 8 ] * pt1Y ) +
71  ( params.m_directParameters[ 9 ] * pt1X * pt1Y ) +
72  ( params.m_directParameters[ 10 ] * pt1X * pt1X ) +
73  ( params.m_directParameters[ 11 ] * pt1Y * pt1Y );
74 }
75 
76 void te::gm::SecondDegreePolynomialGT::inverseMap( const GTParameters& params, const double& pt2X,
77  const double& pt2Y, double& pt1X, double& pt1Y ) const
78 {
79  assert( isValid( params ) );
80 
81  pt1X =
82  params.m_inverseParameters[ 0 ] +
83  ( params.m_inverseParameters[ 1 ] * pt2X ) +
84  ( params.m_inverseParameters[ 2 ] * pt2Y ) +
85  ( params.m_inverseParameters[ 3 ] * pt2X * pt2Y ) +
86  ( params.m_inverseParameters[ 4 ] * pt2X * pt2X ) +
87  ( params.m_inverseParameters[ 5 ] * pt2Y * pt2Y );
88 
89  pt1Y =
90  params.m_inverseParameters[ 6 ] +
91  ( params.m_inverseParameters[ 7 ] * pt2X ) +
92  ( params.m_inverseParameters[ 8 ] * pt2Y ) +
93  ( params.m_inverseParameters[ 9 ] * pt2X * pt2Y ) +
94  ( params.m_inverseParameters[ 10 ] * pt2X * pt2X ) +
95  ( params.m_inverseParameters[ 11 ] * pt2Y * pt2Y );
96 }
97 
99 {
100  return 7;
101 }
102 
104 {
106  newTransPtr->m_internalParameters = m_internalParameters;
107  return newTransPtr;
108 }
109 
111 {
112  /* Reference: Remote Sensing - Models and Methods For Image Processing
113  Second Edition
114  Robert A. Schowengerdt
115  Academic Press
116  */
117 
118  // Creating the equation system parameters
119 
120  m_computeParameters_tiepointsSize = params.m_tiePoints.size();
121  if( m_computeParameters_tiepointsSize < getMinRequiredTiePoints() ) return false;
122 
123  m_computeParameters_W.resize( m_computeParameters_tiepointsSize, 6 );
124  m_computeParameters_WI.resize( m_computeParameters_tiepointsSize, 6 );
125  m_computeParameters_X.resize( m_computeParameters_tiepointsSize, 1 );
126  m_computeParameters_XI.resize( m_computeParameters_tiepointsSize, 1 );
127  m_computeParameters_Y.resize( m_computeParameters_tiepointsSize, 1 );
128  m_computeParameters_YI.resize( m_computeParameters_tiepointsSize, 1 );
129 
130  for ( m_computeParameters_tpIdx = 0 ; m_computeParameters_tpIdx < m_computeParameters_tiepointsSize ; ++m_computeParameters_tpIdx )
131  {
132  const Coord2D& pt1 = params.m_tiePoints[ m_computeParameters_tpIdx ].first;
133 
134  m_computeParameters_W( m_computeParameters_tpIdx, 0 ) = 1;
135  m_computeParameters_W( m_computeParameters_tpIdx, 1 ) = pt1.x;
136  m_computeParameters_W( m_computeParameters_tpIdx, 2 ) = pt1.y;
137  m_computeParameters_W( m_computeParameters_tpIdx, 3 ) = pt1.x * pt1.y;
138  m_computeParameters_W( m_computeParameters_tpIdx, 4 ) = pt1.x * pt1.x;
139  m_computeParameters_W( m_computeParameters_tpIdx, 5 ) = pt1.y * pt1.y;
140 
141  const Coord2D& pt2 = params.m_tiePoints[ m_computeParameters_tpIdx ].second;
142 
143  m_computeParameters_WI( m_computeParameters_tpIdx, 0 ) = 1;
144  m_computeParameters_WI( m_computeParameters_tpIdx, 1 ) = pt2.x;
145  m_computeParameters_WI( m_computeParameters_tpIdx, 2 ) = pt2.y;
146  m_computeParameters_WI( m_computeParameters_tpIdx, 3 ) = pt2.x * pt2.y;
147  m_computeParameters_WI( m_computeParameters_tpIdx, 4 ) = pt2.x * pt2.x;
148  m_computeParameters_WI( m_computeParameters_tpIdx, 5 ) = pt2.y * pt2.y;
149 
150  m_computeParameters_X( m_computeParameters_tpIdx, 0 ) = pt2.x;
151 
152  m_computeParameters_XI( m_computeParameters_tpIdx, 0 ) = pt1.x;
153 
154  m_computeParameters_Y( m_computeParameters_tpIdx, 0 ) = pt2.y;
155 
156  m_computeParameters_YI( m_computeParameters_tpIdx, 0 ) = pt1.y;
157  }
158 
159  // Solving...
160 
161  if( ! te::common::GetPseudoInverseMatrix( m_computeParameters_W, m_computeParameters_PinvW ) ) return false;
162 
163  if( ! te::common::GetPseudoInverseMatrix( m_computeParameters_WI, m_computeParameters_PinvWI ) ) return false;
164 
165  m_computeParameters_A = boost::numeric::ublas::prod( m_computeParameters_PinvW, m_computeParameters_X );
166 
167  m_computeParameters_AI = boost::numeric::ublas::prod( m_computeParameters_PinvWI, m_computeParameters_XI );
168 
169  m_computeParameters_B = boost::numeric::ublas::prod( m_computeParameters_PinvW, m_computeParameters_Y );
170 
171  m_computeParameters_BI = boost::numeric::ublas::prod( m_computeParameters_PinvWI, m_computeParameters_YI );
172 
173  // Copying the parameters to output
174 
175  params.m_directParameters.resize( 12 );
176  params.m_directParameters[ 0 ] = m_computeParameters_A( 0, 0 );
177  params.m_directParameters[ 1 ] = m_computeParameters_A( 1, 0 );
178  params.m_directParameters[ 2 ] = m_computeParameters_A( 2, 0 );
179  params.m_directParameters[ 3 ] = m_computeParameters_A( 3, 0 );
180  params.m_directParameters[ 4 ] = m_computeParameters_A( 4, 0 );
181  params.m_directParameters[ 5 ] = m_computeParameters_A( 5, 0 );
182  params.m_directParameters[ 6 ] = m_computeParameters_B( 0, 0 );
183  params.m_directParameters[ 7 ] = m_computeParameters_B( 1, 0 );
184  params.m_directParameters[ 8 ] = m_computeParameters_B( 2, 0 );
185  params.m_directParameters[ 9 ] = m_computeParameters_B( 3, 0 );
186  params.m_directParameters[ 10 ] = m_computeParameters_B( 4, 0 );
187  params.m_directParameters[ 11 ] = m_computeParameters_B( 5, 0 );
188 
189  params.m_inverseParameters.resize( 12 );
190  params.m_inverseParameters[ 0 ] = m_computeParameters_AI( 0, 0 );
191  params.m_inverseParameters[ 1 ] = m_computeParameters_AI( 1, 0 );
192  params.m_inverseParameters[ 2 ] = m_computeParameters_AI( 2, 0 );
193  params.m_inverseParameters[ 3 ] = m_computeParameters_AI( 3, 0 );
194  params.m_inverseParameters[ 4 ] = m_computeParameters_AI( 4, 0 );
195  params.m_inverseParameters[ 5 ] = m_computeParameters_AI( 5, 0 );
196  params.m_inverseParameters[ 6 ] = m_computeParameters_BI( 0, 0 );
197  params.m_inverseParameters[ 7 ] = m_computeParameters_BI( 1, 0 );
198  params.m_inverseParameters[ 8 ] = m_computeParameters_BI( 2, 0 );
199  params.m_inverseParameters[ 9 ] = m_computeParameters_BI( 3, 0 );
200  params.m_inverseParameters[ 10 ] = m_computeParameters_BI( 4, 0 );
201  params.m_inverseParameters[ 11 ] = m_computeParameters_BI( 5, 0 );
202 
203  return true;
204 }
205 
206 
Second Degree Polynomial Geometric transformation.
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
const std::string & getName() const
Returns the current transformation name.
double y
y-coordinate.
Definition: Coord2D.h:114
double x
x-coordinate.
Definition: Coord2D.h:113
Second Degree Polynomial Geometric transformation.
std::vector< double > m_directParameters
Transformation numeric direct parameters.
Definition: GTParameters.h:100
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
2D Geometric transformation base class.
bool GetPseudoInverseMatrix(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &outputMatrix)
Pseudo matrix inversion.
Definition: MatrixUtils.h:152
GTParameters m_internalParameters
The current internal parameters.
bool isValid() const
Tells if the current instance has a valid transformation.
bool computeParameters(GTParameters &params) const
Calculate the transformation parameters following the new supplied tie-points.
void inverseMap(const GTParameters &params, const double &pt2X, const double &pt2Y, double &pt1X, double &pt1Y) const
Inverse mapping (from pt2 space into pt1 space).
std::vector< double > m_inverseParameters
Transformation numeric inverse parameters.
Definition: GTParameters.h:101
2D Geometric transformation parameters.
Definition: GTParameters.h:50
unsigned int getMinRequiredTiePoints() const
Returns the minimum number of required tie-points for the current transformation. ...
GeometricTransformation * clone() const
Creat a clone copy of this instance.
void directMap(const GTParameters &params, const double &pt1X, const double &pt1Y, double &pt2X, double &pt2Y) const
Direct mapping (from pt1 space into pt2 space).