1 #ifndef ldpk_generic_anamorphic_distortion_sdv 2 #define ldpk_generic_anamorphic_distortion_sdv 22 template <
class VEC2,
class MAT2,
int N>
27 typedef VEC2 vec2_type;
32 double _cx[(N / 2) + 1][(N / 2) + 1];
33 double _cy[(N / 2) + 1][(N / 2) + 1];
35 double *_c[(N + 2) * (N + 4) / 4 - 2];
42 for(
int i_phi = 0;i_phi <= N;i_phi += 2)
44 for(
int i_r = 0;i_r <= N;i_r += 2)
53 for(
int i_r = 0;i_r <= N;i_r += 2)
55 for(
int i_phi = 0;i_phi <= i_r;i_phi += 2)
57 if((i_phi != 0) || (i_r != 0))
59 _c[k++] = &_cx[i_phi >> 1][i_r >> 1];
60 _c[k++] = &_cy[i_phi >> 1][i_r >> 1];
66 std::cerr <<
"generic_anamorphic_distortion: bad implementation for N = " << N;
67 std::cerr <<
". This needs to be fixed." << std::endl;
89 double cx(
int i_phi,
int i_r)
const 90 {
return _cx[i_phi >> 1][i_r >> 1]; }
91 void cx(
int i_phi,
int i_r,
double c)
92 { _cx[i_phi >> 1][i_r >> 1] = c; }
94 double cy(
int i_phi,
int i_r)
const 95 {
return _cy[i_phi >> 1][i_r >> 1]; }
96 void cy(
int i_phi,
int i_r,
double c)
97 { _cy[i_phi >> 1][i_r >> 1] = c; }
106 double r = norm2(p_dn);
107 double phi = atan2(p_dn[1],p_dn[0]);
112 for(
int i = 2;i < N + 1;i += 2)
114 r_pow[i] = (r * r) * r_pow[i - 2];
117 for(
int i_phi = 0;i_phi <= N;i_phi += 2)
119 double cos_i_phi = cos(i_phi * phi);
120 for(
int i_r = i_phi;i_r <= N;i_r += 2)
123 q[0] +=
cx(i_phi,i_r) * cos_i_phi * r_pow[i_r];
124 q[1] +=
cy(i_phi,i_r) * cos_i_phi * r_pow[i_r];
127 return vec2_type(p_dn[0] * q[0],p_dn[1] * q[1]);
134 void derive(
double* dg,
int n_parameters,
const vec2_type& p_dn)
const 136 int size = 2 * n_parameters;
139 double r = norm2(p_dn);
140 double phi = atan2(p_dn[1],p_dn[0]);
144 for(
int i = 2;i < N + 1;i += 2)
146 r_pow[i] = (r * r) * r_pow[i - 2];
148 double cos_phi[N + 1];
149 for(
int i_phi = 0;i_phi < N + 1;i_phi += 2)
151 cos_phi[i_phi] = cos(i_phi * phi);
156 for(
int i_r = 0;i_r <= N;i_r += 2)
158 for(
int i_phi = 0;i_phi <= i_r;i_phi += 2)
164 double cr = cos_phi[i_phi] * r_pow[i_r];
165 dg[k++] = p_dn[0] * cr;
168 if(k == size)
return;
171 dg[k++] = p_dn[1] * cr;
173 if(k == size)
return;
178 std::ostream&
out(std::ostream& cout)
const 180 int p = cout.precision();
182 for(
int i_r = 0;i_r <= N;i_r += 2)
185 if(i_r) cout <<
" Cx(i," << i_r <<
"): ";
186 for(
int i_phi = 0;i_phi <= i_r;i_phi += 2)
191 cout << std::right << std::fixed <<
cx(i_phi,i_r) <<
" ";
194 if(i_r) cout <<
"\n";
196 if(i_r) cout <<
" Cy(i," << i_r <<
"): ";
197 for(
int i_phi = 0;i_phi <= i_r;i_phi += 2)
202 cout << std::right << std::fixed <<
cy(i_phi,i_r) <<
" ";
205 if(i_r) cout <<
"\n";
214 template <
class VEC2,
class MAT2>
219 typedef VEC2 vec2_type;
220 typedef MAT2 mat2_type;
223 double _cx02,_cx22,_cx04,_cx24,_cx44;
224 double _cy02,_cy22,_cy04,_cy24,_cy44;
228 double _cx_for_x2,_cx_for_y2,_cx_for_x4,_cx_for_x2_y2,_cx_for_y4;
229 double _cy_for_x2,_cy_for_y2,_cy_for_x4,_cy_for_x2_y2,_cy_for_y4;
235 _c[0] = &_cx02;_c[1] = &_cy02;
236 _c[2] = &_cx22;_c[3] = &_cy22;
237 _c[4] = &_cx04;_c[5] = &_cy04;
238 _c[6] = &_cx24;_c[7] = &_cy24;
239 _c[8] = &_cx44;_c[9] = &_cy44;
240 for(
int i = 0;i < 10;++i)
258 _cx_for_x2 = _cx02 + _cx22;
259 _cx_for_y2 = _cx02 - _cx22;
261 _cx_for_x4 = _cx04 + _cx24 + _cx44;
262 _cx_for_x2_y2 = 2.0 * _cx04 - 6.0 * _cx44;
263 _cx_for_y4 = _cx04 - _cx24 + _cx44;
265 _cy_for_x2 = _cy02 + _cy22;
266 _cy_for_y2 = _cy02 - _cy22;
268 _cy_for_x4 = _cy04 + _cy24 + _cy44;
269 _cy_for_x2_y2 = 2.0 * _cy04 - 6.0 * _cy44;
270 _cy_for_y4 = _cy04 - _cy24 + _cy44;
277 double x = p_dn[0],x2 = x * x,x4 = x2 * x2;
278 double y = p_dn[1],y2 = y * y,y4 = y2 * y2;
280 + x2 * _cx_for_x2 + y2 * _cx_for_y2
281 + x4 * _cx_for_x4 + x2 * y2 * _cx_for_x2_y2 + y4 * _cx_for_y4);
283 + x2 * _cy_for_x2 + y2 * _cy_for_y2
284 + x4 * _cy_for_x4 + x2 * y2 * _cy_for_x2_y2 + y4 * _cy_for_y4);
285 return vec2_type(xq,yq);
288 mat2_type
jacobi(
const vec2_type& p_dn)
const 290 double x = p_dn[0],x2 = x * x,x3 = x2 * x,x4 = x2 * x2;
291 double y = p_dn[1],y2 = y * y,y3 = y2 * y,y4 = y2 * y2;
293 m[0][0] = 1.0 + x2 * 3.0 * _cx_for_x2 + y2 * _cx_for_y2
294 + x4 * 5.0 * _cx_for_x4 + x2 * y2 * 3.0 * _cx_for_x2_y2 + y4 * _cx_for_y4;
295 m[1][1] = 1.0 + y2 * 3.0 * _cy_for_y2 + x2 * _cy_for_x2
296 + y4 * 5.0 * _cy_for_y4 + x2 * y2 * 3.0 * _cy_for_x2_y2 + x4 * _cy_for_x4;
297 m[0][1] = x * y * 2.0 * _cx_for_y2
298 + x * y3 * 4.0 * _cx_for_y4 + x3 * y * 2.0 * _cx_for_x2_y2;
299 m[1][0] = x * y * 2.0 * _cy_for_x2
300 + x3 * y * 4.0 * _cy_for_x4 + x * y3 * 2.0 * _cy_for_x2_y2;
303 vec2_type twist(
const vec2_type& p_dn)
const 305 double x = p_dn[0],x2 = x * x,x3 = x2 * x;
306 double y = p_dn[1],y2 = y * y,y3 = y2 * y;
308 t[0] = y * 2.0 * _cx_for_y2
309 + x2 * y * 6.0 * _cx_for_x2_y2 + y3 * 4.0 * _cx_for_y4;
310 t[1] = x * 2.0 * _cy_for_x2
311 + x * y2 * 6.0 * _cy_for_x2_y2 + x3 * 4.0 * _cy_for_x4;
317 template <
class VEC2,
class MAT2>
322 typedef VEC2 vec2_type;
323 typedef MAT2 mat2_type;
326 double _cx02,_cx22,_cx04,_cx24,_cx44,_cx06,_cx26,_cx46,_cx66;
327 double _cy02,_cy22,_cy04,_cy24,_cy44,_cy06,_cy26,_cy46,_cy66;
331 double _cx_for_x2,_cx_for_y2,_cx_for_x4,_cx_for_x2_y2,_cx_for_y4,_cx_for_x6,_cx_for_x4_y2,_cx_for_x2_y4,_cx_for_y6;
332 double _cy_for_x2,_cy_for_y2,_cy_for_x4,_cy_for_x2_y2,_cy_for_y4,_cy_for_x6,_cy_for_x4_y2,_cy_for_x2_y4,_cy_for_y6;
338 _c[ 0] = &_cx02;_c[ 1] = &_cy02;
339 _c[ 2] = &_cx22;_c[ 3] = &_cy22;
340 _c[ 4] = &_cx04;_c[ 5] = &_cy04;
341 _c[ 6] = &_cx24;_c[ 7] = &_cy24;
342 _c[ 8] = &_cx44;_c[ 9] = &_cy44;
343 _c[10] = &_cx06;_c[11] = &_cy06;
344 _c[12] = &_cx26;_c[13] = &_cy26;
345 _c[14] = &_cx46;_c[15] = &_cy46;
346 _c[16] = &_cx66;_c[17] = &_cy66;
347 for(
int i = 0;i < 18;++i)
365 _cx_for_x2 = _cx02 + _cx22;
366 _cx_for_y2 = _cx02 - _cx22;
368 _cx_for_x4 = _cx04 + _cx24 + _cx44;
369 _cx_for_x2_y2 = 2.0 * _cx04 - 6.0 * _cx44;
370 _cx_for_y4 = _cx04 - _cx24 + _cx44;
372 _cx_for_x6 = _cx06 + _cx26 + _cx46 + _cx66;
373 _cx_for_x4_y2 = 3.0 * _cx06 + _cx26 - 5.0 * _cx46 - 15.0 * _cx66;
374 _cx_for_x2_y4 = 3.0 * _cx06 - _cx26 - 5.0 * _cx46 + 15.0 * _cx66;
375 _cx_for_y6 = _cx06 - _cx26 + _cx46 - _cx66;
377 _cy_for_x2 = _cy02 + _cy22;
378 _cy_for_y2 = _cy02 - _cy22;
380 _cy_for_x4 = _cy04 + _cy24 + _cy44;
381 _cy_for_x2_y2 = 2.0 * _cy04 - 6.0 * _cy44;
382 _cy_for_y4 = _cy04 - _cy24 + _cy44;
384 _cy_for_x6 = _cy06 + _cy26 + _cy46 + _cy66;
385 _cy_for_x4_y2 = 3.0 * _cy06 + _cy26 - 5.0 * _cy46 - 15.0 * _cy66;
386 _cy_for_x2_y4 = 3.0 * _cy06 - _cy26 - 5.0 * _cy46 + 15.0 * _cy66;
387 _cy_for_y6 = _cy06 - _cy26 + _cy46 - _cy66;
394 double x = p_dn[0],x2 = x * x,x4 = x2 * x2,x6 = x4 * x2;
395 double y = p_dn[1],y2 = y * y,y4 = y2 * y2,y6 = y4 * y2;
397 + x2 * _cx_for_x2 + y2 * _cx_for_y2
398 + x4 * _cx_for_x4 + x2 * y2 * _cx_for_x2_y2 + y4 * _cx_for_y4
399 + x6 * _cx_for_x6 + x4 * y2 * _cx_for_x4_y2 + x2 * y4 * _cx_for_x2_y4 + y6 * _cx_for_y6);
401 + x2 * _cy_for_x2 + y2 * _cy_for_y2
402 + x4 * _cy_for_x4 + x2 * y2 * _cy_for_x2_y2 + y4 * _cy_for_y4
403 + x6 * _cy_for_x6 + x4 * y2 * _cy_for_x4_y2 + x2 * y4 * _cy_for_x2_y4 + y6 * _cy_for_y6);
404 return vec2_type(xq,yq);
410 mat2_type
jacobi(
const vec2_type& p_dn)
const 412 double x = p_dn[0],x2 = x * x,x3 = x2 * x,x4 = x2 * x2,x5 = x3 * x2,x6 = x4 * x2;
413 double y = p_dn[1],y2 = y * y,y3 = y2 * y,y4 = y2 * y2,y5 = y3 * y2,y6 = y4 * y2;
415 m[0][0] = 1.0 + x2 * 3.0 * _cx_for_x2 + y2 * _cx_for_y2
416 + x4 * 5.0 * _cx_for_x4 + x2 * y2 * 3.0 * _cx_for_x2_y2 + y4 * _cx_for_y4
417 + x6 * 7.0 * _cx_for_x6 + x4 * y2 * 5.0 * _cx_for_x4_y2 + x2 * y4 * 3.0 * _cx_for_x2_y4 + y6 * _cx_for_y6;
418 m[1][1] = 1.0 + y2 * 3.0 * _cy_for_y2 + x2 * _cy_for_x2
419 + y4 * 5.0 * _cy_for_y4 + x2 * y2 * 3.0 * _cy_for_x2_y2 + x4 * _cy_for_x4
420 + x6 * _cy_for_x6 + x4 * y2 * 3.0 * _cy_for_x4_y2 + x2 * y4 * 5.0 * _cy_for_x2_y4 + y6 * 7.0 * _cy_for_y6;
421 m[0][1] = x * y * 2.0 * _cx_for_y2
422 + x * y3 * 4.0 * _cx_for_y4 + x3 * y * 2.0 * _cx_for_x2_y2
423 + x5 * y * 2.0 * _cx_for_x4_y2 + x3 * y3 * 4.0 * _cx_for_x2_y4 + x * y5 * 6.0 * _cx_for_y6;
424 m[1][0] = x * y * 2.0 * _cy_for_x2
425 + x3 * y * 4.0 * _cy_for_x4 + x * y3 * 2.0 * _cy_for_x2_y2
426 + x5 * y * 6.0 * _cy_for_x6 + x3 * y3 * 4.0 * _cy_for_x4_y2 + x * y5 * 2.0 * _cy_for_x2_y4;
429 vec2_type twist(
const vec2_type& p_dn)
const 431 double x = p_dn[0],x2 = x * x,x3 = x2 * x,x4 = x2 * x2,x5 = x3 * x2;
432 double y = p_dn[1],y2 = y * y,y3 = y2 * y,y4 = y2 * y2,y5 = y3 * y2;
434 t[0] = y * 2.0 * _cx_for_y2
435 + x2 * y * 6.0 * _cx_for_x2_y2 + y3 * 4.0 * _cx_for_y4
436 + x4 * y * 10.0 * _cx_for_x4_y2 + x2 * y3 * 12.0 * _cx_for_x2_y4 + y5 * 6.0 * _cx_for_y6;
437 t[1] = x * 2.0 * _cy_for_x2
438 + x * y2 * 6.0 * _cy_for_x2_y2 + x3 * 4.0 * _cy_for_x4
439 + x5 * 6.0 * _cy_for_x6 + x3 * y2 * 12.0 * _cy_for_x4_y2 + x * y4 * 10.0 * _cy_for_x2_y4;
generic_anamorphic_distortion()
Definition: ldpk_generic_anamorphic_distortion.h:335
int get_num_parameters() const
Number of parameters, that is N.
Definition: ldpk_generic_distortion_base.h:49
generic_anamorphic_distortion()
Definition: ldpk_generic_anamorphic_distortion.h:232
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
double get_coeff(int i) const
Get coefficient as demanded by base class.
Definition: ldpk_generic_anamorphic_distortion.h:351
void set_coeff(int i, double q)
Set coefficient as demanded by base class.
Definition: ldpk_generic_anamorphic_distortion.h:357
double get_coeff(int i) const
Get coefficient as demanded by base class.
Definition: ldpk_generic_anamorphic_distortion.h:244
void check_range(int i) const
A derived class may check if the index is valid.
Definition: ldpk_generic_distortion_base.h:36
The namespace of (most of the) things related to the Lens Distortion Plugin Kit.
Definition: ldpk.h:19
void set_coeff(int i, double q)
Set coefficient as demanded by base class.
Definition: ldpk_generic_anamorphic_distortion.h:77
Base class for distortion models.
std::ostream & out(std::ostream &cout) const
The derived class implements a method for printing values inside 3DE4's matrix tool dialog...
Definition: ldpk_generic_anamorphic_distortion.h:178
double cx(int i_phi, int i_r) const
x-direction
Definition: ldpk_generic_anamorphic_distortion.h:89
mat2_type jacobi(const vec2_type &p_dn) const
Jacobi-Matrix.
Definition: ldpk_generic_anamorphic_distortion.h:288
void prepare()
To be invoked by initializeParameters().
Definition: ldpk_generic_anamorphic_distortion.h:256
double cy(int i_phi, int i_r) const
y-direction
Definition: ldpk_generic_anamorphic_distortion.h:94
mat2_type jacobi(const vec2_type &p_dn) const
Jacobi-Matrix, tested against difference quotient method in base class. We calculated the Jacobian of...
Definition: ldpk_generic_anamorphic_distortion.h:410
vec2_type operator()(const vec2_type &p_dn) const
As usual, we define the distortion mapping in diagonally normalized coordinates, (hence the suffix _d...
Definition: ldpk_generic_anamorphic_distortion.h:392
void set_coeff(int i, double q)
Set coefficient as demanded by base class.
Definition: ldpk_generic_anamorphic_distortion.h:250
vec2_type operator()(const vec2_type &p_dn) const
As usual, we define the distortion mapping in diagonally normalized coordinates, (hence the suffix _d...
Definition: ldpk_generic_anamorphic_distortion.h:275
void prepare()
To be invoked by initializeParameters().
Definition: ldpk_generic_anamorphic_distortion.h:363
double get_coeff(int i) const
Get coefficient as demanded by base class.
Definition: ldpk_generic_anamorphic_distortion.h:71
void derive(double *dg, int n_parameters, const vec2_type &p_dn) const
Derivative wrt distortion coefficients. For performance reasons we calculate all derivatives simultan...
Definition: ldpk_generic_anamorphic_distortion.h:134
A polynomial distortion model for anamorphic distortion without decntering. N is the degree of the po...
Definition: ldpk_generic_anamorphic_distortion.h:23
vec2_type operator()(const vec2_type &p_dn) const
As usual, we define the distortion mapping in diagonally normalized coordinates, (hence the suffix _d...
Definition: ldpk_generic_anamorphic_distortion.h:102