37 #ifndef __INCLUDE_MIST_CALIBRATION__
38 #define __INCLUDE_MIST_CALIBRATION__
41 #ifndef __INCLUDE_MIST_CONF_H__
45 #ifndef __INCLUDE_MIST_MATRIX__
49 #ifndef __INCLUDE_MIST_VECTOR__
53 #ifndef __INCLUDE_NUMERIC__
57 #ifndef __INCLUDE_MIST_MINIMIZATION__
115 : Ncx( 640 ), Ncy( 480 ), Nfx( 640 ), Nfy( 640 ), dx( 1.0 ), dy( 1.0 ), Cx( 320 ), Cy( 240 ), sx( 1.0 ),
116 r1( 1.0 ), r2( 0.0 ), r3( 0.0 ), r4( 0.0 ), r5( 1.0 ), r6( 0.0 ), r7( 0.0 ), r8( 0.0 ), r9( 1.0 ),
117 Tx( 0.0 ), Ty( 0.0 ), Tz( 0.0 ), f( 1.0 ), ka1( 0.0 )
123 inline std::string to_string(
double v,
int f1,
int f2 )
130 sprintf( format,
"%%f" );
134 sprintf( format,
"%%%d.%df", f1 + f2 + 1, f2 );
137 sprintf( buff, format, v );
142 inline std::string fixed_string(
double v,
int f1,
int f2,
size_t len )
144 std::string str = to_string( v, f1, f2 );
145 size_t i = str.length( );
146 for( ; i < len ; i++ )
163 out <<
"Ncx : " << fixed_string( p.
Ncx, 4, 6, 12 ) <<
" [cell]" << ::std::endl;
164 out <<
"Ncy : " << fixed_string( p.
Ncy, 4, 6, 12 ) <<
" [cell]" << ::std::endl;
165 out <<
"Nfx : " << fixed_string( p.
Nfx, 4, 6, 12 ) <<
" [pixels]" << ::std::endl;
166 out <<
"Nfy : " << fixed_string( p.
Nfy, 4, 6, 12 ) <<
" [pixels]" << ::std::endl;
167 out <<
"dx : " << fixed_string( p.
dx, 4, 6, 12 ) <<
" [mm/cell]" << ::std::endl;
168 out <<
"dy : " << fixed_string( p.
dy, 4, 6, 12 ) <<
" [mm/cell]" << ::std::endl;
169 out <<
"dpx : " << fixed_string( p.
dpx, 4, 6, 12 ) <<
" [mm/pixel]" << ::std::endl;
170 out <<
"dpy : " << fixed_string( p.
dpy, 4, 6, 12 ) <<
" [mm/pixel]" << ::std::endl;
171 out <<
"Cx : " << fixed_string( p.
Cx, 4, 6, 12 ) <<
" [pixel]" << ::std::endl;
172 out <<
"Cy : " << fixed_string( p.
Cy, 4, 6, 12 ) <<
" [pixel]" << ::std::endl;
173 out <<
"sx : " << fixed_string( p.
sx, 4, 6, 12 ) << ::std::endl;
176 out <<
"R =" << ::std::endl;
177 out << to_string( p.
r1, 2, 6 ) <<
", " << to_string( p.
r2, 2, 6 ) <<
", " << to_string( p.
r3, 2, 6 ) << ::std::endl;
178 out << to_string( p.
r4, 2, 6 ) <<
", " << to_string( p.
r5, 2, 6 ) <<
", " << to_string( p.
r6, 2, 6 ) << ::std::endl;
179 out << to_string( p.
r7, 2, 6 ) <<
", " << to_string( p.
r8, 2, 6 ) <<
", " << to_string( p.
r2, 2, 6 ) << ::std::endl;
182 out <<
"T [mm] = ( " << p.
Tx <<
", " << p.
Ty <<
", " << p.
Tz <<
" )" << ::std::endl;
183 out <<
"focal length = " << p.
f <<
" [mm]" << ::std::endl;
184 out <<
"Tz / f = " << p.
Tz / p.
f << ::std::endl;
185 out <<
"kappa1 = " << p.
ka1 <<
" [1/mm^2]" << ::std::endl;
191 template <
class T1,
class T2 >
192 struct __parameter__ :
public parameter
194 typedef parameter base;
198 const std::vector< point3 > &world;
199 const std::vector< point2 > ℑ
201 __parameter__(
const parameter &p,
const std::vector< point3 > &w,
const std::vector< point2 > &i )
202 : base( p ), world( w ), image( i )
206 template <
class TT >
207 double operator( )(
const matrix< TT > &v )
const
209 typedef matrix< TT >::size_type size_type;
216 for( size_type i = 0 ; i < world.size( ) ; i++ )
218 const point3 &w = world[ i ];
219 const point2 &p = image[ i ];
220 double Xd = ( p.x - Cx ) * dpx / sx;
221 double Yd = ( p.y - Cy ) * dpy;
222 double x = r1 * w.x + r2 * w.y + r3 * w.z + Tx;
223 double y = r4 * w.x + r5 * w.y + r6 * w.z + Ty;
224 double z = r7 * w.x + r8 * w.y + r9 * w.z + Tz;
225 double rr = Xd * Xd + Yd * Yd;
227 double e1 = f * x - Xd * ( 1 + ka1 * rr ) * z;
228 double e2 = f * y - Yd * ( 1 + ka1 * rr ) * z;
234 err += std::sqrt( e1 * e1 + e2 * e2 );
251 template <
class T1,
class T2 >
259 double r1, r2, r3, r4, r5, r6, r7, r8, r9;
274 double dpx = dx * Ncx / Nfx;
275 double dpy = dy * Ncy / Nfy;
277 size_type i, num = image.size( );
279 matrix_type A( num, 5 ), B( num, 1 );
282 for( i = 0 ; i < num ; i++ )
284 const point3 &w = world[ i ];
285 const point2 &p = image[ i ];
286 double Xd = ( p.x - Cx ) * dpx / sx;
287 double Yd = ( p.y - Cy ) * dpy;
289 A( i, 0 ) = Yd * w.x;
290 A( i, 1 ) = Yd * w.y;
292 A( i, 3 ) = - Xd * w.x;
293 A( i, 4 ) = - Xd * w.y;
298 matrix_type L =
inverse( A ) * B;
303 double Ty_Tx = L[ 2 ];
307 bool b1 = std::abs( r1_ ) > 1.0e-12;
308 bool b2 = std::abs( r2_ ) > 1.0e-12;
309 bool b4 = std::abs( r4_ ) > 1.0e-12;
310 bool b5 = std::abs( r5_ ) > 1.0e-12;
312 if( b1 && b2 && b4 && b5 )
314 double Sr = r1_ * r1_ + r2_ * r2_ + r4_ * r4_ + r5_ * r5_;
315 double Br = r1_ * r5_ - r4_ * r2_;
316 Ty = ( Sr - std::sqrt( Sr * Sr - 4.0 * Br * Br ) ) / ( 2.0 * Br * Br );
338 Ty = 1.0 / ( rr[ 0 ] * rr[ 0 ] + rr[ 1 ] * rr[ 1 ] );
345 point3 w = world[ 0 ];
346 point2 p = image[ 0 ];
347 double len = ( p.x - Cx ) * ( p.x - Cx ) + ( p.y - Cy ) * ( p.y - Cy );
348 for( i = 1 ; i < num ; i++ )
350 point3 ww = world[ i ];
351 point2 pp = image[ i ];
352 double l = ( pp.x - Cx ) * ( pp.x - Cx ) + ( pp.y - Cy ) * ( pp.y - Cy );
361 Ty = std::sqrt( Ty );
368 double x = r1 * w.x + r2 * w.y + Tx;
369 double y = r4 * w.x + r5 * w.y + Ty;
370 if( x * p.x > 0 && y * p.y > 0 )
392 double s = -1.0 * ( r1 * r4 + r2 * r5 < 0.0 ? -1.0 : 1.0 );
394 r3 = std::sqrt( 1.0 - r1 * r1 - r2 * r2 );
395 r6 = s * std::sqrt( 1.0 - r4 * r4 - r5 * r5 );
396 r7 = r2 * r6 - r3 * r5;
399 double Rz = std::atan2( r4, r1 );
401 double s1, s2, s3, c1, c2, c3;
406 double Ry = std::atan2( -r7, r1 * c3 + r4 * s3 );
407 double Rx = std::atan2( r3 * s3 - r6 * c3, r5 * c3 - r2 * s3 );
415 r2 = c3 * s1 * s2 - c1 * s3;
416 r3 = s1 * s3 + c1 * c3 * s2;
418 r5 = s1 * s2 * s3 + c1 * c3;
419 r6 = c1 * s2 * s3 - c3 * s1;
429 for( i = 0 ; i < num ; i++ )
431 const point3 &w = world[ i ];
432 const point2 &p = image[ i ];
433 double Yd = ( p.y - Cy ) * dpy;
435 A( i, 0 ) = r4 * w.x + r5 * w.y + r6 * 0 + Ty;
437 B( i, 0 ) = ( r7 * w.x + r8 * w.y + r9 * 0 ) * Yd;
455 double Rz = atan2( r4, r1 );
456 double s3 = std::sin( Rz );
457 double c3 = std::cos( Rz );
458 double Ry = atan2( -r7, r1 * c3 + r4 * s3 );
459 double Rx = atan2( r3 * s3 - r6 * c3, r5 * c3 - r2 * s3 );
461 double s1 = std::sin( Rx );
462 double c1 = std::cos( Rx );
463 double s2 = std::sin( Ry );
464 double c2 = std::cos( Ry );
467 r2 = c3 * s1 * s2 - c1 * s3;
468 r3 = s1 * s3 + c1 * c3 * s2;
470 r5 = s1 * s2 * s3 + c1 * c3;
471 r6 = c1 * s2 * s3 - c3 * s1;
477 for( i = 0 ; i < num ; i++ )
479 const point3 &w = world[ i ];
480 const point2 &p = image[ i ];
481 double Yd = ( p.y - Cy ) * dpy;
483 A( i, 0 ) = r4 * w.x + r5 * w.y + r6 * 0 + Ty;
485 B( i, 0 ) = ( r7 * w.x + r8 * w.y + r9 * 0 ) * Yd;
501 __parameter__< T1, T2 > param( p, world, image );
535 param.ka1 = ppp[ 2 ];
571 #endif // __INCLUDE_MIST_CALIBRATION__