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;
25 bool decypher(
const char* name,
int& i)
32 if(0 == strcmp(name,_para[i]))
39 bool initializeParameters()
42 bt::check_builtin_parameters();
45 bool getNumParameters(
int& n)
50 bool getParameterName(
int i,
char* identifier)
52 strcpy(identifier,_para[i]);
55 bool setParameterValue(
const char *identifier,
double v)
60 if(bt::set_builtin_parameter_value(identifier,v))
64 if(!decypher(identifier,i))
70 bt::no_longer_uptodate_lut();
78 bool remap_esa2plain(
const vec2_type& p_esa_dn,vec2_type& p_plain_dn)
81 double f_dn = this->fl_cm() / this->r_fb_cm();
83 double r_esa_dn = norm2(p_esa_dn);
86 p_plain_dn = p_esa_dn;
89 double arg = r_esa_dn / (2.0 * f_dn),arg_clip = arg;
95 double phi = 2.0 * asin(arg_clip);
99 phi = M_PI / 2.0 - 1e-5;
102 double r_plain_dn = f_dn * tan(phi);
103 if(r_plain_dn > _r_clip_factor)
106 r_plain_dn = _r_clip_factor;
108 p_plain_dn = r_plain_dn * unit(p_esa_dn);
111 bool remap_plain2esa(
const vec2_type& p_plain_dn,vec2_type& p_esa_dn)
113 typedef base_type bt;
114 double f_dn = bt::fl_cm() / bt::r_fb_cm();
116 double r_plain_dn = norm2(p_plain_dn);
117 if(r_plain_dn == 0.0)
119 p_esa_dn = p_plain_dn;
122 double phi = atan2(r_plain_dn,f_dn);
123 double r_esa_dn = 2.0 * f_dn * std::sin(phi / 2.0);
124 p_esa_dn = r_esa_dn * unit(p_plain_dn);
128 bool undistort(
double x0,
double y0,
double &x1,
double &y1)
130 typedef base_type bt;
131 vec2_type p_esa_dn = bt::map_unit_to_dn(vec2_type(x0,y0));
132 vec2_type p_plain_dn;
133 if(!remap_esa2plain(p_esa_dn,p_plain_dn))
return false;
136 vec2_type q_dn = _distortion.
eval(p_plain_dn);
137 if(norm2(q_dn) > 100.0)
138 { q_dn = 100.0 * unit(q_dn); }
140 vec2_type q = bt::map_dn_to_unit(q_dn);
145 bool distort(
double x0,
double y0,
double &x1,
double &y1)
147 typedef base_type bt;
154 if(!bt::is_uptodate_lut())
157 if(!bt::is_uptodate_lut())
167 vec2_type qs = bt::get_lut().get_initial_value(vec2_type(x0,y0));
169 vec2_type p_plain_dn = _distortion.
map_inverse(bt::map_unit_to_dn(vec2_type(x0,y0)),bt::map_unit_to_dn(qs));
172 if(!remap_plain2esa(p_plain_dn,p_esa_dn))
return false;
174 vec2_type q = bt::map_dn_to_unit(p_esa_dn);
179 bool distort(
double x0,
double y0,
double x1_start,
double y1_start,
double &x1,
double &y1)
181 typedef base_type bt;
182 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)));
184 if(!remap_plain2esa(p_plain_dn,p_esa_dn))
return false;
186 vec2_type q = bt::map_dn_to_unit(p_esa_dn);
191 bool undistort_gnomonic(
double x0,
double y0,
double &x1,
double &y1)
193 typedef base_type bt;
194 vec2_type q = bt::map_dn_to_unit(
196 bt::map_unit_to_dn(vec2_type(x0,y0))));
201 bool distort_gnomonic(
double x0,
double y0,
double &x1,
double &y1)
203 typedef base_type bt;
205 if(!bt::is_uptodate_lut())
208 if(!bt::is_uptodate_lut())
215 vec2_type qs = bt::get_lut().get_initial_value(vec2_type(x0,y0));
217 vec2_type p_plain_dn = _distortion.
map_inverse(bt::map_unit_to_dn(vec2_type(x0,y0)),bt::map_unit_to_dn(qs));
222 bool distort_gnomonic(
double x0,
double y0,
double x1_start,
double y1_start,
double &x1,
double &y1)
224 typedef base_type bt;
225 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)));
226 vec2_type q = bt::map_dn_to_unit(p_plain_dn);
237 double r_clip_factor()
const 238 {
return _r_clip_factor; }
239 void r_clip_factor(
double f)
240 { _r_clip_factor = f; }
243 #ifdef LDPK_COMPILE_AS_PLUGIN_SDV 244 strcpy(name,
"3DE4 Radial - Fisheye, Degree 8 [Plugin]");
246 strcpy(name,
"3DE4 Radial - Fisheye, Degree 8");
252 typedef base_type bt;
254 if(bt::get_builtin_parameter_type(identifier,ptype))
return true;
255 if(!decypher(identifier,i))
return false;
256 ptype = TDE4_LDP_ADJUSTABLE_DOUBLE;
261 typedef base_type bt;
263 if(!decypher(identifier,i))
return false;
269 typedef base_type bt;
271 if(!decypher(identifier,i))
return false;
278 typedef base_type bt;
282 vec2_type p_esa_dn = bt::map_unit_to_dn(vec2_type(x0,y0));
283 vec2_type p_plain_dn;
284 if(!remap_esa2plain(p_esa_dn,p_plain_dn))
286 m00 = 1;m01 = 0;m10 = 0;m11 = 1;
289 mat2_type m = _distortion.
jacobi(p_plain_dn);
292 double f_dn = this->fl_cm() / this->r_fb_cm();
293 double r_esa_dn = norm2(p_esa_dn);
294 double r_esa_div_2f = r_esa_dn / (2.0 * f_dn);
296 if(fabs(r_esa_div_2f) > 0.99)
298 m00 = 1;m01 = 0;m10 = 0;m11 = 1;
301 double asn = asin(r_esa_div_2f);
303 if(fabs(2.0 * asn) > 0.99 * M_PI / 2.0)
305 m00 = 1;m01 = 0;m10 = 0;m11 = 1;
308 double csn = cos(2.0 * asn);
310 double sqr = sqrt(1.0 - r_esa_div_2f * r_esa_div_2f);
314 e = (mat2_type(1) -
tensq(p_esa_dn / r_esa_dn)) * (f_dn / r_esa_dn) * tan(2.0 * asn)
315 + (
tensq(p_esa_dn / r_esa_dn)) / (csn * csn * sqr);
324 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());
325 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));
326 m = d2u * m * e * u2d;
328 if(tr(trans(m) * m) > 100.0)
333 m00 = m[0][0];m01 = m[0][1];m10 = m[1][0];m11 = m[1][1];
338 template <
class VEC2,
class MAT2>
340 "Distortion - Degree 2",
341 "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
vec2_type eval(const vec2_type &p) const
Same as method instead of operator.
Definition: ldpk_generic_distortion_base.h:102
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:276
bool getParameterRange(const char *identifier, double &a, double &b)
returns range for adjustable double parameters...
Definition: tde4_ldp_radial_deg_8.h:267
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:259
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
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:250
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:120
void set_coeff(int i, double q)
Set coefficient c[i], 0 <= i < N.
Definition: ldpk_generic_radial_distortion.h:38
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:241