ldpk
ldpk_radial_decentered_distortion.h
Go to the documentation of this file.
1 #ifndef ldpk_radial_decentered_distortion_sdv
2 #define ldpk_radial_decentered_distortion_sdv
3 
6 
8 #include <iostream>
9 
10 namespace ldpk
11  {
14  template <class VEC2,class MAT2>
16  {
17  public:
19  typedef VEC2 vec2_type;
20  typedef MAT2 mat2_type;
21  private:
22 // union allows to access coefficients by index.
23  union
24  {
25  struct
26  {
27  double _c2,_u1,_v1;
28  double _c4,_u3,_v3;
29  };
30  double _c[6];
31  };
32  public:
34  {
35  _c2 = _u1 = _v1 = 0.0;
36  _c4 = _u3 = _v3 = 0.0;
37  }
39  double get_coeff(int i) const
40  {
42  return _c[i];
43  }
45  void set_coeff(int i,double q)
46  {
48  _c[i] = q;
49  }
51  vec2_type operator()(const vec2_type& p_dn) const
52  {
53  double x_dn,y_dn;
54  double x = p_dn[0];
55  double y = p_dn[1];
56  double x2 = x * x;
57  double y2 = y * y;
58  double xy = x * y;
59  double r2 = x2 + y2;
60  double r4 = r2 * r2;
61  x_dn = x * (1.0 + _c2 * r2 + _c4 * r4)
62  + (r2 + 2.0 * x2) * (_u1 + _u3 * r2)
63  + 2.0 * xy * (_v1 + _v3 * r2);
64 
65  y_dn = y * (1.0 + _c2 * r2 + _c4 * r4)
66  + (r2 + 2.0 * y2) * (_v1 + _v3 * r2)
67  + 2.0 * xy * (_u1 + _u3 * r2);
68  return vec2_type(x_dn,y_dn);
69  }
72  mat2_type jacobi(const vec2_type& p_dn) const
73  {
74  mat2_type m;
75  double x = p_dn[0];
76  double y = p_dn[1];
77  double x2 = x * x;
78  double y2 = y * y;
79  double x3 = x2 * x;
80  double y3 = y2 * y;
81  double xy = x * y;
82  double x2y = xy * x;
83  double xy2 = xy * y;
84  double r2 = x2 + y2;
85 
86 // original implementation as in the document.
87 // m[0][0] = 1 + _c2 * (3.0 * x2 + y2) + _c4 * (5.0 * x2 + y2) * r2
88 // + 6.0 * _u1 * x + _u3 * (8.0 * xy2 + 12.0 * x3)
89 // + 2.0 * _v1 * y + _v3 * (2.0 * y3 + 6.0 * x2y);
90 // m[1][1] = 1 + _c2 * (x2 + 3.0 * y2) + _c4 * (x2 + 5.0 * y2) * r2
91 // + 6.0 * _v1 * y + _v3 * (8.0 * x2y + 12.0 * y3)
92 // + 2.0 * _u1 * x + _u3 * (2.0 * x3 + 6.0 * xy2);
93 //
94 // m[0][1] = 2.0 * _c2 * xy + 4.0 * _c4 * xy * r2
95 // + 2.0 * _u1 * y + _u3 * (8.0 * x2y + 4.0 * y3)
96 // + 2.0 * _v1 * x + _v3 * (2.0 * x3 + 6.0 * xy2);
97 // m[1][0] = 2.0 * _c2 * xy + 4.0 * _c4 * xy * r2
98 // + 2.0 * _u1 * y + _u3 * (6.0 * x2y + 2.0 * y3)
99 // + 2.0 * _v1 * x + _v3 * (4.0 * x3 + 8.0 * xy2);
100 // slightly condensed implementation
101  double u1x = _u1 * x;
102  double v1y = _v1 * y;
103  double c4r2 = _c4 * r2;
104  m[0][0] = 1.0 + _c2 * (3.0 * x2 + y2) + c4r2 * (5.0 * x2 + y2)
105  + 6.0 * u1x + _u3 * (8.0 * xy2 + 12.0 * x3)
106  + 2.0 * v1y + _v3 * (2.0 * y3 + 6.0 * x2y);
107  m[1][1] = 1.0 + _c2 * (x2 + 3.0 * y2) + c4r2 * (x2 + 5.0 * y2)
108  + 6.0 * v1y + _v3 * (8.0 * x2y + 12.0 * y3)
109  + 2.0 * u1x + _u3 * (2.0 * x3 + 6.0 * xy2);
110 
111  double m_off_diag_common = 2.0 * _c2 * xy + 4.0 * _c4 * xy * r2
112  + 2.0 * _u1 * y + 2.0 * _v1 * x;
113  m[0][1] = m_off_diag_common
114  + _u3 * (8.0 * x2y + 4.0 * y3)
115  + _v3 * (2.0 * x3 + 6.0 * xy2);
116  m[1][0] = m_off_diag_common
117  + _u3 * (6.0 * x2y + 2.0 * y3)
118  + _v3 * (4.0 * x3 + 8.0 * xy2);
119 
120  return m;
121  }
124  void derive(double* dg,int n_parameters,const vec2_type& p_dn) const
125  {
126  int size = 2 * n_parameters;
127  double x = p_dn[0];
128  double y = p_dn[1];
129  double x2 = p_dn[0] * p_dn[0];
130  double y2 = p_dn[1] * p_dn[1];
131  double xy = p_dn[0] * p_dn[1];
132  double r2 = x2 + y2;
133  double r4 = r2 * r2;
134 
135  int k = 0;
136 // c2
137  dg[k++] = x * r2;
138  dg[k++] = y * r2;
139  if(k == size) return;
140 // u1
141  dg[k++] = r2 + 2.0 * x2;
142  dg[k++] = 2.0 * xy;
143  if(k == size) return;
144 // v1
145  dg[k++] = 2.0 * xy;
146  dg[k++] = r2 + 2.0 * y2;
147  if(k == size) return;
148 // c4
149  dg[k++] = x * r4;
150  dg[k++] = y * r4;
151  if(k == size) return;
152 // u3
153  dg[k++] = r2 * (r2 + 2.0 * x2);
154  dg[k++] = 2.0 * r2 * xy;
155  if(k == size) return;
156 // v3
157  dg[k++] = 2.0 * r2 * xy;
158  dg[k++] = r2 * (r2 + 2.0 * y2);
159  if(k == size) return;
160 // Unreachable
161  std::cerr << "radial_decentered_distortion: n_parameters out of range" << std::endl;
162  }
163  std::ostream& out(std::ostream& cout) const
164  {
165  int p = int(cout.precision());
166  cout.precision(5);
167  cout << "c2: " << _c2 << std::endl;
168  cout << "u1: " << _u1 << std::endl;
169  cout << "v1: " << _v1 << std::endl;
170  cout << "u3: " << _u3 << std::endl;
171  cout << "c4: " << _c4 << std::endl;
172  cout << "v3: " << _v3 << std::endl;
173  cout.precision(p);
174  return cout;
175  }
176  };
177  }
178 
179 #endif
Base class for a distortion model with N parameters. You may find it useful to derive your own distor...
Definition: ldpk_generic_distortion_base.h:21
void check_range(int i) const
A derived class may check if the index is valid.
Definition: ldpk_generic_distortion_base.h:43
The namespace of (most of the) things related to the Lens Distortion Plugin Kit.
Definition: ldpk.h:169
Base class for distortion models.
std::ostream & out(std::ostream &cout) const
The derived class implements a method for printing values inside 3DE4&#39;s matrix tool dialog...
Definition: ldpk_radial_decentered_distortion.h:163
void derive(double *dg, int n_parameters, const vec2_type &p_dn) const
Derivative wrt distortion coefficients. dg points to an array with N / 2 Elements.
Definition: ldpk_radial_decentered_distortion.h:124
mat2_type jacobi(const vec2_type &p_dn) const
Analytic version of the Jacobi-matrix, about two times faster than the base class version which uses ...
Definition: ldpk_radial_decentered_distortion.h:72
void set_coeff(int i, double q)
Set coefficient c[i], 0 <= i < 6.
Definition: ldpk_radial_decentered_distortion.h:45
double get_coeff(int i) const
Get coefficient c[i], 0 <= i < 6.
Definition: ldpk_radial_decentered_distortion.h:39
vec2_type operator()(const vec2_type &p_dn) const
Remove distortion. p_dn is a point in diagonally normalized coordinates.
Definition: ldpk_radial_decentered_distortion.h:51
A polynomial radially symmetric model of degree 4 with decentering. This is the distortion model for ...
Definition: ldpk_radial_decentered_distortion.h:15