3 #include <ldpk/ldpk_ldp_builtin.h> 12 template <
class VEC2,
class MAT2>
16 typedef VEC2 vec2_type;
17 typedef MAT2 mat2_type;
22 static const char* _para[4];
23 double _r_clip_factor;
28 double _r_ed_dn_domain;
29 double _r_plain_dn_domain;
31 bool decypher(
const char* name,
int& i)
38 if(0 == strcmp(name,_para[i]))
48 bt::check_builtin_parameters();
49 _fl_dn = this->fl_cm() / this->r_fb_cm();
55 _r_ed_dn_domain = 0.0;
56 double radius_a = 0.0;
57 double radius_b = M_PI * _fl_dn;
58 double r_in_prev = -1.0;
59 double r_out_prev = -1.0;
60 for(
int i = 0;i <= n;++i)
62 double q = double(i) / n;
64 double r_in = radius_a * (1.0 - q) + radius_b * q;
65 vec2_type p_esa_dn(r_in,0.0);
71 _r_ed_dn_domain = r_in_prev;
72 _r_plain_dn_domain = r_out_prev;
75 vec2_type q_dn = _distortion.
eval(p_plain_dn);
76 double r_out = q_dn[0];
78 if(r_out < r_out_prev)
80 _r_ed_dn_domain = r_in_prev;
81 _r_plain_dn_domain = r_out_prev;
86 _r_ed_dn_domain = r_in;
87 _r_plain_dn_domain = r_out;
114 strcpy(identifier,_para[i]);
119 typedef base_type bt;
122 if(bt::set_builtin_parameter_value(identifier,v))
126 if(!decypher(identifier,i))
132 bt::no_longer_uptodate_lut();
143 double f_dn = this->fl_cm() / this->r_fb_cm();
145 double r_esa_dn = norm2(p_esa_dn);
148 p_plain_dn = p_esa_dn;
151 double arg = r_esa_dn / (2.0 * f_dn),arg_clip = arg;
157 double phi = 2.0 * asin(arg_clip);
158 if(phi >= M_PI / 2.0)
161 phi = M_PI / 2.0 - 1e-5;
164 double r_plain_dn = f_dn * tan(phi);
165 if(r_plain_dn > _r_clip_factor)
168 r_plain_dn = _r_clip_factor;
170 p_plain_dn = r_plain_dn * unit(p_esa_dn);
173 bool remap_plain2esa(
const vec2_type& p_plain_dn,vec2_type& p_esa_dn)
const 175 typedef base_type bt;
176 double f_dn = bt::fl_cm() / bt::r_fb_cm();
178 double r_plain_dn = norm2(p_plain_dn);
179 if(r_plain_dn == 0.0)
181 p_esa_dn = p_plain_dn;
184 double phi = atan2(r_plain_dn,f_dn);
185 double r_esa_dn = 2.0 * f_dn * std::sin(phi / 2.0);
186 p_esa_dn = r_esa_dn * unit(p_plain_dn);
190 bool undistort(
double x0,
double y0,
double &x1,
double &y1)
192 typedef base_type bt;
193 vec2_type p_esa_dn = bt::map_unit_to_dn(vec2_type(x0,y0));
194 vec2_type p_plain_dn;
196 if(norm2(p_esa_dn) > _r_ed_dn_domain)
201 vec2_type q_dn = _distortion.
eval(p_plain_dn);
202 if(norm2(q_dn) > 100.0)
203 { q_dn = 100.0 * unit(q_dn); }
205 vec2_type q = bt::map_dn_to_unit(q_dn);
210 bool distort(
double x0,
double y0,
double &x1,
double &y1)
212 typedef base_type bt;
219 if(!bt::is_uptodate_lut())
222 if(!bt::is_uptodate_lut())
232 vec2_type qs = bt::get_lut().get_initial_value(vec2_type(x0,y0));
234 vec2_type p_dn = bt::map_unit_to_dn(vec2_type(x0,y0));
235 double r = norm2(p_dn);
236 if(r > _r_plain_dn_domain)
239 vec2_type p_plain_dn = _distortion.
map_inverse(p_dn,bt::map_unit_to_dn(qs));
241 if(!remap_plain2esa(p_plain_dn,p_esa_dn))
245 if(dot(p_esa_dn,p_dn) < 0.0)
249 vec2_type q = bt::map_dn_to_unit(p_esa_dn);
254 bool distort(
double x0,
double y0,
double x1_start,
double y1_start,
double &x1,
double &y1)
256 typedef base_type bt;
257 vec2_type p_plain_dn = _distortion.
map_inverse(bt::map_unit_to_dn(vec2_type(x0,y0)),bt::map_unit_to_dn(vec2_type(x1_start,y1_start)));
259 if(!remap_plain2esa(p_plain_dn,p_esa_dn))
return false;
261 vec2_type q = bt::map_dn_to_unit(p_esa_dn);
268 typedef base_type bt;
269 vec2_type q = bt::map_dn_to_unit(
271 bt::map_unit_to_dn(vec2_type(x0,y0))));
276 bool distort_gnomonic(
double x0,
double y0,
double &x1,
double &y1)
278 typedef base_type bt;
280 if(!bt::is_uptodate_lut())
283 if(!bt::is_uptodate_lut())
290 vec2_type qs = bt::get_lut().get_initial_value(vec2_type(x0,y0));
292 vec2_type p_plain_dn = _distortion.
map_inverse(bt::map_unit_to_dn(vec2_type(x0,y0)),bt::map_unit_to_dn(qs));
297 bool distort_gnomonic(
double x0,
double y0,
double x1_start,
double y1_start,
double &x1,
double &y1)
299 typedef base_type bt;
300 vec2_type p_plain_dn = _distortion.
map_inverse(bt::map_unit_to_dn(vec2_type(x0,y0)),bt::map_unit_to_dn(vec2_type(x1_start,y1_start)));
301 vec2_type q = bt::map_dn_to_unit(p_plain_dn);
309 bool get_jacobian_matrix_dn(
const vec2_type& p_esa_dn,mat2_type m_dn)
const 311 vec2_type p_plain_dn;
314 mat2_type m = _distortion.
jacobi(p_plain_dn);
317 double f_dn = this->fl_cm() / this->r_fb_cm();
318 double r_esa_dn = norm2(p_esa_dn);
319 double r_esa_div_2f = r_esa_dn / (2.0 * f_dn);
321 if(fabs(r_esa_div_2f) > 0.99)
323 double asn = asin(r_esa_div_2f);
325 if(fabs(2.0 * asn) > 0.99 * M_PI / 2.0)
327 double csn = cos(2.0 * asn);
329 double sqr = sqrt(1.0 - r_esa_div_2f * r_esa_div_2f);
333 e = (mat2_type(1) -
tensq(p_esa_dn / r_esa_dn)) * (f_dn / r_esa_dn) * tan(2.0 * asn)
334 + (
tensq(p_esa_dn / r_esa_dn)) / (csn * csn * sqr);
350 double r_clip_factor()
const 351 {
return _r_clip_factor; }
352 void r_clip_factor(
double f)
353 { _r_clip_factor = f; }
356 #ifdef LDPK_COMPILE_AS_PLUGIN_SDV 357 strcpy(name,
"3DE4 Radial - Fisheye, Degree 8 [Plugin]");
359 strcpy(name,
"3DE4 Radial - Fisheye, Degree 8");
365 typedef base_type bt;
367 if(bt::get_builtin_parameter_type(identifier,ptype))
return true;
368 if(!decypher(identifier,i))
return false;
369 ptype = TDE4_LDP_ADJUSTABLE_DOUBLE;
374 typedef base_type bt;
376 if(!decypher(identifier,i))
return false;
382 typedef base_type bt;
384 if(!decypher(identifier,i))
return false;
391 typedef base_type bt;
395 vec2_type p_esa_dn = bt::map_unit_to_dn(vec2_type(x0,y0));
396 vec2_type p_plain_dn;
399 m00 = 1;m01 = 0;m10 = 0;m11 = 1;
402 mat2_type m = _distortion.
jacobi(p_plain_dn);
405 double f_dn = this->fl_cm() / this->r_fb_cm();
406 double r_esa_dn = norm2(p_esa_dn);
407 double r_esa_div_2f = r_esa_dn / (2.0 * f_dn);
409 if(fabs(r_esa_div_2f) > 0.99)
411 m00 = 1;m01 = 0;m10 = 0;m11 = 1;
414 double asn = asin(r_esa_div_2f);
416 if(fabs(2.0 * asn) > 0.99 * M_PI / 2.0)
418 m00 = 1;m01 = 0;m10 = 0;m11 = 1;
421 double csn = cos(2.0 * asn);
423 double sqr = sqrt(1.0 - r_esa_div_2f * r_esa_div_2f);
427 e = (mat2_type(1) -
tensq(p_esa_dn / r_esa_dn)) * (f_dn / r_esa_dn) * tan(2.0 * asn)
428 + (
tensq(p_esa_dn / r_esa_dn)) / (csn * csn * sqr);
437 mat2_type u2d((bt::w_fb_cm() / 2) / bt::r_fb_cm(),0.0,0.0,(bt::h_fb_cm() / 2) / bt::r_fb_cm());
438 mat2_type d2u(bt::r_fb_cm() / (bt::w_fb_cm() / 2),0.0,0.0,bt::r_fb_cm() / (bt::h_fb_cm() / 2));
439 m = d2u * m * e * u2d;
446 m00 = m[0][0];m01 = m[0][1];m10 = m[1][0];m11 = m[1][1];
451 template <
class VEC2,
class MAT2>
453 "Distortion - Degree 2",
454 "Quartic Distortion - Degree 4",
A polynomial radially symmetric model of degree N (even)
mat2d tensq(const vec2d &a)
Tensor (dyadic) product square.
Definition: ldpk_vec2d.h:186
Plugin class for radial distortion. Does not compensate for decentering. Parameters can be calculated...
Definition: tde4_ldp_radial_deg_8.h:13
bool setParameterValue(const char *identifier, double v)
set parameter values... parameters predefined by 3DE4: "tde4_focal_length_cm", "tde4_filmback_width_c...
Definition: tde4_ldp_radial_deg_8.h:117
vec2_type eval(const vec2_type &p) const
Same as method instead of operator.
Definition: ldpk_generic_distortion_base.h:77
bool remap_esa2plain(const vec2_type &p_esa_dn, vec2_type &p_plain_dn) const
esa stands for "equisolid-angle". The method will fill p_plain_dn with some more or less reasonable v...
Definition: tde4_ldp_radial_deg_8.h:140
bool undistort(double x0, double y0, double &x1, double &y1)
warp/unwarp 2D points...
Definition: tde4_ldp_radial_deg_8.h:190
bool getJacobianMatrix(double x0, double y0, double &m00, double &m01, double &m10, double &m11)
calculate the Jacobian matrix of the undistort()-Method. Overwrite this, if you know the Jacobian for...
Definition: tde4_ldp_radial_deg_8.h:389
bool getNumParameters(int &n)
returns the number of plugin parameters...
Definition: tde4_ldp_radial_deg_8.h:107
bool getParameterRange(const char *identifier, double &a, double &b)
returns range for adjustable double parameters...
Definition: tde4_ldp_radial_deg_8.h:380
bool getParameterDefaultValue(const char *identifier, double &v)
returns default value for given parameter (maximum length of "char *v": 1000 bytes)......
Definition: tde4_ldp_radial_deg_8.h:372
bool undistort_gnomonic(double x0, double y0, double &x1, double &y1)
Model function Our base class presents the model functions along with the projection. Internally, we have to carefully keep apart the model function and the projection. For most distortion models, this is no problem, yet for fisheye models it is, so all non-gnomonic distortion classes will have to overwrite these.
Definition: tde4_ldp_radial_deg_8.h:266
mat2_type jacobi(const vec2_type &p_dn) const
Analytic version of the Jacobi-matrix, about 2.5 times faster than the base class version which uses ...
Definition: ldpk_generic_radial_distortion.h:59
bool distort(double x0, double y0, double x1_start, double y1_start, double &x1, double &y1)
potentially more efficient function which uses initial values...
Definition: tde4_ldp_radial_deg_8.h:254
This class handles the built-in parameter and the lookup table. You may find it useful for your own d...
Definition: ldpk_ldp_builtin.h:31
bool getParameterType(const char *identifier, tde4_ldp_ptype &ptype)
returns type of given parameter... The method should return false, if the parameter addressed by iden...
Definition: tde4_ldp_radial_deg_8.h:363
virtual vec2_type map_inverse(const vec2_type &q) const
Inverse mapping by solving the fixed point equation without providing initial values. Virtual, because the derived class might use some smart data structure for calculating an initial value.
Definition: ldpk_generic_distortion_base.h:95
bool initializeParameters()
prepare the current set of parameters...
Definition: tde4_ldp_radial_deg_8.h:45
void set_coeff(int i, double q)
Set coefficient c[i], 0 <= i < N.
Definition: ldpk_generic_radial_distortion.h:38
bool getParameterName(int i, char *identifier)
returns "identifier" name of parameter "i" (maximum length of "identifier": 100 bytes)...
Definition: tde4_ldp_radial_deg_8.h:112
double get_coeff(int i) const
Get coefficient c[i], 0 <= i < N (i.e. coefficient power r^(2i))
Definition: ldpk_generic_radial_distortion.h:32
bool getModelName(char *name)
returns a name for the model as to show up in the GUI (maximum length of "name": 100 bytes)...
Definition: tde4_ldp_radial_deg_8.h:354