ldpk
ldpk_radial_homomorphic_decentered_distortion.h
Go to the documentation of this file.
1 #pragma once
2 
5 
7 #include <iostream>
8 
9 namespace ldpk
10  {
12  template <class VEC2,class MAT2>
14  {
15  public:
17  typedef VEC2 vec2_type;
18  typedef MAT2 mat2_type;
19  private:
20 // union allows to access coefficients by index.
21  union
22  {
23  struct
24  {
25  double _c2,_u2,_v2;
26  };
27  double _c[3];
28  };
29  mutable bool _valid;
30  public:
32  {
33  _c2 = _u2 = _v2 = 0.0;
34  }
36  double get_coeff(int i) const
37  {
39  return _c[i];
40  }
42  void set_coeff(int i,double q)
43  {
45  _c[i] = q;
46  }
47 // This model function is not polynomial; it has a restricted
48 // domain. This flag indicates range violations for undistort().
49  bool valid() const
50  { return _valid; }
51  bool check_domain(const vec2_type& p_dn) const
52  {
53  double x = p_dn[0];
54  double y = p_dn[1];
55  double x2 = x * x;
56  double y2 = y * y;
57  double r2 = x2 + y2;
58  double disc = 1.0 - 2.0 * _c2 * r2;
59  if(disc <= 1e-12)
60  { return false; }
61  return true;
62  }
64  vec2_type operator()(const vec2_type& p_dn) const
65  {
66  double x_dn,y_dn;
67  double x = p_dn[0];
68  double y = p_dn[1];
69  double x2 = x * x;
70  double y2 = y * y;
71  double xy = x * y;
72  double r2 = x2 + y2;
73  double disc = 1.0 - 2.0 * _c2 * r2;
74 // Check for domain. The return value is (0,0)
75 // in case of domain violations.
76  if(disc <= 1e-12)
77  {
78  _valid = false;
79  return vec2_type(0,0);
80  }
81  _valid = true;
82  double q = ::sqrt(disc);
83  x_dn = x / q
84  + (r2 + 2.0 * x2) * _u2
85  + 2.0 * xy * _v2;
86 
87  y_dn = y / q
88  + (r2 + 2.0 * y2) * _v2
89  + 2.0 * xy * _u2;
90 
91  return vec2_type(x_dn,y_dn);
92  }
94  mat2_type jacobi(const vec2_type& p_dn) const
95  {
96  double x = p_dn[0];
97  double y = p_dn[1];
98  double x2 = x * x;
99  double y2 = y * y;
100  double xy = x * y;
101  double r2 = x2 + y2;
102 
103  double u2x = _u2 * x;
104  double v2y = _v2 * y;
105  double u2y = _u2 * y;
106  double v2x = _v2 * x;
107  double c2xy = _c2 * xy;
108 
109  double q = 1.0 - 2.0 * _c2 * r2;
110  mat2_type m_radial = (mat2_type(q) + 2.0 * _c2 * tensq(p_dn)) / (::sqrt(q) * q);
111  mat2_type m_decenter( 6.0 * u2x + 2.0 * v2y,
112  2.0 * (u2y + v2x),
113  2.0 * (u2y + v2x),
114  6.0 * v2y + 2.0 * u2x);
115  return m_radial + m_decenter;
116  }
119  void derive(double* dg,int n_parameters,const vec2_type& p_dn) const
120  {
121  int size = 2 * n_parameters;
122  double x = p_dn[0];
123  double y = p_dn[1];
124  double x2 = p_dn[0] * p_dn[0];
125  double y2 = p_dn[1] * p_dn[1];
126  double xy = p_dn[0] * p_dn[1];
127  double r2 = x2 + y2;
128 
129  int k = 0;
130 // c2
131  double q = 1.0 - 2.0 * _c2 * r2;
132  dg[k++] = x * (-2.0 * r2) / (::sqrt(q) * q);
133  dg[k++] = y * (-2.0 * r2) / (::sqrt(q) * q);
134  if(k == size) return;
135 // u2
136  dg[k++] = r2 + 2.0 * x2;
137  dg[k++] = 2.0 * xy;
138  if(k == size) return;
139 // v2
140  dg[k++] = 2.0 * xy;
141  dg[k++] = r2 + 2.0 * y2;
142  if(k == size) return;
143 // Unreachable
144  std::cerr << "radial_homomorphic_decentered_distortion: n_parameters out of range" << std::endl;
145  }
146  std::ostream& out(std::ostream& cout) const
147  {
148  int p = int(cout.precision());
149  cout.precision(5);
150  cout << "c2: " << _c2 << std::endl;
151  cout << "u2: " << _u2 << std::endl;
152  cout << "v2: " << _v2 << std::endl;
153  cout.precision(p);
154  return cout;
155  }
156  };
157  }
158 
mat2d tensq(const vec2d &a)
Tensor (dyadic) product square.
Definition: ldpk_vec2d.h:186
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:20
void set_coeff(int i, double q)
Set coefficient c[i], 0 <= i < 3.
Definition: ldpk_radial_homomorphic_decentered_distortion.h:42
The homomorphic radially symmetric model of degree 2 with decentering.
Definition: ldpk_radial_homomorphic_decentered_distortion.h:13
void check_range(int i) const
A derived class may check if the index is valid.
Definition: ldpk_generic_distortion_base.h:36
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_homomorphic_decentered_distortion.h:119
The namespace of (most of the) things related to the Lens Distortion Plugin Kit.
Definition: ldpk.h:19
Base class for distortion models.
mat2_type jacobi(const vec2_type &p_dn) const
Analytic version of the Jacobi-matrix.
Definition: ldpk_radial_homomorphic_decentered_distortion.h:94
vec2_type operator()(const vec2_type &p_dn) const
Remove distortion. p_dn is a point in diagonally normalized coordinates.
Definition: ldpk_radial_homomorphic_decentered_distortion.h:64
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_homomorphic_decentered_distortion.h:146
double get_coeff(int i) const
Get coefficient c[i], 0 <= i < 3.
Definition: ldpk_radial_homomorphic_decentered_distortion.h:36