All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ProjectiveGT.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/ProjectiveGT.cpp
22 
23  \brief 2D Projective Geometric transformation.
24 */
25 
26 // TerraLib
27 #include "../common/MatrixUtils.h"
28 #include "ProjectiveGT.h"
29 
30 // STL
31 #include <cmath>
32 
34 {
35 }
36 
38 {
39 }
40 
41 const std::string& te::gm::ProjectiveGT::getName() const
42 {
43  static std::string name( "Projective" );
44  return name;
45 }
46 
47 bool te::gm::ProjectiveGT::isValid( const GTParameters& params ) const
48 {
49  return ( ( params.m_directParameters.size() == 8 ) &&
50  ( params.m_inverseParameters.size() == 8 ) );
51 }
52 
53 void te::gm::ProjectiveGT::directMap( const GTParameters& params, const double& pt1X,
54  const double& pt1Y, double& pt2X, double& pt2Y ) const
55 {
56  assert( isValid( params ) );
57 
58  pt2X = (
59  ( params.m_directParameters[0] * pt1X ) +
60  ( params.m_directParameters[1] * pt1Y ) +
61  params.m_directParameters[2]
62  )
63  /
64  (
65  ( params.m_directParameters[6] * pt1X ) +
66  ( params.m_directParameters[7] * pt1Y ) +
67  1
68  );
69 
70  pt2Y = (
71  ( params.m_directParameters[3] * pt1X ) +
72  ( params.m_directParameters[4] * pt1Y ) +
73  params.m_directParameters[5]
74  )
75  /
76  (
77  ( params.m_directParameters[6] * pt1X ) +
78  ( params.m_directParameters[7] * pt1Y ) +
79  1
80  );
81 }
82 
83 void te::gm::ProjectiveGT::inverseMap( const GTParameters& params, const double& pt2X,
84  const double& pt2Y, double& pt1X, double& pt1Y ) const
85 {
86  assert( isValid( params ) );
87 
88  pt1X = (
89  ( params.m_inverseParameters[0] * pt2X ) +
90  ( params.m_inverseParameters[1] * pt2Y ) +
91  params.m_inverseParameters[2]
92  )
93  /
94  (
95  ( params.m_inverseParameters[6] * pt2X ) +
96  ( params.m_inverseParameters[7] * pt2Y ) +
97  1
98  );
99 
100  pt1Y = (
101  ( params.m_inverseParameters[3] * pt2X ) +
102  ( params.m_inverseParameters[4] * pt2Y ) +
103  params.m_inverseParameters[5]
104  )
105  /
106  (
107  ( params.m_inverseParameters[6] * pt2X ) +
108  ( params.m_inverseParameters[7] * pt2Y ) +
109  1
110  );
111 }
112 
114 {
115  return 4;
116 }
117 
119 {
120  te::gm::ProjectiveGT* newTransPtr = new ProjectiveGT;
121  newTransPtr->m_internalParameters = m_internalParameters;
122  return newTransPtr;
123 }
124 
126 {
127  /*
128  | u | = | a b c | * | x |
129  | v | | d e f | | y |
130  | 1 | | g h 1 | | 1 |
131 
132  u = a.x + b.y + c
133  -------------------
134  g.x + h.y + 1
135 
136  v = d.x + e.y + f
137  -------------------
138  g.x + h.y + 1
139 
140  Method adapted from Albertz and Kreiling (1989).
141  Reference: Albertz, J.; Kreiling, W. Photogrametriches taschenbuch.
142  Karlsruhe: Wichmann, 1989.
143  */
144 
145  m_computeParameters_tiepointsSize = params.m_tiePoints.size();
146  if( m_computeParameters_tiepointsSize < getMinRequiredTiePoints() ) return false;
147 
148  // Direct mapping
149  m_computeParameters_L_DM.resize( 2*m_computeParameters_tiepointsSize, 1 );
150  m_computeParameters_A_DM.resize( 2*m_computeParameters_tiepointsSize, 8 );
151 
152  //Inverse mapping
153  m_computeParameters_L_IM.resize( 2*m_computeParameters_tiepointsSize, 1 );
154  m_computeParameters_A_IM.resize( 2*m_computeParameters_tiepointsSize, 8 );
155 
156  for ( m_computeParameters_blockOffset = 0 ; (m_computeParameters_blockOffset < m_computeParameters_tiepointsSize) ;
157  ++m_computeParameters_blockOffset)
158  {
159  m_computeParameters_index1 = m_computeParameters_blockOffset*2;
160  m_computeParameters_index2 = m_computeParameters_index1 + 1;
161 
162  const Coord2D& x_y = params.m_tiePoints[ m_computeParameters_blockOffset ].first;
163  const Coord2D& u_v = params.m_tiePoints[ m_computeParameters_blockOffset ].second;
164 
165  m_computeParameters_L_DM( m_computeParameters_index1, 0) = u_v.x;
166  m_computeParameters_L_DM( m_computeParameters_index2, 0) = u_v.y;
167 
168  m_computeParameters_A_DM( m_computeParameters_index1, 0 ) = x_y.x ;
169  m_computeParameters_A_DM( m_computeParameters_index1, 1 ) = x_y.y ;
170  m_computeParameters_A_DM( m_computeParameters_index1, 2 ) = 1 ;
171  m_computeParameters_A_DM( m_computeParameters_index1, 3 ) = 0 ;
172  m_computeParameters_A_DM( m_computeParameters_index1, 4 ) = 0 ;
173  m_computeParameters_A_DM( m_computeParameters_index1, 5 ) = 0 ;
174  m_computeParameters_A_DM( m_computeParameters_index1, 6 ) = - x_y.x * u_v.x;
175  m_computeParameters_A_DM( m_computeParameters_index1, 7 ) = - x_y.y * u_v.x;
176 
177  m_computeParameters_A_DM( m_computeParameters_index2, 0 ) = 0;
178  m_computeParameters_A_DM( m_computeParameters_index2, 1 ) = 0;
179  m_computeParameters_A_DM( m_computeParameters_index2, 2 ) = 0;
180  m_computeParameters_A_DM( m_computeParameters_index2, 3 ) = x_y.x ;
181  m_computeParameters_A_DM( m_computeParameters_index2, 4 ) = x_y.y ;
182  m_computeParameters_A_DM( m_computeParameters_index2, 5 ) = 1 ;
183  m_computeParameters_A_DM( m_computeParameters_index2, 6 ) = - x_y.x * u_v.y;
184  m_computeParameters_A_DM( m_computeParameters_index2, 7 ) = - x_y.y * u_v.y;
185 
186  m_computeParameters_L_IM( m_computeParameters_index1, 0) = x_y.x;
187  m_computeParameters_L_IM( m_computeParameters_index2, 0) = x_y.y;
188 
189  m_computeParameters_A_IM( m_computeParameters_index1, 0 ) = u_v.x ;
190  m_computeParameters_A_IM( m_computeParameters_index1, 1 ) = u_v.y ;
191  m_computeParameters_A_IM( m_computeParameters_index1, 2 ) = 1 ;
192  m_computeParameters_A_IM( m_computeParameters_index1, 3 ) = 0 ;
193  m_computeParameters_A_IM( m_computeParameters_index1, 4 ) = 0 ;
194  m_computeParameters_A_IM( m_computeParameters_index1, 5 ) = 0 ;
195  m_computeParameters_A_IM( m_computeParameters_index1, 6 ) = - u_v.x * x_y.x;
196  m_computeParameters_A_IM( m_computeParameters_index1, 7 ) = - u_v.y * x_y.x;
197 
198  m_computeParameters_A_IM( m_computeParameters_index2, 0 ) = 0;
199  m_computeParameters_A_IM( m_computeParameters_index2, 1 ) = 0;
200  m_computeParameters_A_IM( m_computeParameters_index2, 2 ) = 0;
201  m_computeParameters_A_IM( m_computeParameters_index2, 3 ) = u_v.x ;
202  m_computeParameters_A_IM( m_computeParameters_index2, 4 ) = u_v.y ;
203  m_computeParameters_A_IM( m_computeParameters_index2, 5 ) = 1 ;
204  m_computeParameters_A_IM( m_computeParameters_index2, 6 ) = - u_v.x * x_y.y;
205  m_computeParameters_A_IM( m_computeParameters_index2, 7 ) = - u_v.y * x_y.y;
206  }
207 
208  /* At calcule */
209  m_computeParameters_A_DM_t = boost::numeric::ublas::trans( m_computeParameters_A_DM );
210  m_computeParameters_A_IM_t = boost::numeric::ublas::trans( m_computeParameters_A_IM );
211 
212  /* N calcule */
213  m_computeParameters_N_DM = boost::numeric::ublas::prod( m_computeParameters_A_DM_t, m_computeParameters_A_DM );
214  m_computeParameters_N_IM = boost::numeric::ublas::prod( m_computeParameters_A_IM_t, m_computeParameters_A_IM );
215 
216  /* U calcule */
217  m_computeParameters_U_DM = boost::numeric::ublas::prod( m_computeParameters_A_DM_t, m_computeParameters_L_DM );
218  m_computeParameters_U_IM = boost::numeric::ublas::prod( m_computeParameters_A_IM_t, m_computeParameters_L_IM );
219 
220  /* N_inv calcule */
221 
222  if ( ! te::common::GetInverseMatrix( m_computeParameters_N_DM, m_computeParameters_N_DM_inv ) ) return false;
223 
224  m_computeParameters_X_DM = boost::numeric::ublas::prod( m_computeParameters_N_DM_inv, m_computeParameters_U_DM );
225 
226  params.m_directParameters.resize( 8 );
227  params.m_directParameters[0] = m_computeParameters_X_DM(0,0);
228  params.m_directParameters[1] = m_computeParameters_X_DM(1,0);
229  params.m_directParameters[2] = m_computeParameters_X_DM(2,0);
230  params.m_directParameters[3] = m_computeParameters_X_DM(3,0);
231  params.m_directParameters[4] = m_computeParameters_X_DM(4,0);
232  params.m_directParameters[5] = m_computeParameters_X_DM(5,0);
233  params.m_directParameters[6] = m_computeParameters_X_DM(6,0);
234  params.m_directParameters[7] = m_computeParameters_X_DM(7,0);
235 
236  if ( ! te::common::GetInverseMatrix( m_computeParameters_N_IM, m_computeParameters_N_IM_inv ) ) return false;
237 
238  m_computeParameters_X_IM = boost::numeric::ublas::prod( m_computeParameters_N_IM_inv, m_computeParameters_U_IM );
239 
240  params.m_inverseParameters.resize( 8 );
241  params.m_inverseParameters[0] = m_computeParameters_X_IM(0,0);
242  params.m_inverseParameters[1] = m_computeParameters_X_IM(1,0);
243  params.m_inverseParameters[2] = m_computeParameters_X_IM(2,0);
244  params.m_inverseParameters[3] = m_computeParameters_X_IM(3,0);
245  params.m_inverseParameters[4] = m_computeParameters_X_IM(4,0);
246  params.m_inverseParameters[5] = m_computeParameters_X_IM(5,0);
247  params.m_inverseParameters[6] = m_computeParameters_X_IM(6,0);
248  params.m_inverseParameters[7] = m_computeParameters_X_IM(7,0);
249 
250  return true;
251 }
252 
253 
ProjectiveGT()
Default constructor.
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
double y
y-coordinate.
Definition: Coord2D.h:114
void directMap(const GTParameters &params, const double &pt1X, const double &pt1Y, double &pt2X, double &pt2Y) const
Direct mapping (from pt1 space into pt2 space).
double x
x-coordinate.
Definition: Coord2D.h:113
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.
2D Projective Geometric transformation.
const std::string & getName() const
Returns the current transformation name.
GTParameters m_internalParameters
The current internal parameters.
void inverseMap(const GTParameters &params, const double &pt2X, const double &pt2Y, double &pt1X, double &pt1Y) const
Inverse mapping (from pt2 space into pt1 space).
GeometricTransformation * clone() const
Creat a clone copy of this instance.
2D Projective Geometric transformation.
Definition: ProjectiveGT.h:73
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.
bool GetInverseMatrix(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &outputMatrix)
Matrix inversion.
Definition: MatrixUtils.h:104
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. ...
~ProjectiveGT()
Destructor.