24 double R_matrix[3][3],
29 double S_matrix[3][3],
62 extern void showmatrix(CvMat &M,
const char *header);
71 extern void showmatrix(
const char *header,CvMat &M);
81 v_homography_r_t = cvCreateMat( 3, 4, CV_64FC1 );
82 v_homography_r_t_jacobian = cvCreateMat( 3, 9, CV_64FC1 );
87 cvReleaseMat(&v_homography_r_t);
88 cvReleaseMat(&v_homography_r_t_jacobian);
91 void CamAugmentation::ReleaseOptimalCameraStructure(){
92 for(
int i = 0; i < (int)s_optimal.v_camera_c.size(); i++ ) cvReleaseMat(&s_optimal.v_camera_c[i]);
93 s_optimal.v_camera_c.clear();
94 for(
int i = 0; i < (int)s_optimal.v_camera_r_t.size(); i++ ) cvReleaseMat(&s_optimal.v_camera_r_t[i]);
95 s_optimal.v_camera_r_t.clear();
96 for(
int i = 0; i < (int)s_optimal.v_camera_r_t_jacobian.size(); i++ ) cvReleaseMat(&s_optimal.v_camera_r_t_jacobian[i]);
97 s_optimal.v_camera_r_t_jacobian.clear();
101 for(
int i = 0; i < (int)v_homography.size(); i++ )
102 delete v_homography[i];
103 v_homography.clear();
104 ReleaseOptimalCameraStructure();
112 if( (stream = fopen( cam_c_file,
"r+t" )) != NULL ){
113 int num,width,height;
114 while( fscanf( stream,
"no: %i\nwidth: %i\nheight: %i\n", &num, &width, &height ) != EOF ){
116 CvMat* m = cvCreateMat( 3, 3, CV_64FC1 );
117 for(
int i=0; i < 3; i++)
118 for(
int j=0; j < 3; j++) {
119 fscanf( stream,
"%f", &h );
122 fscanf( stream,
"\n" );
123 s_optimal.v_camera_width.push_back( width );
124 s_optimal.v_camera_height.push_back( height );
125 s_optimal.v_camera_c.push_back( m );
126 printf(
"Calibration matrix %i loaded!\n", num );
130 printf(
"WARNING: Could not load matrices from file %s.", cam_c_file );
135 if( (stream = fopen( cam_rt_file,
"r+t" )) != NULL ){
136 int num,width,height;
137 while( fscanf( stream,
"no: %i\nwidth: %i\nheight: %i\n", &num, &width, &height ) != EOF ){
139 CvMat* m = cvCreateMat( 3, 4, CV_64FC1 );
140 for(
int i=0; i < 3; i++)
141 for(
int j=0; j < 4; j++) {
142 fscanf( stream,
"%f", &h );
145 fscanf( stream,
"\n" );
146 s_optimal.v_camera_r_t.push_back( m );
149 CvMat* R = cvCreateMat( 3, 3, CV_64FC1 );
150 CvMat* r = cvCreateMat( 3, 1, CV_64FC1 );
151 CvMat* j = cvCreateMat( 3, 9, CV_64FC1 );
153 cvRodrigues2( R, r, j );
154 s_optimal.v_camera_r_t_jacobian.push_back( j );
155 printf(
"Rotation-Translation matrix %i loaded and jacobian created!\n", num );
159 printf(
"WARNING: Could not load matrices from file %s.", cam_rt_file );
167 s_struct_homography *s_homography =
new s_struct_homography();
170 v_homography.push_back( s_homography );
175 s_struct_homography *s_homography =
new s_struct_homography();
178 s_homography->v_point = p;
179 s_homography->m_homography =
new homography();
180 cvCopy(ready, s_homography->m_homography);
183 v_homography.push_back( s_homography );
186 CvMat* CamAugmentation::InverseCalibrationMatrix( CvMat *in ){
187 if(
cvmGet( in, 1, 1 ) != 0 ){
188 CvMat* out = cvCreateMat( 3, 3, CV_64FC1 );
190 double f =
cvmGet( in, 1, 1 );
191 double u0 =
cvmGet( in, 0, 2 );
192 double v0 =
cvmGet( in, 1, 2 );
193 cvmSet( out, 0, 0, 1.00/(tau*f) );
194 cvmSet( out, 0, 1, 0.00 );
195 cvmSet( out, 0, 2, -(u0)/(tau*f) );
196 cvmSet( out, 1, 0, 0.00 );
197 cvmSet( out, 1, 1, 1.00/f );
198 cvmSet( out, 1, 2, -(v0)/f );
199 cvmSet( out, 2, 0, 0.00 );
200 cvmSet( out, 2, 1, 0.00 );
201 cvmSet( out, 2, 2, 1.00 );
207 bool CamAugmentation::CreateHomographyRotationTranslationMatrix(
int c ){
211 CvMat* m_homography = v_homography[c]->m_homography;
217 CvMat m_H1 = cvMat( 3, 1, CV_64FC1, a_H1 );
218 for( i = 0; i < 3; i++ )
cvmSet( &m_H1, i, 0,
cvmGet( m_homography, i, 0 ) );
221 CvMat m_H2 = cvMat( 3, 1, CV_64FC1, a_H2 );
222 for( i = 0; i < 3; i++ )
cvmSet( &m_H2, i, 0,
cvmGet( m_homography, i, 1 ) );
225 CvMat m_H3 = cvMat( 3, 1, CV_64FC1, a_H3 );
226 for( i = 0; i < 3; i++ )
cvmSet( &m_H3, i, 0,
cvmGet( m_homography, i, 2 ) );
229 CvMat m_CinvH1 = cvMat( 3, 1, CV_64FC1, a_CinvH1 );
232 CvMat m_R1 = cvMat( 3, 1, CV_64FC1, a_R1 );
235 CvMat m_R2 = cvMat( 3, 1, CV_64FC1, a_R2 );
238 CvMat m_R3 = cvMat( 3, 1, CV_64FC1, a_R3 );
242 CvMat m_R = cvMat( 3, 3, CV_64FC1, a_R );
246 CvMat m_T = cvMat( 3, 1, CV_64FC1, a_T );
250 CvMat* m_Cinv = InverseCalibrationMatrix( s_optimal.v_camera_c[c] );
253 cvGEMM( m_Cinv, &m_H1, 1, NULL, 0, &m_CinvH1, 0 );
256 if( cvNorm( &m_CinvH1, NULL, CV_L2, NULL ) != 0 ){
257 double lambda = 1.00/cvNorm( &m_CinvH1, NULL, CV_L2, NULL );
260 cvGEMM( m_Cinv, &m_H1, lambda, NULL, 0, &m_R1, 0 );
261 cvGEMM( m_Cinv, &m_H2, lambda, NULL, 0, &m_R2, 0 );
264 cvCrossProduct( &m_R1, &m_R2, &m_R3 );
267 for( i = 0; i < 3; i++ ){
274 cvGEMM( m_Cinv, &m_H3, -lambda, NULL, 0, &m_T, 0 );
277 double a_W[9]; CvMat m_W = cvMat( 3, 3, CV_64FC1, a_W );
278 double a_U[9]; CvMat m_U = cvMat( 3, 3, CV_64FC1, a_U );
279 double a_Vt[9]; CvMat m_Vt = cvMat( 3, 3, CV_64FC1, a_Vt );
280 cvSVD( &m_R, &m_W, &m_U, &m_Vt, CV_SVD_MODIFY_A | CV_SVD_V_T );
281 cvMatMul( &m_U, &m_Vt, &m_R );
285 double a_view_to_cam[12];
286 CvMat m_view_to_cam = cvMat( 3, 4, CV_64FC1, a_view_to_cam );
290 double a_cam_inv[12];
291 CvMat m_cam_inv = cvMat( 3, 4, CV_64FC1, a_cam_inv );
301 bool CamAugmentation::EstimateHomographyRT(){
304 for(
int c = 0; c < (int)v_homography.size(); c++ ){
307 if( v_homography[c]->m_homography && (
int)s_optimal.v_camera_c.size() > c ){
308 return CreateHomographyRotationTranslationMatrix( c );
314 int CamAugmentation::GetObservationNumber(){
316 for(
int c = 0; c < (int)v_homography.size(); c++ ){
317 num += (int)v_homography[c]->v_point.size();
322 void CamAugmentation::updateCB(
double *params,
void **user_data ){
326 int parameter_number = 6;
327 for(
int i = 0; i < parameter_number; i++ )
328 cam->v_opt_param[i] = params[i];
331 cam->SetParameterSet();
334 void CamAugmentation::GetParameterSet(){
339 double a_R[9]; CvMat m_R = cvMat( 3, 3, CV_64FC1, a_R );
340 double a_r[3]; CvMat m_r = cvMat( 3, 1, CV_64FC1, a_r );
341 double a_T[3]; CvMat m_T = cvMat( 3, 1, CV_64FC1, a_T );
345 v_opt_param.push_back( -
cvmGet( &m_T, 0, 0 ) );
346 v_opt_param.push_back( -
cvmGet( &m_T, 1, 0 ) );
347 v_opt_param.push_back( -
cvmGet( &m_T, 2, 0 ) );
348 cvRodrigues2( &m_R, &m_r, v_homography_r_t_jacobian );
349 v_opt_param.push_back(
cvmGet( &m_r, 0, 0 ) );
350 v_opt_param.push_back(
cvmGet( &m_r, 1, 0 ) );
351 v_opt_param.push_back(
cvmGet( &m_r, 2, 0 ) );
354 void CamAugmentation::SetParameterSet(){
356 double a_R[9]; CvMat m_R = cvMat( 3, 3, CV_64FC1, a_R );
357 double a_r[3]; CvMat m_r = cvMat( 3, 1, CV_64FC1, a_r );
358 double a_T[3]; CvMat m_T = cvMat( 3, 1, CV_64FC1, a_T );
361 cvmSet( &m_T, 0, 0, -v_opt_param[0] );
362 cvmSet( &m_T, 1, 0, -v_opt_param[1] );
363 cvmSet( &m_T, 2, 0, -v_opt_param[2] );
364 cvmSet( &m_r, 0, 0, v_opt_param[3] );
365 cvmSet( &m_r, 1, 0, v_opt_param[4] );
366 cvmSet( &m_r, 2, 0, v_opt_param[5] );
367 cvRodrigues2( &m_r, &m_R, v_homography_r_t_jacobian );
380 virtual void eval_func(
const double *params,
double *f,
double *J,
void **user_data)
const;
391 double a_p[4];
double a_p3[3];
double a_p4[3];
392 double a_RT[12]; CvMat m_RT = cvMat( 3, 4, CV_64FC1, a_RT );
393 a_p[0] = cam->v_homography[c]->v_point[
point].x; a_p[2] = 0;
394 a_p[1] = cam->v_homography[c]->v_point[
point].y; a_p[3] = 1;
395 CvMat m_p = cvMat( 4, 1, CV_64FC1, a_p );
396 CvMat m_p3 = cvMat( 3, 1, CV_64FC1, a_p3 );
397 CvMat m_p4 = cvMat( 3, 1, CV_64FC1, a_p4 );
399 cvMatMul( &m_RT, &m_p, &m_p3 );
400 cvMatMul( cam->s_optimal.v_camera_c[c], &m_p3, &m_p4 );
402 f[0] =
cvmGet( &m_p4, 0, 0 );
403 f[1] =
cvmGet( &m_p4, 1, 0 );
410 double a_R1[9]; CvMat m_R1 = cvMat( 3, 3, CV_64FC1, a_R1 );
411 double a_T1[3]; CvMat m_T1 = cvMat( 3, 1, CV_64FC1, a_T1 );
412 double a_R2[9]; CvMat m_R2 = cvMat( 3, 3, CV_64FC1, a_R2 );
413 double a_T2[3]; CvMat m_T2 = cvMat( 3, 1, CV_64FC1, a_T2 );
418 for(
int i = 0; i < 3; i++ )
419 for(
int j = 0; j < 3; j++ )
420 R1[i][j] =
cvmGet( &m_R1, i, j );
423 for(
int i = 0; i < 3; i++ )
424 for(
int j = 0; j < 3; j++ )
425 R2[i][j] =
cvmGet( &m_R2, i, j );
431 cvmGet( cam->s_optimal.v_camera_c[c], 1, 1 ),
432 cvmGet( cam->s_optimal.v_camera_c[c], 0, 2 ),
433 cvmGet( cam->s_optimal.v_camera_c[c], 1, 2 ),
438 cam->s_optimal.v_camera_r_t_jacobian[c],
443 cam->v_homography_r_t_jacobian,
448 for(
int i = 0; i < 3; i++ )
449 grad0[gc++] = cgret[6+i+3];
450 for(
int i = 0; i < 3; i++ )
451 grad0[gc++] = cgret[6+i];
453 for(
int i = 0; i < 3; i++ )
454 grad1[gc++] = cgret[12+6+i+3];
455 for(
int i = 0; i < 3; i++ )
456 grad1[gc++] = cgret[12+6+i];
460 bool CamAugmentation::OptimizeCurrentView(
int iter,
double eps ){
463 int parameter_number = 6;
464 int observation_number = GetObservationNumber();
467 minimizer.set_user_data(0,
this);
468 minimizer.set_state_change_callback(updateCB);
469 minimizer.lm_set_max_iterations(iter);
477 for(
int c = 0; c < (int)v_homography.size(); c++ )
478 if( v_homography[c]->m_homography ){
479 int points = (int)v_homography[c]->v_point.size();
480 for(
int point = 0; point < points; point++ ){
484 o->
target[0] = v_homography[c]->v_point[point].u;
485 o->
target[1] = v_homography[c]->v_point[point].v;
486 minimizer.add_observation(o,
true,
false);
490 minimizer.minimize_using_levenberg_marquardt_from(&v_opt_param[0]);
493 updateCB(minimizer.state, &ptr);
499 if( EstimateHomographyRT() ){
500 return OptimizeCurrentView( iter, eps );
506 for(
int i = 0; i < (int)v_homography.size(); i++ )
507 delete v_homography[i];
508 v_homography.clear();
514 if( s_optimal.v_camera_c.size() > (unsigned)c ){
517 if( s_optimal.v_camera_c[c] && s_optimal.v_camera_r_t[c] && v_homography_r_t ){
518 CvMat* m_proj = cvCreateMat( 3, 4, CV_64FC1 );
519 cvMatMul( s_optimal.v_camera_c[c], s_optimal.v_camera_r_t[c], m_proj );
531 if( s_optimal.v_camera_c.size() > (unsigned)c ){
534 if( s_optimal.v_camera_c[c] && s_optimal.v_camera_r_t[c] ){
535 CvMat* m_proj = cvCreateMat( 3, 4, CV_64FC1 );
536 cvMatMul( s_optimal.v_camera_c[c], s_optimal.v_camera_r_t[c], m_proj );
547 if( s_optimal.v_camera_c.size() > (unsigned)c ){
549 if(s_optimal.v_camera_r_t[c])
550 return cvCloneMat(s_optimal.v_camera_r_t[c]);
558 if (v_homography_r_t)
559 return cvCloneMat(v_homography_r_t);