Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TextureTransformSimilar.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #ifndef __TextureTransformSimilar__hh__
26 #define __TextureTransformSimilar__hh__
27 
28 #include <Base/Common/BIASpragmaStart.hh>
29 #include <Image/TextureTransform.hh>
30 #include <Base/Common/CompareFloatingPoint.hh>
31 
32 namespace BIAS {
33 
34  /** @class TextureTransformDisplacement
35  * @brief analytic properties of similarity image warp (scale+rot.+displ.)
36  *
37  * See BIAS::TextureTransform for explanation of methods.
38  * @author koeser 01/2008
39  **/
41  public:
43  P_.newsize(4);
44  P_[0] = 0;
45  P_[1] = 0;
46  P_[2] = 0;
47  P_[3] = 0;
48  }
49 
51 
52  int MapForward(const HomgPoint2D& src, HomgPoint2D& sink) const {
53  const double& sx = src[0];
54  const double& sy = src[1];
55  sink[0] = A_[0][0]*sx + A_[0][1]*sy + tx_;
56  sink[1] = A_[1][0]*sx + A_[1][1]*sy + ty_;
57  sink[2] = 1;
58  return 0;
59  }
60 
61  int MapBackward(const HomgPoint2D& sink, HomgPoint2D& src) const {
62  src[0] = Ainv_[0][0]*sink[0] + Ainv_[0][1]*sink[1] + txinv_;
63  src[1] = Ainv_[1][0]*sink[0] + Ainv_[1][1]*sink[1] + tyinv_;
64  src[2] = 1;
65 #ifdef BIAS_DEBUG
66  HomgPoint2D testsink;
67  MapForward(src, testsink);
68  if (!Equal(testsink[0]+1e-4,sink[0]+1e-4, 1e-4) ||
69  !Equal(testsink[1]+1e-4,sink[1]+1e-4, 1e-4)) {
70  BIASERR(testsink<<" and "<<sink<<" are not equal!!!");
71  BIASABORT;
72  }
73 #endif
74  return 0;
75  }
76 
78  Matrix2x2<double>& Jac) const {
79  Jac = A_;
80  return 0;
81  }
82 
84  Matrix2x2<double>& Jac) const {
85  Jac = Ainv_;
86  return 0;
87  }
88 
89  /** @brief local warp is the same at any image position */
90  virtual bool TextureJacobianIsConstant() const { return true;};
91 
93  Jac.newsize(2,4);
94 
95  const double sinphi = sin(P_[0]);
96  const double cosphi = cos(P_[0]);
97  const double scale = P_[1];
98  const double scaleplus1 = scale+1.0;
99  const double x = src[0]-origin_[0];
100  const double y = src[1]-origin_[1];
101 
102  Jac[0][0] = -sinphi*scaleplus1*x-cosphi*scaleplus1*y;
103  Jac[0][1] = cosphi*x-sinphi*y;
104  Jac[0][2] = 1;
105  Jac[0][3] = 0;
106 
107  Jac[1][0] = cosphi*scaleplus1*x-sinphi*scaleplus1*y;
108  Jac[1][1] = sinphi*x+cosphi*y;
109  Jac[1][2] = 0;
110  Jac[1][3] = 1;
111 
112  return 0;
113  }
114 
116  Jac.newsize(2,4);
117  const double sinphi = sin(P_[0]);
118  const double cosphi = cos(P_[0]);
119  const double scale = P_[1];
120  const double scaleplus1 = scale+1.0;
121  const double c13 = P_[2];
122  const double c23 = P_[3];
123  const double x = src[0]-origin_[0];
124  const double y = src[1]-origin_[1];
125  // dx/dP_
126  Jac[0][0] = (-sinphi*x+cosphi*y-cosphi*c23+c13*sinphi)/scaleplus1;
127  Jac[0][1] = (-cosphi*x-sinphi*y+sinphi*c23+c13*cosphi)/
128  (scaleplus1*scaleplus1);
129  Jac[0][2] = -cosphi/scaleplus1;
130  Jac[0][3] = -sinphi/scaleplus1;
131 
132  // dy/dP_
133  Jac[1][0] = (-cosphi*x-sinphi*y+sinphi*c23+c13*cosphi)/scaleplus1;
134  Jac[1][1] = -(-sinphi*x+cosphi*y-cosphi*c23+c13*sinphi)/
135  (scaleplus1*scaleplus1);
136  Jac[1][2] = sinphi/scaleplus1;
137  Jac[1][3] = -cosphi/scaleplus1;
138 
139  return 0;
140  }
141 
142  /** @brief the jacobian depends on x */
143  bool ParameterJacobianIsConstant() const { return false;};
144 
145 
146  /** @brief rotation(rad), scale-1, dx,dy. All parameters with respect
147  to origin_! x' = A*(x-origin)+d+origin
148  where A==(s+1)[cos -sin; sin cos]
149  */
150  void SetParameters(const Vector<double>& p) {
151  BIASASSERT(p.Size()==4);
152  P_ = p;
153  A_[0][0] = A_[1][1] = cos(p[0])*(p[1]+1.0);
154  A_[0][1] = -sin(p[0])*(p[1]+1.0);
155  A_[1][0] = -A_[0][1];
156 
158 
159  tx_ = p[2]-offset[0];
160  ty_ = p[3]-offset[1];
161 
162  Ainv_ = A_.Invert();
163  txinv_ = -(Ainv_[0][0]*tx_ + Ainv_[0][1]*ty_);
164  tyinv_ = -(Ainv_[1][0]*tx_ + Ainv_[1][1]*ty_);
165  }
166 
169  A1[0][0] = A_[0][0];
170  A1[0][1] = A_[0][1];
171  A1[1][0] = A_[1][0];
172  A1[1][1] = A_[1][1];
173 
174  A1[0][2] = tx_;
175  A1[1][2] = ty_;
176 
177  A2[0][0] = A2[1][1] = cos(deltaP[0])*(deltaP[1]+1.0);
178  A2[0][1] = -sin(deltaP[0])*(deltaP[1]+1.0);
179  A2[1][0] = -A2[0][1];
180 
181 
182  A2[0][2] = deltaP[2]-(A2[0][0]-1.0)*origin_[0]-A2[0][1]*origin_[1];
183  A2[1][2] = deltaP[3]-A2[1][0]*origin_[0]-(A2[1][1]-1.0)*origin_[1];
184  Matrix3x3<double> A2inv;
185  A2.GetInverse(A2inv);
186  A1 = A2inv * A1;
187 
188  Vector<double> p(4);
189  p[1] = sqrt(A1.GetDeterminant());
190  const double sine = (A1[1][0]-A1[0][1])/(2.0*p[1]);
191  const double cosine = (A1[0][0]+A1[1][1])/(2.0*p[1]);
192  p[0] = atan2(sine, cosine);
193  p[1] -= 1.0;
194  p[2] = A1[0][2] + (A1[0][0]-1.0)*origin_[0] + A1[0][1]*origin_[1];
195  p[3] = A1[1][2] + A1[1][0]*origin_[0] + (A1[1][1]-1.0)*origin_[1];
196  SetParameters(p);
197  }
198 
199 
200  virtual TextureTransformSimilar* Clone() const {
201  return new TextureTransformSimilar(*this);
202  }
203 
204  /** @brief origin relative to which rotation and scale is performed */
205  void SetOrigin(const Vector2<double>& origin) {
206  origin_ = origin;
207  SetParameters(P_);
208  }
209 
210  /** @brief origin relative to which rotation and scale is performed */
211  const Vector2<double>& GetOrigin() const {
212  return origin_;
213  }
214 
215  protected:
216  /// cached local warp and inverse
218  /// cached displacement and inverse
219  double tx_, ty_, txinv_, tyinv_;
220  /// origin relative to which rotation and scale is performed
222  };
223 
224 } // end namespace BIAS
225 
226 #endif
virtual bool TextureJacobianIsConstant() const
local warp is the same at any image position
int Invert(Matrix2x2< T > &result) const
analyticaly inverts matrix
Definition: Matrix2x2.cpp:115
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
int ParameterJacobianBackward(Matrix< double > &Jac, const HomgPoint2D &src)
transformed position change when parameters change
void ComposeWithInverseDeltaP(const Vector< double > &deltaP)
concatenate *this and an inverse transform with param deltaP and save new parameter vector to *this...
Vector< double > P_
current set of parameters, see SetParameters for meaning
Matrix< T > & newsize(Subscript M, Subscript N)
Definition: cmat.h:269
class for representing parameterized image warps, such as homography, displacement, ...
unsigned int Size() const
length of the vector
Definition: Vector.hh:143
void SetParameters(const Vector< double > &p)
rotation(rad), scale-1, dx,dy.
Vector< T > & newsize(Subscript N)
Definition: vec.h:220
int ParameterJacobianForward(Matrix< double > &Jac, const HomgPoint2D &src)
transformed position change when parameters change
int GetInverse(Matrix3x3< T > &inv) const
Matrix inversion: inverts this and stores resulty in argument inv.
Definition: Matrix3x3.cpp:373
Vector2< double > origin_
origin relative to which rotation and scale is performed
Matrix2x2< double > A_
cached local warp and inverse
int TextureJacobianBackward(const HomgPoint2D &sink, Matrix2x2< double > &Jac) const
shape change of the local region when mapping backward
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
const Vector2< double > & GetOrigin() const
origin relative to which rotation and scale is performed
int MapForward(const HomgPoint2D &src, HomgPoint2D &sink) const
map a point in image &quot;source&quot; to a point in image &quot;sink&quot;
void SetOrigin(const Vector2< double > &origin)
origin relative to which rotation and scale is performed
double tx_
cached displacement and inverse
int MapBackward(const HomgPoint2D &sink, HomgPoint2D &src) const
map a point in image &quot;source&quot; to a point in image &quot;sink&quot;
bool ParameterJacobianIsConstant() const
the jacobian depends on x
virtual TextureTransformSimilar * Clone() const
virtual covariant copy constructor, caller must eventually destroy the created object ...
int TextureJacobianForward(const HomgPoint2D &src, Matrix2x2< double > &Jac) const
shape change of the local region when mapping forward