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);
86 srand( (
unsigned)time(NULL) );
87 printf(
"Welcome to AMCC!\n");
88 printf(
"================\n\n");
96 if( m_CH ) cvReleaseMat( &m_CH );
97 for(
int i = 0; i < (int)v_camera.size(); i++ )
100 ReleaseOptimalCameraStructure();
102 if( m_CH ) cvReleaseMat( &m_CH ); m_CH = NULL;
106 v_camera.push_back(
new s_struct_camera( width, height ) );
111 if( (
int)v_camera.size() <= c ){
112 printf(
"ERROR: Homography has not been added: Camera %i does not exist!\n",c);
117 s_struct_homography *s_homography =
new s_struct_homography();
120 v_camera[c]->v_homography.push_back( s_homography );
127 if( (
int)v_camera.size() <= c ){
128 printf(
"ERROR: Homography has not been added because Camera %i doesn't exist!\n",c);
133 s_struct_homography *s_homography =
new s_struct_homography();
136 s_homography->s_plane_object->px =
new double[p.size()];
137 s_homography->s_plane_object->py =
new double[p.size()];
140 for(
unsigned i = 0; i < p.size(); i++ ){
142 s_homography->s_plane_object->px[i] = p[i].x;
143 s_homography->s_plane_object->py[i] = p[i].y;
144 CvMat *plane_point = cvCreateMat( 3, 1, CV_64FC1 );
145 cvmSet( plane_point, 0, 0, p[i].u );
146 cvmSet( plane_point, 1, 0, p[i].v );
147 cvmSet( plane_point, 2, 0, 1 );
148 s_homography->s_plane_object->v_m_pp.push_back( plane_point );
152 s_homography->s_plane_object->p = p.size();
155 v_camera[c]->v_homography.push_back( s_homography );
158 CreateWorldPlaneHomography( c, (
int)v_camera[c]->v_homography.size()-1, ready );
166 if( (stream = fopen( file_name,
"w+t" )) != NULL ){
167 for(
int c = 0; c < (int)v_camera.size(); c++ ){
168 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ ){
169 if( v_camera[c]->v_homography[h]->m_homography ){
171 s_struct_plane* s_plane_object = v_camera[c]->v_homography[h]->s_plane_object;
172 int p = (*s_plane_object).p;
173 length = sprintf(buffer,
"%i %i %i %i %i\n",c,h,p,v_camera[c]->w,v_camera[c]->h);
174 fwrite( buffer,
sizeof(
char), length, stream );
176 for(
int i = 0; i < p; i++ ){
177 double x = (*s_plane_object).px[i];
178 double y = (*s_plane_object).py[i];
179 double u =
cvmGet( (*s_plane_object).v_m_pp[i], 0, 0 );
180 double v =
cvmGet( (*s_plane_object).v_m_pp[i], 1, 0 );
181 length = sprintf(buffer,
"%f %f %f %f\n",x,y,u,v);
182 fwrite( buffer,
sizeof(
char), length, stream );
185 homography *m_homography = v_camera[c]->v_homography[h]->m_homography;
186 for(
int i=0; i < 3; i++) {
187 for(
int j=0; j < 3; j++) {
188 length = sprintf(buffer,
"%f ",m_homography->
cvmGet(i,j));
189 fwrite( buffer,
sizeof(
char), length, stream );
191 length = sprintf(buffer,
"\n");
192 fwrite( buffer,
sizeof(
char), length, stream );
195 length = sprintf(buffer,
"%i %i 0 %i %i\n",c,h,v_camera[c]->w,v_camera[c]->h);
196 fwrite( buffer,
sizeof(
char), length, stream );
200 printf(
"\n----------------------------\n");
201 printf(
"Homographies stored to file!\n");
202 printf(
"----------------------------\n\n");
212 if( (stream = fopen( file_name,
"r+t" )) != NULL ){
214 c=-1;h=-1;p=-1;iw=-1;ih=-1;
215 while( fscanf( stream,
"%i %i %i %i %i\n", &c, &h, &p, &iw, &ih ) != EOF ){
222 std::vector<CamCalibration::s_struct_points> points;
223 for(
int i = 0; i < p; i++ ){
224 fscanf( stream,
"%f %f %f %f\n", &x, &y, &u, &v );
230 for(
int i=0; i < 3; i++)
231 for(
int j=0; j < 3; j++) {
232 fscanf( stream,
"%f", &h );
233 m_homography->
cvmSet(i,j,h);
245 std::vector<CamCalibration::s_struct_solution> CamCalibration::GetRandomSolution(
int num ){
246 std::vector<s_struct_solution> current_solution;
250 while ((
int)v_camera.size() <= (c =
rand()/(RAND_MAX/(int)v_camera.size())) );
251 while ((
int)v_camera[0]->v_homography.size() <= (h =
rand()/(RAND_MAX/(int)v_camera[0]->v_homography.size())) );
254 if( v_camera[c]->v_homography[h]->m_homography ){
257 bool in_vector =
false;
258 for(
int i = 0; i < (int)current_solution.size(); i++ )
259 if( current_solution[i].c == c && current_solution[i].h == h )
264 current_solution.push_back(s_struct_solution(c,h));
266 }
while( (
int)current_solution.size() < num );
267 return current_solution;
270 double CamCalibration::GetScreenDistance(
int c,
int h1,
int h2 ){
272 double a_w[] = { 0, 0, 1 }; CvMat m_w = cvMat( 3, 1, CV_64FC1, a_w );
273 double a_p1[3]; CvMat m_p1 = cvMat( 3, 1, CV_64FC1, a_p1 );
274 double a_p2[3]; CvMat m_p2 = cvMat( 3, 1, CV_64FC1, a_p2 );
275 double a_h1[9]; CvMat m_h1 = cvMat( 3, 3, CV_64FC1, a_h1 );
276 double a_h2[9]; CvMat m_h2 = cvMat( 3, 3, CV_64FC1, a_h2 );
279 for(
int i = 0; i < 3; i++ )
280 for(
int j = 0; j < 3; j++ ){
281 cvmSet( &m_h1, i, j,
cvmGet( v_camera[c]->v_homography[h1]->m_homography, i, j ) );
282 cvmSet( &m_h2, i, j,
cvmGet( v_camera[c]->v_homography[h2]->m_homography, i, j ) );
290 return sqrt( pow(
cvmGet(&m_p1,0,0)-
cvmGet(&m_p2,0,0),2) +
294 double CamCalibration::GetSolutionQuality( std::vector<s_struct_solution> solution,
double p_PreFilter_a,
double p_PreFilter_b,
double p_PreFilter_c ){
297 int overall_points = 0;
298 for(
int c = 0; c < (int)v_camera.size(); c++ )
299 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
300 if( v_camera[c]->v_homography[h]->m_homography )
301 overall_points += v_camera[c]->v_homography[h]->s_plane_object->p;
303 int solution_points = 0;
304 for(
int i = 0; i < (int)solution.size(); i++ )
305 solution_points += v_camera[solution[i].c]->v_homography[solution[i].h]->s_plane_object->p;
308 double q1 = (
double)solution_points/(double)overall_points;
312 int overall_connections = (int)v_camera.size()*(int)v_camera[0]->v_homography.size();
313 int solution_connections = 0;
314 for(
int h = 0; h < (int)v_camera[0]->v_homography.size(); h++ ){
315 int current_connections = 0;
316 for(
int i = 0; i < (int)solution.size(); i++ )
317 if( solution[i].h == h )
318 current_connections++;
320 solution_connections += (int)pow((
double)current_connections,2.);
322 double q2 = (double)solution_connections/(
double)overall_connections;
326 double overall_distances = 0;
327 double solution_distances = 0;
328 for(
int c = 0; c < (int)v_camera.size(); c++ ){
330 for(
int i = 0; i < (int)solution.size(); i++ )
331 if( solution[i].c == c )
334 double overall_cam_distances = pow((
double)hom_cam_num,2.)*sqrt(pow((
double)v_camera[c]->w,2.)+pow((
double)v_camera[c]->h,2.));
335 double solution_cam_distances = 0;
336 for(
int i = 0; i < (int)solution.size(); i++ )
337 if( solution[i].c == c )
338 for(
int j = 0; j < (int)solution.size(); j++ )
339 if( solution[j].c == c )
340 solution_cam_distances += GetScreenDistance(c,solution[i].h,solution[j].h);
342 overall_distances += overall_cam_distances;
343 solution_distances += solution_cam_distances;
346 double q3 = solution_distances/overall_distances;
347 return p_PreFilter_a*q1+p_PreFilter_b*q2+p_PreFilter_c*q3;
351 bool CamCalibration::FilterBestHomographiesGreedyMethod(
int num ){
353 printf(
"INFO: Starting pre-filtering process, greedy method...\n" );
354 for(
int h = 0; h < (int)v_camera[0]->v_homography.size(); h++ )
355 for(
int c = 0; c < (int)v_camera.size(); c++ )
356 if( v_camera[c]->v_homography[h]->m_homography ){
358 DeleteWorldPlaneHomography(c,h);
359 printf(
"INFO: View %i of camera %i has been deleted!\n", h, c );
365 printf(
"WARNING: Only %i homographies available instead of the requested %i ones!\n", cnt, num );
367 printf(
"INFO: Pre-filtering process finished\n" );
373 for (
int i=0; i<size; ++i) {
376 for (
int i=0; i<size; ++i) {
377 int n = (size*
rand())/RAND_MAX;
380 if (n>=size) n=size-1;
388 bool CamCalibration::FilterBestHomographiesFillingMethod(
int num,
double p_PreFilter_a ){
389 double ratio = p_PreFilter_a;
390 int cam = (int)v_camera.size();
391 int min = (int)floor((
double)num/((double)cam*ratio));
396 for(
int c = 0; c <
cam; c++ ){
398 for(
unsigned h = 0; h < v_camera[c]->v_homography.size(); h++ )
399 if (v_camera[c]->v_homography[h]->m_homography) {
400 v_camera[c]->v_homography[h]->b_discard=
true;
403 printf(
"Camera %d: %d homographies\n", c, totalHom);
405 for(
int i = 0; i < min; i++ ){
409 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
410 if( v_camera[c]->v_homography[h]->m_homography &&
411 v_camera[c]->v_homography[h]->s_plane_object->p > pmax &&
412 v_camera[c]->v_homography[h]->b_discard ){
413 pmax = (int)v_camera[c]->v_homography[h]->s_plane_object->p;
419 v_camera[c]->v_homography[hmax]->b_discard =
false;
425 printf(
"ERROR: Could not detect >= 2 homographies for camera %i\n", c );
430 int *random_h =
new int [v_camera[0]->v_homography.size()];
431 fill_random(random_h,v_camera[0]->v_homography.size());
433 for(
int i = cam; i > 0; i-- ){
434 for(
int _h = 0; _h < (int)v_camera[0]->v_homography.size(); _h++ ){
435 int h = random_h[_h];
437 for(
int c = 0; c <
cam; c++ )
438 if( v_camera[c]->v_homography[h]->m_homography )
441 for(
int c2 = 0; c2 <
cam; c2++ ){
442 if( v_camera[c2]->v_homography[h]->m_homography ){
443 if( v_camera[c2]->v_homography[h]->b_discard ){
444 v_camera[c2]->v_homography[h]->b_discard =
false;
460 for(
int i = 0; i <
cam; i++ ){
461 for(
int j = 0; j <
cam; j++ ){
464 for(
int h = 0; h < (int)v_camera[0]->v_homography.size(); h++ ) {
465 if (v_camera[i]->v_homography[h]->m_homography
466 && v_camera[j]->v_homography[h]->m_homography) {
467 if (!v_camera[i]->v_homography[h]->b_discard
468 && !v_camera[j]->v_homography[h]->b_discard)
474 if (taken > 5 || missed ==0)
continue;
475 int required =
imin(missed,5);
476 for(
int h = 0; h < (int)v_camera[0]->v_homography.size(); h++ ) {
477 if (v_camera[i]->v_homography[h]->m_homography
478 && v_camera[j]->v_homography[h]->m_homography) {
479 if (v_camera[i]->v_homography[h]->b_discard
480 || v_camera[j]->v_homography[h]->b_discard)
482 v_camera[i]->v_homography[h]->b_discard=
false;
483 v_camera[j]->v_homography[h]->b_discard=
false;
484 if (--required==0)
break;
492 for(
int c = 0; c <
cam; c++ )
493 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
494 if( v_camera[c]->v_homography[h]->m_homography &&
495 v_camera[c]->v_homography[h]->b_discard )
496 DeleteWorldPlaneHomography(c,h);
499 for(
int h = 0; h < (int)v_camera[0]->v_homography.size(); h++ ) {
501 for(
int c = 0; c <
cam; c++ ) {
502 taken = taken || (v_camera[c]->v_homography[h]->m_homography &&
503 !v_camera[c]->v_homography[h]->b_discard);
506 for(
int c = 0; c <
cam; c++ ) {
507 if (v_camera[c]->v_homography[h]->m_homography && v_camera[c]->v_homography[h]->b_discard) {
508 v_camera[c]->v_homography[h]->b_discard=
false;
516 printf(
"Selected %d homographies out of %d. Minimum was: %d\n", cnt, totalHom, num );
519 printf(
"ERROR: Only %i homographies available instead of the requested %i ones!\n", cnt, num );
524 bool CamCalibration::FilterBestHomographiesRandomMethod(
int num,
int p_Solutions,
double p_PreFilter_a,
double p_PreFilter_b,
double p_PreFilter_c ){
529 for(
int c = 0; c < (int)v_camera.size(); c++ )
530 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
531 if( v_camera[c]->v_homography[h]->m_homography )
536 printf(
"ERROR: Only %i homographies available instead of the requested %i ones!\n", hom_num, num );
539 printf(
"Filtering %i homographies out of %i ones ...\n", num, hom_num );
542 std::vector<s_struct_solution> best_solution;
543 double best_quality = 0;
544 for(
int i = 0; i < p_Solutions; i++ ){
545 std::vector<s_struct_solution> current_solution = GetRandomSolution( num );
546 printf(
"Solution %i, ",i);
548 double current_quality = GetSolutionQuality( current_solution, p_PreFilter_a, p_PreFilter_b, p_PreFilter_c );
549 printf(
"quality: %f",current_quality);
550 if( current_quality > best_quality ){
551 best_solution = current_solution;
552 best_quality = current_quality;
554 printf(
"best: %f",best_quality);
560 for(
int c = 0; c < (int)v_camera.size(); c++ )
561 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
562 if( v_camera[c]->v_homography[h]->m_homography ){
566 for(
int i = 0; i < (int)best_solution.size(); i++ )
567 if( c == best_solution[i].c && h == best_solution[i].h )
571 DeleteWorldPlaneHomography(c,h);
579 bool CamCalibration::Calibrate(
int p_HomographyNum,
int p_PreFilter,
int p_Solutions,
double p_PreFilter_a,
double p_PreFilter_b,
double p_PreFilter_c,
580 double p_InitialGuess_a,
double p_InitialGuess_b,
double p_InitialGuess_c,
581 int p_Iterations,
double p_Epsilon,
double p_PostFilter ){
584 stat_HomographyNum = p_HomographyNum;
585 stat_ExpStartTime = time(0);
588 switch( p_PreFilter ){
589 case 0: filter_ok = FilterBestHomographiesGreedyMethod ( p_HomographyNum );
break;
590 case 1: filter_ok = FilterBestHomographiesFillingMethod( p_HomographyNum, p_PreFilter_a );
break;
591 case 2: filter_ok = FilterBestHomographiesRandomMethod ( p_HomographyNum, p_Solutions, p_PreFilter_a, p_PreFilter_b, p_PreFilter_c );
break;
592 default: filter_ok = FilterBestHomographiesFillingMethod( p_HomographyNum, p_PreFilter_a );
break;
596 printf(
"ERROR: Homography filtering process failed!\n");
601 for(
int c = 0; c < (int)v_camera.size(); c++ ){
602 if( !ExtractIntrinsicParameters( c, p_InitialGuess_a, p_InitialGuess_b, p_InitialGuess_c ) ){
603 printf(
"ERROR: Extraction of intrinsic parameters of camera %i failed!\n",c);
606 CreateEstimatedCalibrationMatrixFromEstimatedIntrinsicParameters( c );
607 CreateEstimatedInverseCalibrationMatrixFromEstimatedIntrinsicParameters( c );
608 CreateAllRotationTranslationMatrices( c );
612 if( OptimizeCalibrationByMinimalParameterMethod( p_Iterations, p_Epsilon, p_PostFilter ) ){
618 void CamCalibration::PrintStatisticToFile(){
620 stat = fopen(
"stat.txt",
"a" );
621 fprintf( stat,
"%i %ld", stat_HomographyNum, time(0)-stat_ExpStartTime);
622 for(
int i = 0; i < (int)v_camera.size(); i++ )
623 for(
int j = 0; j < 4; j++ )
624 fprintf( stat,
" %f", v_opt_param[i*4+j] );
625 fprintf( stat,
"\n" );
626 printf(
"Statistic has successfully been saved!\n");
630 void CamCalibration::CreateAllRotationTranslationMatrices(
int c ){
631 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
632 if( v_camera[c]->v_homography[h]->m_homography )
633 CreateRotationTranslationMatrixFromInverseCalibrationMatrixAndHomography( c, h );
636 CvMat* CamCalibration::GetM(
enum matrix_desc desc,
int c,
int h ){
638 case m_calibration:
return v_camera[c]->m_calibration_matrix;
639 case m_rot_trans :
return v_camera[c]->m_rot_trans_matrix;
640 case m_estim_calib:
return v_camera[c]->m_estim_calib_matrix;
641 case m_estinvcalib:
return v_camera[c]->m_estinvcalib_matrix;
642 case m_estim_r_t :
return v_camera[c]->v_homography[h]->m_estim_r_t_matrix;
643 case m_jacobian :
return v_camera[c]->v_homography[h]->m_jacobian_matrix;\
644 default :
return NULL;
648 double CamCalibration::GetRandomValue(
double min,
double max ){
649 double delta = max - min;
650 double value = (double)
rand()/(double)RAND_MAX;
651 return min + delta*value;
655 void CamCalibration::AddGaussianNoise( CvMat* mat,
double noise ){
656 double u1 = GetRandomValue( 0, 1 );
657 double u2 = GetRandomValue( 0, 1 );
658 cvmSet( mat, 0, 0,
cvmGet( mat, 0, 0 ) + noise*sqrt(-2.00*log(u1))*cos(2*
M_PI*u2) );
659 cvmSet( mat, 1, 0,
cvmGet( mat, 1, 0 ) + noise*sqrt(-2.00*log(u1))*sin(2*
M_PI*u2) );
663 if( cvGetDimSize( mat, 0 ) > 1 ){
664 double d =
cvmGet( mat, cvGetDimSize( mat, 0 )-1, 0 );
666 for(
int i = 0; i < cvGetDimSize( mat, 0 ); i++ )
669 double d =
cvmGet( mat, 0, cvGetDimSize( mat, 1 )-1 );
671 for(
int i = 0; i < cvGetDimSize( mat, 1 ); i++ )
676 void CamCalibration::SetIntrinsicParam(
int c,
double f,
double a,
double u,
double v ){
677 v_camera[c]->s_intrinsic.focal = f;
678 v_camera[c]->s_intrinsic.aspect = a;
679 v_camera[c]->s_intrinsic.u0 = u;
680 v_camera[c]->s_intrinsic.v0 = v;
683 void CamCalibration::SetPlaneObject(
int c,
int h,
int p,
double px[],
double py[],
684 double rx,
double ry,
double rz,
double tx,
double ty,
double tz ){
686 s_struct_plane* s_plane_object = v_camera[c]->v_homography[h]->s_plane_object;
689 if( (*s_plane_object).px )
delete (*s_plane_object).px;
690 if( (*s_plane_object).py )
delete (*s_plane_object).py;
691 if( (*s_plane_object).v_m_wp.size() > 0 ){
692 for(
int i = 0; i < (int)(*s_plane_object).v_m_wp.size(); i++ )
693 cvReleaseMat( &(*s_plane_object).v_m_wp[i] );
694 (*s_plane_object).v_m_wp.clear();
696 if( (*s_plane_object).v_m_pp.size() > 0 ){
697 for(
int i = 0; i < (*s_plane_object).p; i++ )
698 cvReleaseMat( &(*s_plane_object).v_m_pp[i] );
699 (*s_plane_object).v_m_pp.clear();
703 (*s_plane_object).px =
new double[p];
704 (*s_plane_object).py =
new double[p];
705 for(
int i = 0; i < p; i++ ){
706 (*s_plane_object).v_m_wp.push_back(cvCreateMat( 4, 1, CV_64FC1 ));
707 (*s_plane_object).v_m_pp.push_back(cvCreateMat( 3, 1, CV_64FC1 ));
711 (*s_plane_object).p = p;
714 for(
int i = 0; i < p; i++ ){
715 (*s_plane_object).px[i] = px[i];
716 (*s_plane_object).py[i] = py[i];
720 (*s_plane_object).rx = rx;
721 (*s_plane_object).ry = ry;
722 (*s_plane_object).rz = rz;
723 (*s_plane_object).tx = tx;
724 (*s_plane_object).ty = ty;
725 (*s_plane_object).tz = tz;
728 void CamCalibration::Translate3DVector( CvMat* v,
double x,
double y,
double z ){
729 double a_T[] = { 1, 0, 0, -x,
733 CvMat m_T = cvMat( 4, 4, CV_64FC1, a_T );
734 cvMatMul( &m_T, v, v );
737 void CamCalibration::Rotate3DVector( CvMat* v,
double x,
double y,
double z ){
741 double a_Rx[] = { 1, 0, 0, 0,
742 0, cos(x), -sin(x), 0,
743 0, sin(x), cos(x), 0,
745 double a_Ry[] = { cos(y), 0, -sin(y), 0,
747 sin(y), 0, cos(y), 0,
749 double a_Rz[] = { cos(z), -sin(z), 0, 0,
750 sin(z), cos(z), 0, 0,
753 CvMat m_Rx = cvMat( 4, 4, CV_64FC1, a_Rx );
754 CvMat m_Ry = cvMat( 4, 4, CV_64FC1, a_Ry );
755 CvMat m_Rz = cvMat( 4, 4, CV_64FC1, a_Rz );
756 cvMatMul( &m_Rx, v, v );
757 cvMatMul( &m_Ry, v, v );
758 cvMatMul( &m_Rz, v, v );
795 void CamCalibration::Mat3x4ToMat4x4( CvMat* m_A, CvMat* m_B ){
796 for(
int i = 0; i < 3; i++ )
797 for(
int j = 0; j < 4; j++ )
805 void CamCalibration::Mat4x4ToMat3x4( CvMat* m_A, CvMat* m_B ){
806 for(
int i = 0; i < 3; i++ )
807 for(
int j = 0; j < 4; j++ )
812 double a_A2[16]; CvMat m_A2 = cvMat( 4, 4, CV_64FC1, a_A2 );
813 double a_B2[16]; CvMat m_B2 = cvMat( 4, 4, CV_64FC1, a_B2 );
814 double a_C2[16]; CvMat m_C2 = cvMat( 4, 4, CV_64FC1, a_C2 );
815 Mat3x4ToMat4x4( m_A, &m_A2 );
816 Mat3x4ToMat4x4( m_B, &m_B2 );
817 cvMatMul( &m_A2, &m_B2, &m_C2 );
818 Mat4x4ToMat3x4( &m_C2, m_C );
822 double a_R[9]; CvMat m_R = cvMat( 3, 3, CV_64FC1, a_R );
823 double a_T[3]; CvMat m_T = cvMat( 3, 1, CV_64FC1, a_T );
825 cvTranspose( &m_R, &m_R );
826 cvGEMM( &m_R, &m_T, -1.00, NULL, +1.00, &m_T, 0 );
830 void CamCalibration::CreatePlaneObjectWorldPoints(
int c,
int h ){
831 s_struct_plane* s_plane_object = v_camera[c]->v_homography[h]->s_plane_object;
832 for(
int i = 0; i < (*s_plane_object).p; i++ ){
835 cvmSet( (*s_plane_object).v_m_wp[i], 0, 0, (*s_plane_object).px[i] );
836 cvmSet( (*s_plane_object).v_m_wp[i], 1, 0, (*s_plane_object).py[i] );
837 cvmSet( (*s_plane_object).v_m_wp[i], 2, 0, 0.0 );
838 cvmSet( (*s_plane_object).v_m_wp[i], 3, 0, 1.0 );
841 Rotate3DVector ( (*s_plane_object).v_m_wp[i],
842 (*s_plane_object).rx,
843 (*s_plane_object).ry,
844 (*s_plane_object).rz );
846 Translate3DVector( (*s_plane_object).v_m_wp[i],
847 (*s_plane_object).tx,
848 (*s_plane_object).ty,
849 (*s_plane_object).tz );
853 void CamCalibration::CreatePlaneObjectPlanePoints(
int c,
int h,
double noise ){
854 s_struct_plane* s_plane_object = v_camera[c]->v_homography[h]->s_plane_object;
855 for(
int i = 0; i < (*s_plane_object).p; i++ ){
856 double a_P[12]; CvMat m_P = cvMat( 3, 4, CV_64FC1, a_P );
857 cvMatMul( GetM(m_calibration,c,h), GetM(m_rot_trans,c,h), &m_P );
858 cvMatMul( &m_P, (*s_plane_object).v_m_wp[i], (*s_plane_object).v_m_pp[i] );
860 AddGaussianNoise( (*s_plane_object).v_m_pp[i], noise );
864 void CamCalibration::CreateWorldPlaneHomography(
int c,
int h, CvMat *ready ){
865 s_struct_plane* s_plane_object = v_camera[c]->v_homography[h]->s_plane_object;
869 cvCopy(ready, m_homography);
873 for(
int i = 0; i < (*s_plane_object).p; i++ ){
875 m_homography->
add_match( (
float)(*s_plane_object).px[i],
876 (
float)(*s_plane_object).py[i],
877 (
float)
cvmGet( (*s_plane_object).v_m_pp[i], 0, 0 ),
878 (
float)
cvmGet( (*s_plane_object).v_m_pp[i], 1, 0 ) );
885 double CamCalibration::VectorAngle( CvMat* v1, CvMat* v2, CvMat* v3, CvMat* v4 ){
890 double a = x1*x2+y1*y2;
891 double b = sqrt(pow(x1,2)+pow(y1,2)) * sqrt(pow(x2,2)+pow(y2,2));
898 double CamCalibration::PointDistance( CvMat* v1, CvMat* v2 ){
901 return sqrt(pow(x,2)+pow(y,2));
904 void CamCalibration::DeleteWorldPlaneHomography(
int c,
int h ){
905 delete v_camera[c]->v_homography[h]->m_homography;
906 v_camera[c]->v_homography[h]->m_homography = NULL;
909 bool CamCalibration::HomographySingular(
int c,
int h,
double p_InitialGuess_a,
double p_InitialGuess_b,
double p_InitialGuess_c ){
912 double a_w1[] = { -1, -1, 1 }; CvMat m_w1 = cvMat( 3, 1, CV_64FC1, a_w1 );
913 double a_w2[] = { -1, 1, 1 }; CvMat m_w2 = cvMat( 3, 1, CV_64FC1, a_w2 );
914 double a_w3[] = { 1, 1, 1 }; CvMat m_w3 = cvMat( 3, 1, CV_64FC1, a_w3 );
915 double a_w4[] = { 1, -1, 1 }; CvMat m_w4 = cvMat( 3, 1, CV_64FC1, a_w4 );
916 double a_p1[3]; CvMat m_p1 = cvMat( 3, 1, CV_64FC1, a_p1 );
917 double a_p2[3]; CvMat m_p2 = cvMat( 3, 1, CV_64FC1, a_p2 );
918 double a_p3[3]; CvMat m_p3 = cvMat( 3, 1, CV_64FC1, a_p3 );
919 double a_p4[3]; CvMat m_p4 = cvMat( 3, 1, CV_64FC1, a_p4 );
920 double a_h[9]; CvMat m_h = cvMat( 3, 3, CV_64FC1, a_h );
923 for(
int i = 0; i < 3; i++ )
924 for(
int j = 0; j < 3; j++ )
925 cvmSet( &m_h, i, j,
cvmGet( v_camera[c]->v_homography[h]->m_homography, i, j ) );
934 double a1 = VectorAngle( &m_p1, &m_p4, &m_p1, &m_p2 );
935 double a2 = VectorAngle( &m_p2, &m_p3, &m_p2, &m_p1 );
936 double a3 = VectorAngle( &m_p3, &m_p4, &m_p3, &m_p2 );
937 double a4 = VectorAngle( &m_p4, &m_p1, &m_p4, &m_p3 );
938 double e1 = p_InitialGuess_a;
939 double e2 = p_InitialGuess_b;
940 if( a1 < e2 || (a1 > (
M_PI/2.00) - e1 && a1 < (
M_PI/2.00) + e1) || a1 >
M_PI - e2 ||
941 a2 < e2 || (a2 > (
M_PI/2.00) - e1 && a2 < (
M_PI/2.00) + e1) || a2 >
M_PI - e2 ||
942 a3 < e2 || (a3 > (
M_PI/2.00) - e1 && a3 < (
M_PI/2.00) + e1) || a3 >
M_PI - e2 ||
943 a4 < e2 || (a4 > (
M_PI/2.00) - e1 && a4 < (
M_PI/2.00) + e1) || a4 >
M_PI - e2 ){
948 double d1 = PointDistance( &m_p1, &m_p2 );
949 double d2 = PointDistance( &m_p2, &m_p3 );
950 double d3 = PointDistance( &m_p3, &m_p4 );
951 double d4 = PointDistance( &m_p4, &m_p1 );
952 double d5 = (d1+d2+d3+d4)/4.00;
953 double e3 = p_InitialGuess_c;
954 if( d1 < d5*e3 || d2 < d5*e3 || d3 < d5*e3 || d4 < d5*e3 ){
961 double CamCalibration::GetFrobeniusDistance(
int c,
int h1,
int h2 ){
966 for(
int i = 0; i < 3; i++ )
967 for(
int j = 0; j < 3; j++ ){
968 na += pow(
cvmGet( v_camera[c]->v_homography[h1]->m_homography, i, j ),2);
969 nb += pow(
cvmGet( v_camera[c]->v_homography[h2]->m_homography, i, j ),2);
976 for(
int i = 0; i < 3; i++ )
977 for(
int j = 0; j < 3; j++ ){
978 double a =
cvmGet( v_camera[c]->v_homography[h1]->m_homography, i, j )/na;
979 double b =
cvmGet( v_camera[c]->v_homography[h2]->m_homography, i, j )/nb;
980 sum += pow( a - b, 2 );
985 bool CamCalibration::GetDistalHomographiesForCalibration(
int c,
int *h1,
int *h2 ){
987 for(
int i = 0; i < (int)v_camera[c]->v_homography.size(); i++ )
988 for(
int j = 0; j < (int)v_camera[c]->v_homography.size(); j++ )
989 if( v_camera[c]->v_homography[i]->m_homography &&
990 v_camera[c]->v_homography[j]->m_homography ){
991 double dnew = GetFrobeniusDistance( c, i, j );
1005 bool CamCalibration::ExtractIntrinsicParameters(
int c,
double p_InitialGuess_a,
double p_InitialGuess_b,
double p_InitialGuess_c ){
1007 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
1008 if( v_camera[c]->v_homography[h]->m_homography )
1009 if( !HomographySingular( c, h, p_InitialGuess_a, p_InitialGuess_b, p_InitialGuess_c ) )
1014 printf(
"ERROR: Could not extract intrinsic parameters of camera %i\n", c );
1015 printf(
" because there are fewer than 2 views available!\n" );
1019 int rows_of_a = 2*homs;
1020 CvMat* m_A = cvCreateMat( rows_of_a, 4, CV_64FC1 );
1021 CvMat* m_X = cvCreateMat( 4, 1, CV_64FC1 );
1022 CvMat* m_B = cvCreateMat( rows_of_a, 1, CV_64FC1 );
1025 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
1026 if( v_camera[c]->v_homography[h]->m_homography )
1027 if( !HomographySingular( c, h, p_InitialGuess_a, p_InitialGuess_b, p_InitialGuess_c ) ){
1030 homography* m_homography = v_camera[c]->v_homography[h]->m_homography;
1032 double v_h11 = m_homography->
cvmGet( 0, 0 );
1033 double v_h12 = m_homography->
cvmGet( 0, 1 );
1034 double v_h21 = m_homography->
cvmGet( 1, 0 );
1035 double v_h22 = m_homography->
cvmGet( 1, 1 );
1036 double v_h31 = m_homography->
cvmGet( 2, 0 );
1037 double v_h32 = m_homography->
cvmGet( 2, 1 );
1040 cvmSet( m_A, homs*2, 0, (pow(v_h21,2)-pow(v_h22,2) ));
1041 cvmSet( m_A, homs*2, 1, 2*( v_h11*v_h31-v_h12*v_h32 ));
1042 cvmSet( m_A, homs*2, 2, 2*( v_h21*v_h31-v_h22*v_h32 ));
1043 cvmSet( m_A, homs*2, 3, (pow(v_h31,2)-pow(v_h32,2) ));
1044 cvmSet( m_B, homs*2, 0, (pow(v_h12,2)-pow(v_h11,2) ));
1047 cvmSet( m_A, homs*2+1, 0, (v_h22*v_h21 ) );
1048 cvmSet( m_A, homs*2+1, 1, (v_h11*v_h32 + v_h12*v_h31 ));
1049 cvmSet( m_A, homs*2+1, 2, (v_h32*v_h21 + v_h22*v_h31 ));
1050 cvmSet( m_A, homs*2+1, 3, (v_h32*v_h31) );
1051 cvmSet( m_B, homs*2+1, 0, (-v_h11*v_h12) );
1057 cvSolve( m_A, m_B, m_X, CV_SVD );
1060 double v_w22 =
cvmGet( m_X, 0, 0 );
1061 double v_w13 =
cvmGet( m_X, 1, 0 );
1062 double v_w23 =
cvmGet( m_X, 2, 0 );
1063 double v_w33 =
cvmGet( m_X, 3, 0 );
1066 cvReleaseMat( &m_A );
1067 cvReleaseMat( &m_X );
1068 cvReleaseMat( &m_B );
1071 double f2 = (v_w22*v_w33-v_w22*pow(v_w13,2)-pow(v_w23,2))/pow(v_w22,2);
1073 if( a2 < 0 || f2 < 0 ){
1074 printf(
"ERROR: Intrinsic parameters of camera %i could not be estimated (complex values)!\n",c);
1079 v_camera[c]->s_estim_int.focal = sqrt(f2);
1080 v_camera[c]->s_estim_int.aspect = sqrt(a2);
1081 v_camera[c]->s_estim_int.u0 = -v_w13;
1082 v_camera[c]->s_estim_int.v0 = -v_w23/v_w22;
1084 printf(
"Estimated camera %i (%03d views): %f %f %f %f\n", c, homs,
1085 v_camera[c]->s_estim_int.focal, v_camera[c]->s_estim_int.aspect,
1086 v_camera[c]->s_estim_int.u0, v_camera[c]->s_estim_int.v0 );
1245 void CamCalibration::CreateCalibrationMatrixFromIntrinsicParameters(
int c ){
1246 cvmSet( GetM(m_calibration,c,0), 0, 0, v_camera[c]->s_intrinsic.aspect*v_camera[c]->s_intrinsic.focal );
1247 cvmSet( GetM(m_calibration,c,0), 0, 1, 0.00 );
1248 cvmSet( GetM(m_calibration,c,0), 0, 2, v_camera[c]->s_intrinsic.u0 );
1249 cvmSet( GetM(m_calibration,c,0), 1, 0, 0.00 );
1250 cvmSet( GetM(m_calibration,c,0), 1, 1, v_camera[c]->s_intrinsic.focal );
1251 cvmSet( GetM(m_calibration,c,0), 1, 2, v_camera[c]->s_intrinsic.v0 );
1252 cvmSet( GetM(m_calibration,c,0), 2, 0, 0.00 );
1253 cvmSet( GetM(m_calibration,c,0), 2, 1, 0.00 );
1254 cvmSet( GetM(m_calibration,c,0), 2, 2, 1.00 );
1257 void CamCalibration::CreateEstimatedCalibrationMatrixFromEstimatedIntrinsicParameters(
int c ){
1258 cvmSet( GetM(m_estim_calib,c,0), 0, 0, v_camera[c]->s_estim_int.aspect*v_camera[c]->s_estim_int.focal );
1259 cvmSet( GetM(m_estim_calib,c,0), 0, 1, 0.00 );
1260 cvmSet( GetM(m_estim_calib,c,0), 0, 2, v_camera[c]->s_estim_int.u0 );
1261 cvmSet( GetM(m_estim_calib,c,0), 1, 0, 0.00 );
1262 cvmSet( GetM(m_estim_calib,c,0), 1, 1, v_camera[c]->s_estim_int.focal );
1263 cvmSet( GetM(m_estim_calib,c,0), 1, 2, v_camera[c]->s_estim_int.v0 );
1264 cvmSet( GetM(m_estim_calib,c,0), 2, 0, 0.00 );
1265 cvmSet( GetM(m_estim_calib,c,0), 2, 1, 0.00 );
1266 cvmSet( GetM(m_estim_calib,c,0), 2, 2, 1.00 );
1269 void CamCalibration::CreateEstimatedInverseCalibrationMatrixFromEstimatedIntrinsicParameters(
int c ){
1270 double tau = v_camera[c]->s_estim_int.aspect;
1271 double f = v_camera[c]->s_estim_int.focal;
1272 cvmSet( GetM(m_estinvcalib,c,0), 0, 0, 1.00/(tau*f) );
1273 cvmSet( GetM(m_estinvcalib,c,0), 0, 1, 0.00 );
1274 cvmSet( GetM(m_estinvcalib,c,0), 0, 2, -(v_camera[c]->s_estim_int.u0)/(tau*f) );
1275 cvmSet( GetM(m_estinvcalib,c,0), 1, 0, 0.00 );
1276 cvmSet( GetM(m_estinvcalib,c,0), 1, 1, 1.00/f );
1277 cvmSet( GetM(m_estinvcalib,c,0), 1, 2, -(v_camera[c]->s_estim_int.v0)/f );
1278 cvmSet( GetM(m_estinvcalib,c,0), 2, 0, 0.00 );
1279 cvmSet( GetM(m_estinvcalib,c,0), 2, 1, 0.00 );
1280 cvmSet( GetM(m_estinvcalib,c,0), 2, 2, 1.00 );
1283 void CamCalibration::CreateRotationTranslationMatrixFromInverseCalibrationMatrixAndHomography(
int c,
int h ){
1287 homography* m_homography = v_camera[c]->v_homography[h]->m_homography;
1293 CvMat m_H1 = cvMat( 3, 1, CV_64FC1, a_H1 );
1294 for( i = 0; i < 3; i++ )
cvmSet( &m_H1, i, 0,
cvmGet( m_homography, i, 0 ) );
1297 CvMat m_H2 = cvMat( 3, 1, CV_64FC1, a_H2 );
1298 for( i = 0; i < 3; i++ )
cvmSet( &m_H2, i, 0,
cvmGet( m_homography, i, 1 ) );
1301 CvMat m_H3 = cvMat( 3, 1, CV_64FC1, a_H3 );
1302 for( i = 0; i < 3; i++ )
cvmSet( &m_H3, i, 0,
cvmGet( m_homography, i, 2 ) );
1305 CvMat m_CinvH1 = cvMat( 3, 1, CV_64FC1, a_CinvH1 );
1308 CvMat m_R1 = cvMat( 3, 1, CV_64FC1, a_R1 );
1311 CvMat m_R2 = cvMat( 3, 1, CV_64FC1, a_R2 );
1314 CvMat m_R3 = cvMat( 3, 1, CV_64FC1, a_R3 );
1318 CvMat m_R = cvMat( 3, 3, CV_64FC1, a_R );
1322 CvMat m_T = cvMat( 3, 1, CV_64FC1, a_T );
1326 cvGEMM( GetM(m_estinvcalib,c,0), &m_H1, 1, NULL, 0, &m_CinvH1, 0 );
1329 if( cvNorm( &m_CinvH1, NULL, CV_L2, NULL ) != 0 ){
1330 double lambda = 1.00/cvNorm( &m_CinvH1, NULL, CV_L2, NULL );
1333 cvGEMM( GetM(m_estinvcalib,c,0), &m_H1, lambda, NULL, 0, &m_R1, 0 );
1334 cvGEMM( GetM(m_estinvcalib,c,0), &m_H2, lambda, NULL, 0, &m_R2, 0 );
1337 cvCrossProduct( &m_R1, &m_R2, &m_R3 );
1340 for( i = 0; i < 3; i++ ){
1347 cvGEMM( GetM(m_estinvcalib,c,0), &m_H3, -lambda, NULL, 0, &m_T, 0 );
1350 double a_W[9]; CvMat m_W = cvMat( 3, 3, CV_64FC1, a_W );
1351 double a_U[9]; CvMat m_U = cvMat( 3, 3, CV_64FC1, a_U );
1352 double a_Vt[9]; CvMat m_Vt = cvMat( 3, 3, CV_64FC1, a_Vt );
1353 cvSVD( &m_R, &m_W, &m_U, &m_Vt, CV_SVD_MODIFY_A | CV_SVD_V_T );
1354 cvMatMul( &m_U, &m_Vt, &m_R );
1362 void CamCalibration::CreateRotationTranslationIdentityMatrix(
int c ){
1363 for(
int i=0; i<3; i++ )
1364 for(
int j=0; j<4; j++ )
1365 cvmSet( GetM(m_rot_trans,c,0), i, j, 0.0 );
1366 cvmSet( GetM(m_rot_trans,c,0), 0, 0, 1.0 );
1367 cvmSet( GetM(m_rot_trans,c,1), 1, 1, 1.0 );
1368 cvmSet( GetM(m_rot_trans,c,2), 2, 2, 1.0 );
1371 void CamCalibration::CreateRotationTranslationMatrix(
int c,
double rx,
double ry,
double rz,
1372 double tx,
double ty,
double tz ){
1373 rx *= 2*
M_PI/360.00;
1374 ry *= 2*
M_PI/360.00;
1375 rz *= 2*
M_PI/360.00;
1376 double a_R[] = { 1, 0, 0,
1379 double a_Rx[] = { 1, 0, 0,
1380 0, cos(rx), -sin(rx),
1381 0, sin(rx), cos(rx) };
1382 double a_Ry[] = { cos(ry), 0, -sin(ry),
1384 sin(ry), 0, cos(ry) };
1385 double a_Rz[] = { cos(rz), -sin(rz), 0,
1386 sin(rz), cos(rz), 0,
1388 CvMat m_R = cvMat( 3, 3, CV_64FC1, a_R );
1389 CvMat m_Rx = cvMat( 3, 3, CV_64FC1, a_Rx );
1390 CvMat m_Ry = cvMat( 3, 3, CV_64FC1, a_Ry );
1391 CvMat m_Rz = cvMat( 3, 3, CV_64FC1, a_Rz );
1392 cvMatMul( &m_Rx, &m_R, &m_R );
1393 cvMatMul( &m_Ry, &m_R, &m_R );
1394 cvMatMul( &m_Rz, &m_R, &m_R );
1396 for(
int i = 0; i < 3; i++ )
1397 for(
int j = 0; j < 3; j++ )
1398 cvmSet( GetM(m_rot_trans,c,0), i, j,
cvmGet( &m_R, i, j ) );
1400 cvmSet( GetM(m_rot_trans,c,0), 0, 3, -tx );
1401 cvmSet( GetM(m_rot_trans,c,0), 1, 3, -ty );
1402 cvmSet( GetM(m_rot_trans,c,0), 2, 3, -tz );
1405 void CamCalibration::CreateEstimated3ChainMatrixRT(
int h1,
int c2,
int h2,
int c1 ){
1406 double a_RTinv[12]; CvMat m_RTinv = cvMat( 3, 4, CV_64FC1, a_RTinv );
1407 CvMat *m_RT11 = v_camera[c1]->v_homography[h1]->m_estim_r_t_matrix;
1408 CvMat *m_RT12 = v_camera[c1]->v_homography[h2]->m_estim_r_t_matrix;
1409 CvMat *m_RT21 = v_camera[c2]->v_homography[h1]->m_estim_r_t_matrix;
1410 CvMat *m_RT22 = v_camera[c2]->v_homography[h2]->m_estim_r_t_matrix;
1416 void CamCalibration::CreateEstimatedOptimalHomographyMatrixRT(
int h1,
int c1,
int h2 ){
1417 double a_RTinv[12]; CvMat m_RTinv = cvMat( 3, 4, CV_64FC1, a_RTinv );
1418 CvMat *m_RT11 = v_camera[c1]->v_homography[h1]->m_estim_r_t_matrix;
1419 CvMat *m_RT12 = v_camera[c1]->v_homography[h2]->m_estim_r_t_matrix;
1421 s_optimal.v_homography_r_t[h1] = cvCreateMat( 3, 4, CV_64FC1 );
1422 Mat3x4Mul( &m_RTinv, m_RT11, s_optimal.v_homography_r_t[h1] );
1425 void CamCalibration::CreateEstimatedOptimalCameraMatrixC(
int c ){
1426 s_optimal.v_camera_c[c] = cvCloneMat( v_camera[c]->m_estim_calib_matrix );
1429 void CamCalibration::CreateEstimatedOptimalCameraMatrixRT(
int c,
int h ){
1430 s_optimal.v_camera_r_t[c] = cvCloneMat( v_camera[c]->v_homography[h]->m_estim_r_t_matrix );
1433 bool CamCalibration::CreateMatrixCH(){
1437 cvReleaseMat( &m_CH );
1439 m_CH = cvCreateMat( v_camera.size(), v_camera[0]->v_homography.size(), CV_64FC1 );
1440 s_optimal.c_max = -1; s_optimal.h_max = -1;
1444 for(
int c = 0; c < (int)v_camera.size(); c++ )
1445 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ ){
1446 cvmSet( m_CH, c, h, v_camera[c]->v_homography[h]->m_homography ? 1 : 0 );
1447 if( v_camera[c]->v_homography[h]->m_homography )
1451 printf(
"\nOriginal connection matrix (connections: %i):\n",cnt);
1455 int cmax = -1;
int hmax = -1;
int max = -1;
1456 for(
int h = 0; h < (int)v_camera[0]->v_homography.size(); h++ ){
1458 for(
int c = 0; c < (int)v_camera.size(); c++ )
1459 if(
cvmGet( m_CH, c, h ) == 1 )
1469 for(
int c = 0; c < (int)v_camera.size(); c++ ){
1470 if(
cvmGet( m_CH, c, hmax ) == 1 ){
1472 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
1473 if(
cvmGet( m_CH, c, h ) == 1 )
1483 if( cmax == -1 || hmax == -1 ){
1484 cvReleaseMat( &m_CH );
1487 printf(
"ERROR: Camera with maximal plane connections could not be estimated!\n");
1489 printf(
"ERROR: Plane with maximal camera connections could not be estimated!\n");
1496 for(
int c1 = 0; c1 < (int)v_camera.size(); c1++ ){
1497 for(
int h1 = 0; h1 < (int)v_camera[c1]->v_homography.size(); h1++ ){
1498 if(
cvmGet( m_CH, c1, h1 ) == 0 ){
1499 bool briged =
false;
1500 for(
int c2 = 0; c2 < (int)v_camera.size(); c2++ ){
1501 for(
int h2 = 0; h2 < (int)v_camera[c2]->v_homography.size(); h2++ ){
1502 if( (
cvmGet( m_CH, c1, h2 ) == 1 ||
cvmGet( m_CH, c1, h2 ) == 2) &&
1503 (
cvmGet( m_CH, c2, h1 ) == 1 ||
cvmGet( m_CH, c2, h1 ) == 2) &&
1504 (
cvmGet( m_CH, c2, h2 ) == 1 ||
cvmGet( m_CH, c2, h2 ) == 2) &&
1505 c1 != c2 && h1 != h2 ){
1509 cvmSet( m_CH, c1, h1, 1 );
1510 CreateEstimated3ChainMatrixRT( h1, c2, h2, c1 );
1519 }
while( big_briged );
1521 s_optimal.c_max = cmax;
1522 s_optimal.h_max = hmax;
1524 printf(
"\nNew connection matrix (cmax: %i, hmax: %i, connections: %i):\n",cmax,hmax,cnt);
1528 for(
int c = 0; c < (int)v_camera.size(); c++ ){
1529 if(
cvmGet( m_CH, c, hmax ) == 0 ){
1530 printf(
"ERROR: Not enough links to connect camera %i to main camera %i!\n",c,cmax);
1538 void CamCalibration::ReleaseOptimalCameraStructure(){
1539 for(
int i = 0; i < (int)s_optimal.v_camera_c.size(); i++ ) cvReleaseMat(&s_optimal.v_camera_c[i]);
1540 s_optimal.v_camera_c.clear();
1541 for(
int i = 0; i < (int)s_optimal.v_camera_r_t.size(); i++ ) cvReleaseMat(&s_optimal.v_camera_r_t[i]);
1542 s_optimal.v_camera_r_t.clear();
1543 for(
int i = 0; i < (int)s_optimal.v_camera_r_t_jacobian.size(); i++ ) cvReleaseMat(&s_optimal.v_camera_r_t_jacobian[i]);
1544 s_optimal.v_camera_r_t_jacobian.clear();
1545 for(
int i = 0; i < (int)s_optimal.v_homography_r_t.size(); i++ ) cvReleaseMat(&s_optimal.v_homography_r_t[i]);
1546 s_optimal.v_homography_r_t.clear();
1547 for(
int i = 0; i < (int)s_optimal.v_homography_r_t_jacobian.size(); i++ ) cvReleaseMat(&s_optimal.v_homography_r_t_jacobian[i]);
1548 s_optimal.v_homography_r_t_jacobian.clear();
1551 bool CamCalibration::CreateOptimalCameraStructure(){
1552 ReleaseOptimalCameraStructure();
1554 if( !CreateMatrixCH() ){
1555 printf(
"ERROR: Connection matrix could not be constructed!\n");
1560 for(
int c = 0; c < m_CH->height; c++ ){
1561 s_optimal.v_camera_r_t.push_back( NULL );
1562 CreateEstimatedOptimalCameraMatrixRT( c, s_optimal.h_max );
1563 s_optimal.v_camera_c.push_back( NULL );
1564 CreateEstimatedOptimalCameraMatrixC( c );
1565 s_optimal.v_camera_r_t_jacobian.push_back( cvCreateMat( 3, 9, CV_64FC1 ) );
1569 for(
int h = 0; h < m_CH->width; h++ ){
1570 s_optimal.v_homography_r_t.push_back( NULL );
1571 if(
cvmGet( m_CH, s_optimal.c_max, h ) == 1 ||
cvmGet( m_CH, s_optimal.c_max, h ) == 2 )
1572 CreateEstimatedOptimalHomographyMatrixRT( h, s_optimal.c_max, s_optimal.h_max );
1573 s_optimal.v_homography_r_t_jacobian.push_back( cvCreateMat( 3, 9, CV_64FC1 ) );
1590 virtual void eval_func(
const double *params,
double *f,
double *J,
void **user_data)
const;
1595 void CamCalibration::updateCB(
double *params ,
void **user_data){
1599 int parameter_number = cam->GetParameterNumber();
1600 for(
int i = 0; i < parameter_number; i++ )
1601 cam->v_opt_param[i] = params[i];
1604 cam->SetParameterSetToOptimalStructure();
1605 cam->PrintOptimizedResultErrors(params);
1620 double a_p[4];
double a_p3[3];
double a_p4[3];
1621 double a_RT[12]; CvMat m_RT = cvMat( 3, 4, CV_64FC1, a_RT );
1622 a_p[0] = cam->v_camera[c]->v_homography[h]->s_plane_object->px[
point]; a_p[2] = 0;
1623 a_p[1] = cam->v_camera[c]->v_homography[h]->s_plane_object->py[
point]; a_p[3] = 1;
1624 CvMat m_p = cvMat( 4, 1, CV_64FC1, a_p );
1625 CvMat m_p3 = cvMat( 3, 1, CV_64FC1, a_p3 );
1626 CvMat m_p4 = cvMat( 3, 1, CV_64FC1, a_p4 );
1627 cam->
Mat3x4Mul( cam->s_optimal.v_camera_r_t[c], cam->s_optimal.v_homography_r_t[h], &m_RT );
1628 cvMatMul( &m_RT, &m_p, &m_p3 );
1629 cvMatMul( cam->s_optimal.v_camera_c[c], &m_p3, &m_p4 );
1631 f[0] =
cvmGet( &m_p4, 0, 0 );
1632 f[1] =
cvmGet( &m_p4, 1, 0 );
1638 for(
int g_c = 0; g_c < (int)cam->s_optimal.v_camera_c.size(); g_c++ ){
1661 double a_R1[9]; CvMat m_R1 = cvMat( 3, 3, CV_64FC1, a_R1 );
1662 double a_T1[3]; CvMat m_T1 = cvMat( 3, 1, CV_64FC1, a_T1 );
1663 double a_R2[9]; CvMat m_R2 = cvMat( 3, 3, CV_64FC1, a_R2 );
1664 double a_T2[3]; CvMat m_T2 = cvMat( 3, 1, CV_64FC1, a_T2 );
1669 for(
int i = 0; i < 3; i++ )
1670 for(
int j = 0; j < 3; j++ )
1671 R1[i][j] =
cvmGet( &m_R1, i, j );
1674 for(
int i = 0; i < 3; i++ )
1675 for(
int j = 0; j < 3; j++ )
1676 R2[i][j] =
cvmGet( &m_R2, i, j );
1689 cam->s_optimal.v_camera_r_t_jacobian[c],
1694 cam->s_optimal.v_homography_r_t_jacobian[h],
1699 for(
int g_c = 0; g_c < (int)cam->s_optimal.v_camera_r_t.size(); g_c++ ){
1701 for(
int i = 0; i < 3; i++ )
1702 grad0[gc+i] = cgret[i+3];
1703 for(
int i = 0; i < 3; i++ )
1704 grad0[gc+3+i] = cgret[i];
1705 for(
int i = 0; i < 3; i++ )
1706 grad1[gc+i] = cgret[12+i+3];
1707 for(
int i = 0; i < 3; i++ )
1708 grad1[gc+3+i] = cgret[12+i];
1710 for(
int i = 0; i < 6; i++ ) {
1719 for(
int g_h = 0; g_h < (int)cam->s_optimal.v_homography_r_t.size(); g_h++ ){
1722 if( g_h != cam->s_optimal.h_max &&
cvmGet( cam->m_CH, cam->s_optimal.c_max, g_h ) == 1 ){
1724 for(
int i = 0; i < 3; i++ )
1725 grad0[gc+i] = cgret[6+i+3];
1726 for(
int i = 0; i < 3; i++ )
1727 grad0[gc+i+3] = cgret[6+i];
1728 for(
int i = 0; i < 3; i++ )
1729 grad1[gc+i] = cgret[12+6+i+3];
1730 for(
int i = 0; i < 3; i++ )
1731 grad1[gc+i+3] = cgret[12+6+i];
1733 for(
int i = 0; i < 6; i++ ) {
1744 int CamCalibration::GetParameterNumber(){
1747 for(
int c = 0; c < (int)s_optimal.v_camera_r_t.size(); c++ )
1750 for(
int h = 0; h < (int)s_optimal.v_homography_r_t.size(); h++ )
1752 if( h != s_optimal.h_max &&
cvmGet( m_CH, s_optimal.c_max, h ) == 1 )
1755 return 4*(int)s_optimal.v_camera_r_t.size()+i;
1758 int CamCalibration::GetObservationNumber(){
1760 for(
int c = 0; c < (int)v_camera.size(); c++ )
1761 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
1762 if( v_camera[c]->v_homography[h]->m_homography )
1763 i += v_camera[c]->v_homography[h]->s_plane_object->p*2;
1767 void CamCalibration::GetParameterSetFromOptimalStructure(){
1769 v_opt_param.clear();
1772 for(
int c = 0; c < (int)s_optimal.v_camera_c.size(); c++ ){
1773 v_opt_param.push_back(
cvmGet( s_optimal.v_camera_c[c], 0, 0 ) );
1774 v_opt_param.push_back(
cvmGet( s_optimal.v_camera_c[c], 1, 1 ) );
1775 v_opt_param.push_back(
cvmGet( s_optimal.v_camera_c[c], 0, 2 ) );
1776 v_opt_param.push_back(
cvmGet( s_optimal.v_camera_c[c], 1, 2 ) );
1779 double a_R[9]; CvMat m_R = cvMat( 3, 3, CV_64FC1, a_R );
1780 double a_r[3]; CvMat m_r = cvMat( 3, 1, CV_64FC1, a_r );
1781 double a_T[3]; CvMat m_T = cvMat( 3, 1, CV_64FC1, a_T );
1784 for(
int c = 0; c < (int)s_optimal.v_camera_r_t.size(); c++ ){
1786 v_opt_param.push_back( -
cvmGet( &m_T, 0, 0 ) );
1787 v_opt_param.push_back( -
cvmGet( &m_T, 1, 0 ) );
1788 v_opt_param.push_back( -
cvmGet( &m_T, 2, 0 ) );
1789 cvRodrigues2( &m_R, &m_r, 0 );
1790 v_opt_param.push_back(
cvmGet( &m_r, 0, 0 ) );
1791 v_opt_param.push_back(
cvmGet( &m_r, 1, 0 ) );
1792 v_opt_param.push_back(
cvmGet( &m_r, 2, 0 ) );
1796 for(
int h = 0; h < (int)s_optimal.v_homography_r_t.size(); h++ ){
1798 if( h != s_optimal.h_max &&
cvmGet( m_CH, s_optimal.c_max, h ) == 1 ){
1800 v_opt_param.push_back( -
cvmGet( &m_T, 0, 0 ) );
1801 v_opt_param.push_back( -
cvmGet( &m_T, 1, 0 ) );
1802 v_opt_param.push_back( -
cvmGet( &m_T, 2, 0 ) );
1803 cvRodrigues2( &m_R, &m_r, 0 );
1804 v_opt_param.push_back(
cvmGet( &m_r, 0, 0 ) );
1805 v_opt_param.push_back(
cvmGet( &m_r, 1, 0 ) );
1806 v_opt_param.push_back(
cvmGet( &m_r, 2, 0 ) );
1813 return cvPoint((
int)a, (
int)b);
1816 void CamCalibration::SetParameterSetToOptimalStructure(){
1820 for(
int c = 0; c < (int)s_optimal.v_camera_c.size(); c++ ){
1821 cvmSet( s_optimal.v_camera_c[c], 0, 0, v_opt_param[i++] );
1822 cvmSet( s_optimal.v_camera_c[c], 1, 1, v_opt_param[i++] );
1823 cvmSet( s_optimal.v_camera_c[c], 0, 2, v_opt_param[i++] );
1824 cvmSet( s_optimal.v_camera_c[c], 1, 2, v_opt_param[i++] );
1827 double a_R[9]; CvMat m_R = cvMat( 3, 3, CV_64FC1, a_R );
1828 double a_r[3]; CvMat m_r = cvMat( 3, 1, CV_64FC1, a_r );
1829 double a_T[3]; CvMat m_T = cvMat( 3, 1, CV_64FC1, a_T );
1832 for(
int c = 0; c < (int)s_optimal.v_camera_r_t.size(); c++ ){
1833 cvmSet( &m_T, 0, 0, -v_opt_param[i++] );
1834 cvmSet( &m_T, 1, 0, -v_opt_param[i++] );
1835 cvmSet( &m_T, 2, 0, -v_opt_param[i++] );
1836 cvmSet( &m_r, 0, 0, v_opt_param[i++] );
1837 cvmSet( &m_r, 1, 0, v_opt_param[i++] );
1838 cvmSet( &m_r, 2, 0, v_opt_param[i++] );
1839 cvRodrigues2( &m_r, &m_R, s_optimal.v_camera_r_t_jacobian[c] );
1844 for(
int h = 0; h < (int)s_optimal.v_homography_r_t.size(); h++ ){
1846 if( h != s_optimal.h_max && (
cvmGet( m_CH, s_optimal.c_max, h ) == 1 ||
cvmGet( m_CH, s_optimal.c_max, h ) == 1) ){
1847 cvmSet( &m_T, 0, 0, -v_opt_param[i++] );
1848 cvmSet( &m_T, 1, 0, -v_opt_param[i++] );
1849 cvmSet( &m_T, 2, 0, -v_opt_param[i++] );
1850 cvmSet( &m_r, 0, 0, v_opt_param[i++] );
1851 cvmSet( &m_r, 1, 0, v_opt_param[i++] );
1852 cvmSet( &m_r, 2, 0, v_opt_param[i++] );
1853 cvRodrigues2( &m_r, &m_R, s_optimal.v_homography_r_t_jacobian[h] );
1860 char file_name[200];
1861 IplImage * image[5];
1863 for(
int h = 0; h < (int)v_camera[0]->v_homography.size(); h++ ){
1864 for(
int c = 0; c < (int)v_camera.size(); c++ ){
1865 if(
cvmGet( m_CH, c, h ) == 1 ){
1866 sprintf(file_name,
"E:\\andreas_camcal_16_12_2005\\cam%02d%04d.bmp",c+1,h+2048);
1867 if( image[c] = cvLoadImage( file_name, 1 ) ){
1870 if( (boxfile = fopen(
"box.txt",
"r+t" )) != NULL ){
1871 for(
int j = 0; j < 6; j++ ){
1873 for(
int i = 0; (i < 4 && j < 2) || i < 2; i++ ){
1874 double a_p[4];
double a_p3[3];
double a_p4[3];
1875 double a_RT[12]; CvMat m_RT = cvMat( 3, 4, CV_64FC1, a_RT );
1877 fscanf( boxfile,
"%f %f %f\n", &x, &y, &z );
1878 a_p[0] = x; a_p[1] = y; a_p[2] = z; a_p[3] = 1;
1879 CvMat m_p = cvMat( 4, 1, CV_64FC1, a_p );
1880 CvMat m_p3 = cvMat( 3, 1, CV_64FC1, a_p3 );
1881 CvMat m_p4 = cvMat( 3, 1, CV_64FC1, a_p4 );
1882 Mat3x4Mul( s_optimal.v_camera_r_t[c], s_optimal.v_homography_r_t[h], &m_RT );
1883 cvMatMul( &m_RT, &m_p, &m_p3 );
1884 cvMatMul( s_optimal.v_camera_c[c], &m_p3, &m_p4 );
1886 p[i][0] =
cvmGet( &m_p4, 0, 0 );
1887 p[i][1] =
cvmGet( &m_p4, 1, 0 );
1889 CvScalar color = CV_RGB ( 0,0,0 );
1890 if( j == 0 ) color = CV_RGB ( 255,200,0 );
1891 if( j >= 1 ) color = CV_RGB ( 155,100,0 );
1892 cvLine( image[c],
cvPoint( p[0][0],p[0][1] ),
cvPoint( p[1][0],p[1][1] ), color,4,CV_AA,0 );
1894 cvLine( image[c],
cvPoint( p[1][0],p[1][1] ),
cvPoint( p[2][0],p[2][1] ), color,4,CV_AA,0 );
1895 cvLine( image[c],
cvPoint( p[2][0],p[2][1] ),
cvPoint( p[3][0],p[3][1] ), color,4,CV_AA,0 );
1896 cvLine( image[c],
cvPoint( p[3][0],p[3][1] ),
cvPoint( p[0][0],p[0][1] ), color,4,CV_AA,0 );
1904 if(
cvmGet( m_CH, 0, h ) == 1 &&
1905 cvmGet( m_CH, 1, h ) == 1 &&
1906 cvmGet( m_CH, 2, h ) == 1 &&
1907 cvmGet( m_CH, 3, h ) == 1 &&
1908 cvmGet( m_CH, 4, h ) == 1 ){
1910 IplImage *im = cvCreateImage(cvSize(980,480), IPL_DEPTH_8U, 3);
1911 cvSetImageROI(im, cvRect(0,0,320,240)); cvResize(image[0], im, CV_INTER_LINEAR );
1912 cvSetImageROI(im, cvRect(320,0,320,240)); cvResize(image[1], im, CV_INTER_LINEAR );
1913 cvSetImageROI(im, cvRect(640,0,320,240)); cvResize(image[2], im, CV_INTER_LINEAR );
1914 cvSetImageROI(im, cvRect(0,240,320,240)); cvResize(image[3], im, CV_INTER_LINEAR );
1915 cvSetImageROI(im, cvRect(320,240,320,240)); cvResize(image[4], im, CV_INTER_LINEAR );
1916 cvResetImageROI(im);
1917 cvLine( im,
cvPoint( 0,240 ),
cvPoint( 980,240 ), CV_RGB ( 255,255,255 ),2,CV_AA,0 );
1918 cvLine( im,
cvPoint( 320,0 ),
cvPoint( 320,480 ), CV_RGB ( 255,255,255 ),2,CV_AA,0 );
1919 cvLine( im,
cvPoint( 640,0 ),
cvPoint( 640,480 ), CV_RGB ( 255,255,255 ),2,CV_AA,0 );
1920 sprintf(file_name,
"__cam%04d_%04d.bmp",cnt,h);
1921 cvSaveImage( file_name, im );
1922 cvReleaseImage( &image[0] );
1923 cvReleaseImage( &image[1] );
1924 cvReleaseImage( &image[2] );
1925 cvReleaseImage( &image[3] );
1926 cvReleaseImage( &image[4] );
1927 cvReleaseImage( &im );
1928 printf(
"File __cam%04d.bmp written!\n",cnt);
2039 void CamCalibration::PrintOptimizedResultErrors(
double *params){
2042 double total_error_opt = 0;
2043 double total_error_org = 0;
2044 double chi_error_opt = 0;
2045 double chi_error_org = 0;
2046 float error_opt[50000];
2047 float error_org[50000];
2048 float error_gra[10][3000];
2052 for(
int c = 0; c < (int)cam->v_camera.size(); c++ )
2053 for(
int h = 0; h < (int)cam->v_camera[c]->v_homography.size(); h++ ){
2054 error_gra[c][h] = 0;
2055 if( cam->v_camera[c]->v_homography[h]->m_homography ){
2056 int points = cam->v_camera[c]->v_homography[h]->s_plane_object->p;
2057 for(
int point = 0; point < points; point++ ){
2061 double u1 =
cvmGet( cam->v_camera[c]->v_homography[h]->s_plane_object->v_m_pp[point], 0, 0 );
2062 double v1 =
cvmGet( cam->v_camera[c]->v_homography[h]->s_plane_object->v_m_pp[point], 1, 0 );
2065 double a_p[4];
double a_p3[3];
double a_p4[3];
2066 double a_RT[12]; CvMat m_RT = cvMat( 3, 4, CV_64FC1, a_RT );
2067 a_p[0] = cam->v_camera[c]->v_homography[h]->s_plane_object->px[point]; a_p[2] = 0;
2068 a_p[1] = cam->v_camera[c]->v_homography[h]->s_plane_object->py[point]; a_p[3] = 1;
2069 CvMat m_p = cvMat( 4, 1, CV_64FC1, a_p );
2070 CvMat m_p3 = cvMat( 3, 1, CV_64FC1, a_p3 );
2071 CvMat m_p4 = cvMat( 3, 1, CV_64FC1, a_p4 );
2072 cam->
Mat3x4Mul( cam->s_optimal.v_camera_r_t[c], cam->s_optimal.v_homography_r_t[h], &m_RT );
2073 cvMatMul( &m_RT, &m_p, &m_p3 );
2074 cvMatMul( cam->s_optimal.v_camera_c[c], &m_p3, &m_p4 );
2076 double u2 =
cvmGet( &m_p4, 0, 0 );
2077 double v2 =
cvmGet( &m_p4, 1, 0 );
2081 cam->v_camera[c]->v_homography[h]->m_homography->transform_point(
2082 cam->v_camera[c]->v_homography[h]->s_plane_object->px[point],
2083 cam->v_camera[c]->v_homography[h]->s_plane_object->py[point],
2087 double current_error_opt = sqrt( pow(u1-u2,2) + pow(v1-v2,2) );
2088 double current_error_org = sqrt( pow(u1-u3,2) + pow(v1-v3,2) );
2089 chi_error_opt += pow(u1-u2,2) + pow(v1-v2,2);
2090 chi_error_org += pow(u1-u3,2) + pow(v1-v3,2);
2091 error_opt[obs] = (float)current_error_opt;
2092 total_error_opt += current_error_opt;
2093 error_org[obs] = (float)current_error_org;
2094 total_error_org += current_error_org;
2098 error_gra[c][h] += (float)( current_error_opt/(
double)points );
2105 chi_error_opt /= (double)obs * 2.0;
2106 chi_error_org /= (double)obs * 2.0;
2107 double avg_error_opt = total_error_opt / (double)obs;
2108 double avg_error_org = total_error_org / (double)obs;
2109 double std_dev_opt = 0;
2110 double std_dev_org = 0;
2111 double max_error_opt = 0;
2112 double max_error_org = 0;
2113 double min_error_opt = total_error_opt;
2114 double min_error_org = total_error_org;
2115 for(
int j = 0; j < obs; j++ ){
2116 if( error_opt[j] > max_error_opt ) max_error_opt = error_opt[j];
2117 if( error_org[j] > max_error_org ) max_error_org = error_org[j];
2118 if( error_opt[j] < min_error_opt ) min_error_opt = error_opt[j];
2119 if( error_org[j] < min_error_org ) min_error_org = error_org[j];
2120 std_dev_opt += pow( error_opt[j]-avg_error_opt, 2 );
2121 std_dev_org += pow( error_org[j]-avg_error_org, 2 );
2123 std_dev_opt = sqrt(std_dev_opt/(
double)obs);
2124 std_dev_org = sqrt(std_dev_org/(
double)obs);
2127 printf(
"\n Focal Aspect u_0 v_0 Hnum\n");
2128 for(
int c = 0; c < (int)cam->v_camera.size(); c++ )
2129 if( params[c*4+1] != 0 ){
2131 for(
int h = 0; h < (int)cam->v_camera[c]->v_homography.size(); h++ )
2132 if( cam->v_camera[c]->v_homography[h]->m_homography )
2134 printf(
"Camera %02d: %8.3f %8.3f %8.3f %8.3f %5d\n",
2136 params[c*4+1], params[c*4]/params[c*4+1] , params[c*4+2], params[c*4+3],
2141 printf(
"\n Optimal Original\n");
2142 printf(
"Maximal error in observations: %8.3f %8.3f\n", max_error_opt, max_error_org );
2143 printf(
"Minimal error in observations: %8.3f %8.3f\n", min_error_opt, min_error_org );
2144 printf(
"Average error in observations: %8.3f %8.3f\n", avg_error_opt, avg_error_org );
2145 printf(
"Chi^2 error in observations: %8.3f %8.3f\n", chi_error_opt, chi_error_org );
2146 printf(
"Standard deviation of error: %8.3f %8.3f\n", std_dev_opt, std_dev_org );
2147 printf(
"Number of observations: %8i %8i\n", obs, obs);
2152 IplImage *im = cvCreateImage( cvSize( width, height ), IPL_DEPTH_8U, 3 );
2154 cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, 1, 1, 0, 2, 8 );
2157 double max_error = 0;
2158 for(
int c = 0; c < (int)cam->v_camera.size(); c++ )
2159 for(
int h = (
int)cam->v_camera[c]->v_homography.size()-1; h >= 0 ; h-- )
2160 if( cam->v_camera[c]->v_homography[h]->m_homography )
2161 if( error_gra[c][h] > max_error )
2162 max_error = error_gra[c][h];
2166 double cut_error = 1;
2167 int y_cut = (int)((
double)height-(double)height*cut_error/max_error);
2168 cvRectangle( im,
cvPoint( 0, 0 ),
cvPoint( width, y_cut ), CV_RGB ( 100,100,100 ), CV_FILLED, 8, 0 );
2169 cvRectangle( im,
cvPoint( 0, y_cut ),
cvPoint( width, height ), CV_RGB ( 0, 0, 0 ), CV_FILLED, 8, 0 );
2173 for(
int c = 0; c < (int)cam->v_camera.size(); c++ )
2174 for(
int h = (
int)cam->v_camera[c]->v_homography.size()-1; h >= 0 ; h-- )
2175 if( cam->v_camera[c]->v_homography[h]->m_homography ){
2176 int x = (int)((
double)width*(double)h/(
double)cam->v_camera[c]->v_homography.size());
2177 int y = (
int)((
double)height-(
double)height*error_gra[c][h]/max_error);
2178 cvLine( im,
cvPoint( x,y ),
cvPoint( x,height ), CV_RGB ( 255,255,255 ), 2, CV_AA, 0 );
2179 cvCircle( im,
cvPoint( x,y ), 2, CV_RGB ( 255,200,0 ), 2, CV_AA, 0 );
2180 if( error_gra[c][h]/max_error > 0.3 ){
2181 sprintf( info,
"%i", h );
2182 cvPutText( im, info,
cvPoint( x+1,y-1 ), &font, CV_RGB ( 255,200,0 ) );
2187 sprintf( info,
"%.3f", max_error );
2188 cvPutText( im, info,
cvPoint( 10,30 ), &font, CV_RGB ( 255,0,0 ) );
2189 sprintf( info,
"%.3f", 0 );
2190 cvPutText( im, info,
cvPoint( 10,height-10 ), &font, CV_RGB ( 255,0,0 ) );
2191 if( cut_error > 0.1*max_error && cut_error < 0.9*max_error ){
2192 sprintf( info,
"%.3f", cut_error );
2193 cvPutText( im, info,
cvPoint( 10,y_cut-5 ), &font, CV_RGB ( 255,0,0 ) );
2195 sprintf( info,
"Maximal Camera Error in Pixel over homographies", 0 );
2196 cvPutText( im, info,
cvPoint( 150,30 ), &font, CV_RGB ( 200,255,100 ) );
2204 IplImage *im2 = cvCreateImage(cvSize(800,600), IPL_DEPTH_8U, 3);
2205 cvResize(im, im2, CV_INTER_LINEAR );
2206 cvShowImage(
"Error Histogram", im2 );
2208 cvReleaseImage( &im );
2209 cvReleaseImage( &im2 );
2211 printf(
"==================================================\n" );
2213 printf(
"\n\n---------- Calibration results: ----------\n");
2214 printf(
"ERROR: No observations found!\n\n");
2218 bool CamCalibration::FilterHomographiesAfterOptimization(
double p_PostFilter ){
2219 bool filtered =
false;
2220 printf(
"INFO: Starting post-filtering process...\n" );
2223 for(
int c = 0; c < (int)v_camera.size(); c++ )
2224 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ ){
2225 if( v_camera[c]->v_homography[h]->m_homography ){
2226 int points = v_camera[c]->v_homography[h]->s_plane_object->p;
2228 for(
int point = 0; point < points; point++ ){
2232 double u1 =
cvmGet( v_camera[c]->v_homography[h]->s_plane_object->v_m_pp[point], 0, 0 );
2233 double v1 =
cvmGet( v_camera[c]->v_homography[h]->s_plane_object->v_m_pp[point], 1, 0 );
2236 double a_p[4];
double a_p3[3];
double a_p4[3];
2237 double a_RT[12]; CvMat m_RT = cvMat( 3, 4, CV_64FC1, a_RT );
2238 a_p[0] = v_camera[c]->v_homography[h]->s_plane_object->px[point]; a_p[2] = 0;
2239 a_p[1] = v_camera[c]->v_homography[h]->s_plane_object->py[point]; a_p[3] = 1;
2240 CvMat m_p = cvMat( 4, 1, CV_64FC1, a_p );
2241 CvMat m_p3 = cvMat( 3, 1, CV_64FC1, a_p3 );
2242 CvMat m_p4 = cvMat( 3, 1, CV_64FC1, a_p4 );
2243 Mat3x4Mul( s_optimal.v_camera_r_t[c], s_optimal.v_homography_r_t[h], &m_RT );
2244 cvMatMul( &m_RT, &m_p, &m_p3 );
2245 cvMatMul( s_optimal.v_camera_c[c], &m_p3, &m_p4 );
2247 double u2 =
cvmGet( &m_p4, 0, 0 );
2248 double v2 =
cvmGet( &m_p4, 1, 0 );
2251 double current_error_opt = sqrt( pow(u1-u2,2) + pow(v1-v2,2) );
2252 error += current_error_opt/(double)points;
2254 if( error > p_PostFilter ){
2255 for(
int c2 = 0; c2 < (int)v_camera.size(); c2++ ){
2256 DeleteWorldPlaneHomography( c2, h );
2257 cvmSet( m_CH, c2, h, 0 );
2258 cvReleaseMat( &s_optimal.v_homography_r_t[h] );
2259 cvReleaseMat( &s_optimal.v_homography_r_t_jacobian[h] );
2261 printf(
"INFO: View %i has been deleted for all cameras!\n", h );
2268 printf(
"INFO: Nothing filtered!\n" );
2271 printf(
"INFO: Post-filtering process finished.\n\n" );
2275 bool CamCalibration::OptimizeCalibrationByMinimalParameterMethod(
int iter,
double eps,
double p_PostFilter ){
2278 if( !CreateOptimalCameraStructure() ){
2279 printf(
"ERROR: Optial camera structure estimation failed!\n");
2284 errorgraphic_counter = 0;
2285 cvNamedWindow(
"Error Histogram", CV_WINDOW_AUTOSIZE );
2293 int parameter_number = GetParameterNumber();
2297 minimizer.set_state_change_callback(updateCB);
2298 minimizer.set_user_data(0,
this);
2299 minimizer.lm_set_max_iterations(iter);
2301 ProjObs::parameterNumber = parameter_number;
2304 GetParameterSetFromOptimalStructure();
2319 for(
int c = 0; c < (int)v_camera.size(); c++ )
2320 for(
int h = 0; h < (int)v_camera[c]->v_homography.size(); h++ )
2321 if( v_camera[c]->v_homography[h]->m_homography ){
2322 int points = v_camera[c]->v_homography[h]->s_plane_object->p;
2323 for(
int point = 0; point < points; point++ ) {
2332 s_struct_plane* s_plane_object = v_camera[c]->v_homography[h]->s_plane_object;
2334 o->
target[0] =
cvmGet( (*s_plane_object).v_m_pp[point], 0, 0 );
2335 o->
target[1] =
cvmGet( (*s_plane_object).v_m_pp[point], 1, 0 );
2337 minimizer.add_observation(o,
true,
false);
2341 minimizer.minimize_using_levenberg_marquardt_from(&v_opt_param[0]);
2343 updateCB( minimizer.state, &ptr);
2350 }
while( FilterHomographiesAfterOptimization( p_PostFilter ) );
2353 cvDestroyAllWindows();
2362 if( (stream = fopen(
"camera_c.txt",
"w+t" )) != NULL ){
2363 for(
int c = 0; c < (int)s_optimal.v_camera_c.size(); c++ ){
2364 fprintf( stream,
"no: %i\n", c );
2365 fprintf( stream,
"width: %i\n", v_camera[c]->w );
2366 fprintf( stream,
"height: %i\n", v_camera[c]->h );
2373 if( (stream = fopen(
"camera_r_t.txt",
"w+t" )) != NULL ){
2374 for(
int c = 0; c < (int)s_optimal.v_camera_c.size(); c++ ){
2375 fprintf( stream,
"no: %i\n", c );
2376 fprintf( stream,
"width: %i\n", v_camera[c]->w );
2377 fprintf( stream,
"height: %i\n", v_camera[c]->h );
2384 if( (stream = fopen(
"view_r_t.txt",
"w+t" )) != NULL ){
2385 for(
int h = 0; h < (int)s_optimal.v_homography_r_t.size(); h++ ){
2386 if( s_optimal.v_homography_r_t[h] ){
2387 fprintf( stream,
"no: %i\n", h );
2396 char* png_descriptor,
int c_start,
int h_start )
2399 char file_name[200];
2401 char image_out[200];
2404 for(
int c = 0; c < (int)s_optimal.v_camera_c.size(); c++ ){
2405 for(
int h = 0; h < (int)s_optimal.v_homography_r_t.size(); h++ ){
2406 if(
cvmGet( m_CH, c, h ) == 1 ){
2407 sprintf( file_name, file_descriptor, c, h );
2408 if( (stream = fopen( file_name,
"w+t" )) != NULL ){
2410 CvMat m_proj = cvMat( 3, 4, CV_64FC1, a_proj );
2411 cvMatMul( s_optimal.v_camera_c[c], s_optimal.v_camera_r_t[c], &m_proj );
2412 Mat3x4Mul( &m_proj, s_optimal.v_homography_r_t[h], &m_proj );