mono_ex_cal.cpp
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <vector>
00003 #include "ceres/ceres.h"
00004 #include "ceres/rotation.h"
00005 #include <iostream>
00006 typedef struct
00007 {
00008   int p_id; // point's id
00009   double x; // image x
00010   double y; // image y
00011 } observation;
00012 
00013 typedef struct
00014 {
00015   union
00016   {
00017     struct
00018     {
00019       double x;
00020       double y;
00021       double z;
00022     };
00023     double PB[3]; // parameter block
00024   };
00025 } point;
00026 
00027 typedef struct
00028 {
00029   union
00030   {
00031     struct
00032     {
00033       double PB_extrinsics[6]; // parameter block for intrinsics
00034       double PB_intrinsics[9]; // parameter block for extrinsics
00035     };
00036     struct
00037     {
00038       double aa[3]; // angle axis data
00039       double pos[3]; // position data
00040       double fx;
00041       double fy;
00042       double cx;
00043       double cy;
00044       double k1;
00045       double k2;
00046       double k3;
00047       double p1;
00048       double p2;
00049     };
00050   };
00051 } Camera;
00052 
00053 // local prototypes
00054 void print_QTasH(double qx, double qy, double qz, double qw, double tx, double ty, double tz);
00055 void print_AATasH(double x, double y, double z, double tx, double ty, double tz);
00056 void print_AATasHI(double x, double y, double z, double tx, double ty, double tz);
00057 void print_AAasEuler(double x, double y, double z);
00058 void print_camera(Camera C, std::string words);
00059 observation project_point(Camera C, point P);
00060 
00061 // computes image of point in cameras image plane
00062 observation project_point(Camera C, point P)
00063 {
00064   double p[3];
00065   double pt[3];
00066   pt[0] = P.x;
00067   pt[1] = P.y;
00068   pt[2] = P.z;
00069 
00070   // transform point into camera frame
00071   // note, camera transform takes points from camera frame into world frame
00072 
00073   ceres::AngleAxisRotatePoint(C.aa, pt, p);
00074   printf("point %6.3lf %6.3lf %6.3lf rotated: %6.3lf %6.3lf %6.3lf ", P.x, P.y, P.z, p[0], p[1], p[2]);
00075   p[0] += C.pos[0];
00076   p[1] += C.pos[1];
00077   p[2] += C.pos[2];
00078   printf("translated: %6.3lf %6.3lf %6.3lf\n", p[0], p[1], p[2]);
00079   //  printf("PPP %6.3lf  %6.3lf %6.3lf \n",p[0],p[1],p[2]);
00080   double xp = p[0] / p[2];
00081   double yp = p[1] / p[2];
00082 
00083   //  printf("xp yp %6.3lf  %6.3lf\n",xp,yp);
00084   // calculate terms for polynomial distortion
00085   double r2 = xp * xp + yp * yp;
00086   double r4 = r2 * r2;
00087   double r6 = r2 * r4;
00088 
00089   double xp2 = xp * xp; // temporary variables square of others
00090   double yp2 = yp * yp;
00091 
00092   //apply the distortion coefficients to refine pixel location
00093   double xpp = xp + C.k1 * r2 * xp + C.k2 * r4 * xp + C.k3 * r6 * xp + C.p2 * (r2 + 2 * xp2) + 2 * C.p1 * xp * yp;
00094   double ypp = yp + C.k1 * r2 * yp + C.k2 * r4 * yp + C.k3 * r6 * yp + C.p1 * (r2 + 2 * yp2) + 2 * C.p2 * xp * yp;
00095 
00096   // perform projection using focal length and camera center into image plane
00097   observation O;
00098   O.p_id = 0;
00099   O.x = C.fx * xpp + C.cx;
00100   O.y = C.fy * ypp + C.cy;
00101   return (O);
00102 }
00103 
00104 struct Camera_reprj_error
00105 {
00106   Camera_reprj_error(double ob_x, double ob_y) :
00107       Ox(ob_x), Oy(ob_y)
00108   {
00109   }
00110 
00111   template<typename T>
00112     bool operator()(const T* const c_p1, // extrinsic parameters
00113         const T* c_p2, // intrinsic parameters
00114         const T* point, // point being projected, yes this is has 3 parameters
00115         T* resid) const
00116     {
00117       // extract the variables from the camera parameters
00118       int q = 0; // extrinsic block of parameters
00119       const T& x = c_p1[q++]; //  angle_axis x for rotation of camera           
00120       const T& y = c_p1[q++]; //  angle_axis y for rotation of camera
00121       const T& z = c_p1[q++]; //  angle_axis z for rotation of camera
00122       const T& tx = c_p1[q++]; //  translation of camera x
00123       const T& ty = c_p1[q++]; //  translation of camera y
00124       const T& tz = c_p1[q++]; //  translation of camera z
00125 
00126       q = 0; // intrinsic block of parameters
00127       const T& fx = c_p2[q++]; //  focal length x
00128       const T& fy = c_p2[q++]; //  focal length x
00129       const T& cx = c_p2[q++]; //  center point x
00130       const T& cy = c_p2[q++]; //  center point y
00131       const T& k1 = c_p2[q++]; //  distortion coefficient on 2nd order terms
00132       const T& k2 = c_p2[q++]; //  distortion coefficient on 4th order terms
00133       const T& k3 = c_p2[q++]; //  distortion coefficient on 6th order terms
00134       const T& p1 = c_p2[q++]; //  tangential distortion coefficient x
00135       const T& p2 = c_p2[q++]; //  tangential distortion coefficient y
00136 
00137       // rotate and translate points into camera frame
00138       T aa[3]; // angle axis 
00139       T p[3]; // point rotated
00140       aa[0] = x;
00141       aa[1] = y;
00142       aa[2] = z;
00143       ceres::AngleAxisRotatePoint(aa, point, p);
00144 
00145       // apply camera translation
00146       T xp1 = p[0] + tx; // point rotated and translated
00147       T yp1 = p[1] + ty;
00148       T zp1 = p[2] + tz;
00149 
00150       // scale into the image plane by distance away from camera
00151       T xp = xp1 / zp1;
00152       T yp = yp1 / zp1;
00153 
00154       // calculate terms for polynomial distortion
00155       T r2 = xp * xp + yp * yp;
00156       T r4 = r2 * r2;
00157       T r6 = r2 * r4;
00158 
00159       T xp2 = xp * xp; // temporary variables square of others
00160       T yp2 = yp * yp;
00161       //apply the distortion coefficients to refine pixel location
00162       T xpp = xp + k1 * r2 * xp + k2 * r4 * xp + k3 * r6 * xp + p2 * (r2 + T(2.0) * xp2) + T(2.0) * p1 * xp * yp;
00163       T ypp = yp + k1 * r2 * yp + k2 * r4 * yp + k3 * r6 * yp + p1 * (r2 + T(2.0) * yp2) + T(2.0) * p2 * xp * yp;
00164       // perform projection using focal length and camera center into image plane
00165       resid[0] = fx * xpp + cx - Ox;
00166       resid[1] = fy * ypp + cy - Oy;
00167 
00168       return true;
00169     } // end of operator()
00170 
00171     // Factory to hide the construction of the CostFunction object from
00172     // the client code.
00173   static ceres::CostFunction* Create(const double o_x, const double o_y)
00174   {
00175     return (new ceres::AutoDiffCostFunction<Camera_reprj_error, 2, 6, 9, 3>(new Camera_reprj_error(o_x, o_y)));
00176   }
00177   double Ox; // observed x location of object in image
00178   double Oy; // observed y location of object in image
00179 };
00180 
00181 int main(int argc, char** argv)
00182 {
00183 
00184   google::InitGoogleLogging(argv[0]);
00185   if (argc != 5)
00186   {
00187     std::cerr << "usage: monoExCal <3Dpoints_file> <observation_file> <intrinsic_file> <extrinsic_file>\n";
00188     return 1;
00189   }
00190   int num_points;
00191   int num_observations;
00192   observation o;
00193 
00194   // this code peforms extrinsic calibration on a monocular camera
00195   // it assumes that 3D data from a positioning device is available
00196   // this 3D data could come from an IGPS, a Fero arm, or any robot
00197   // each 3D point should be observed by the camera, and the image(x,y) position
00198   // of that observation must be known.
00199   // It is assumed that the intrinsic calibration is already known
00200   // The input is provided by 4 files
00201   // 1. 3D points stored as ascii in the form:
00202   //   num_points      # read as integer
00203   //   x[0] y[0] z[0]  # read as double
00204   //   ...
00205   //   x[num_points-1] y[num_points-1] z[num_points-1]
00206   // 2. Observations stored as ascii in the form
00207   //   num_observations  # read as integer
00208   //   x[0] y[0]         # read as double
00209   //   ...
00210   //   x[num_observations-1] y[num_observations-1] 
00211   // 3. Camera intrisic data stored as ascii in the ROS.ini format
00212   // 4. Camera initial extrinsic file stored as ascii indicating the homogeneous transform
00213   //  nx ox ax tx  #read all as double
00214   //  ny oy ay ty
00215   //  nz oz az tz
00216   //  0  0  0  1.0
00217 
00218   // read in the problem
00219   FILE *points_fp = fopen(argv[1], "r");
00220   FILE *observations_fp = fopen(argv[2], "r");
00221   FILE *intrinsics_fp = fopen(argv[3], "r");
00222   FILE *extrinsics_fp = fopen(argv[4], "r");
00223   if (points_fp == NULL)
00224   {
00225     printf("Could not open file: %s", argv[1]);
00226     exit(1);
00227   }
00228   if (observations_fp == NULL)
00229   {
00230     printf("Could not open file: %s", argv[2]);
00231     exit(1);
00232   }
00233   if (intrinsics_fp == NULL)
00234   {
00235     printf("Could not open file: %s", argv[3]);
00236     exit(1);
00237   }
00238   if (extrinsics_fp == NULL)
00239   {
00240     printf("Could not open file: %s", argv[4]);
00241     exit(1);
00242   }
00243 
00244   // first read points file
00245   if (fscanf(points_fp, "%d", &num_points) != 1)
00246   {
00247     printf("couldn't read num_points\n");
00248     exit(1);
00249   }
00250   std::vector<point> Pts;
00251   for (int i = 0; i < num_points; i++)
00252   {
00253     point p;
00254     if (fscanf(points_fp, "%lf %lf %lf", &p.x, &p.y, &p.z) != 3)
00255     {
00256       printf("couldn't read point %d from %s\n", i, argv[1]);
00257       exit(1);
00258     }
00259     Pts.push_back(p);
00260   }
00261   fclose(points_fp);
00262 
00263   // Then read in the observations
00264   if (fscanf(observations_fp, "%d", &num_observations) != 1)
00265   {
00266     printf("couldn't read num_observations\n");
00267     exit(1);
00268   }
00269   if (num_observations != num_points)
00270   {
00271     printf("WARNING, num_points NOT EQUAL to num_observations\n");
00272   }
00273   std::vector<observation> Ob;
00274   for (int i = 0; i < num_observations; i++)
00275   {
00276     if (fscanf(observations_fp, "%lf %lf", &o.x, &o.y) != 2)
00277     {
00278       printf("couldn't read observation %d from %s\n", i, argv[2]);
00279       exit(1);
00280     }
00281     o.p_id = i;
00282     Ob.push_back(o);
00283   }
00284   fclose(observations_fp);
00285 
00286   // read camera intrinsics
00287   Camera C;
00288   char dum[255];
00289   double Dum, Dum2, Dum3;
00290   int image_width;
00291   int image_height;
00292   int rtn = 0;
00293   rtn += fscanf(intrinsics_fp, "%s", dum); // should be "#"
00294   rtn += fscanf(intrinsics_fp, "%s", dum); // should be "Camera"
00295   rtn += fscanf(intrinsics_fp, "%s", dum); // should be "intrinsics"
00296   rtn += fscanf(intrinsics_fp, "%s", dum); // should be "[image]"
00297   //  printf("should be [image]: %s\n",dum);
00298   rtn += fscanf(intrinsics_fp, "%s", dum); // should be "width"
00299   //  printf("should be width: %s\n",dum);
00300   rtn += fscanf(intrinsics_fp, "%d", &image_width); // should be the image width of provided by camera
00301   printf("image_width: %d\n", image_width);
00302   rtn += fscanf(intrinsics_fp, "%s", dum); // should be "height"
00303   rtn += fscanf(intrinsics_fp, "%d", &image_height); // should be the image width of provided by camera
00304   printf("height: %d\n", image_height);
00305   rtn += fscanf(intrinsics_fp, "%s", dum); // should be "[some name]"
00306   //  printf("[some name]: %s\n",dum);
00307   rtn += fscanf(intrinsics_fp, "%s", dum); // should be "camera"
00308   //  printf("should be camera: %s\n",dum);
00309   rtn += fscanf(intrinsics_fp, "%s", dum); // should be "matrix"
00310   //  printf("should be matrix: %s\n",dum);
00311   rtn += fscanf(intrinsics_fp, "%lf %lf %lf", &C.fx, &Dum, &C.cx);
00312   rtn += fscanf(intrinsics_fp, "%lf %lf %lf", &Dum, &C.fy, &C.cy);
00313   rtn += fscanf(intrinsics_fp, "%lf %lf %lf", &Dum, &Dum2, &Dum3);
00314   rtn += fscanf(intrinsics_fp, "%s", dum); // should be "distortion" 
00315   printf("camera matrix:\n");
00316   printf("%8.3lf %8.3lf %8.3lf\n", C.fx, 0.0, C.cx);
00317   printf("%8.3lf %8.3lf %8.3lf\n", 0.0, C.fy, C.cy);
00318   printf("%8.3lf %8.3lf %8.3lf\n", 0.0, 0.0, 0.0);
00319   //  printf("should be distortion: %s\n",dum);
00320   rtn += fscanf(intrinsics_fp, "%lf %lf %lf %lf %lf", &C.k1, &C.k2, &C.k3, &C.p1, &C.p2);
00321   printf("Distortion: [ %8.3lf %8.3lf %8.3lf %8.3lf %8.3lf ]\n", C.k1, C.k2, C.k3, C.p1, C.p2);
00322   fclose(intrinsics_fp);
00323 
00324   // read camera extrinsics
00325   double H[4][4];
00326   rtn = 0;
00327   rtn += fscanf(extrinsics_fp, "%lf %lf %lf %lf", &H[0][0], &H[0][1], &H[0][2], &H[0][3]);
00328   rtn += fscanf(extrinsics_fp, "%lf %lf %lf %lf", &H[1][0], &H[1][1], &H[1][2], &H[1][3]);
00329   rtn += fscanf(extrinsics_fp, "%lf %lf %lf %lf", &H[2][0], &H[2][1], &H[2][2], &H[2][3]);
00330   rtn += fscanf(extrinsics_fp, "%lf %lf %lf %lf", &H[3][0], &H[3][1], &H[3][2], &H[3][3]);
00331   if (rtn != 16)
00332   {
00333     printf("could not read extrinsics rtn=%d from %s\n", rtn, argv[4]);
00334     exit(1);
00335   }
00336   fclose(extrinsics_fp);
00337 
00338   // use the inverse of transform from camera to world as camera transform
00339   double HI[9]; // note ceres uses column major order
00340   HI[0] = H[0][0]; // first column becomes first row
00341   HI[1] = H[0][1];
00342   HI[2] = H[0][2];
00343 
00344   HI[3] = H[1][0]; // second column becomes second row
00345   HI[4] = H[1][1];
00346   HI[5] = H[1][2];
00347 
00348   HI[6] = H[2][0]; // third column becomes third row
00349   HI[7] = H[2][1];
00350   HI[8] = H[2][2];
00351   C.pos[0] = -(H[0][3] * H[0][0] + H[1][3] * H[1][0] + H[2][3] * H[2][0]);
00352   C.pos[1] = -(H[0][3] * H[0][1] + H[1][3] * H[1][1] + H[2][3] * H[2][1]);
00353   C.pos[2] = -(H[0][3] * H[0][2] + H[1][3] * H[1][2] + H[2][3] * H[2][2]);
00354   printf("C.xyz = %lf %lf %lf\n", C.pos[0], C.pos[1], C.pos[2]);
00355   ceres::RotationMatrixToAngleAxis(HI, C.aa);
00356 
00357   /* used to create sample data with known solution
00358    FILE *fp6 = fopen("new_observations.txt","w");
00359    fprintf(fp6,"%d\n",num_points);
00360    for(int i=0;i<num_points;i++){
00361    o = project_point(C,Pts[i]);
00362    fprintf(fp6,"%lf %lf\n",o.x,o.y);
00363    }
00364    fclose(fp6); 
00365    exit(1);
00366    */
00367 #define MONO_EXCAL_DEBUG
00368 #ifdef MONO_EXCAL_DEBUG
00369   /* Print initial errors */
00370   /* Save projections and observations to matlab compatible form    */
00371   FILE *fp_temp1 = fopen("Obs.m", "w");
00372   FILE *fp_temp2 = fopen("Rep.m", "w");
00373   FILE *fp_temp3 = fopen("FRep.m", "w");
00374   fprintf(fp_temp1, "O = [ ");
00375   fprintf(fp_temp2, "R = [ ");
00376   fprintf(fp_temp3, "F = [ ");
00377   for (int i = 0; i < num_points; i++)
00378   {
00379     o = project_point(C, Pts[i]);
00380     printf("Errors %d  = %lf %lf\n", i, Ob[i].x - o.x, Ob[i].y - o.y);
00381     fprintf(fp_temp1, "%lf %lf;\n", Ob[i].x, Ob[i].y);
00382     fprintf(fp_temp2, "%lf %lf;\n", o.x, o.y);
00383   }
00384   fprintf(fp_temp1, "];\n");
00385   fprintf(fp_temp2, "];\n");
00386   fclose(fp_temp1);
00387   fclose(fp_temp2);
00388 #endif  // MONO_EXCAL_DEBUG
00389   print_camera(C, "Original Parameters");
00390   // Create residuals for each observation in the bundle adjustment problem. The
00391   // parameters for cameras and points are added automatically.
00392   ceres::Problem problem;
00393   for (int i = 0; i < num_observations; ++i)
00394   {
00395     // Each Residual block takes a point and a camera as input and outputs a 2
00396     // dimensional residual. Internally, the cost function stores the observed
00397     // image location and compares the reprojection against the observation.
00398     ceres::CostFunction* cost_function = Camera_reprj_error::Create(Ob[i].x, Ob[i].y);
00399 
00400     problem.AddResidualBlock(cost_function, NULL, C.PB_extrinsics, C.PB_intrinsics, Pts[i].PB);
00401     problem.SetParameterBlockConstant(C.PB_intrinsics);
00402     problem.SetParameterBlockConstant(Pts[i].PB);
00403     /* DEBUG the reprojection error, this shows how to call reprojection error directly
00404      Camera_reprj_error CE(Ob[i].x,Ob[i].y);
00405      double res[2];
00406      CE(C.PB_extrinsics,C.PB_intrinsics,Pts[i].PB,res);
00407      printf("residual %d = %9.3lf %9.3lf\n",i,res[0],res[1]);
00408      */
00409   }
00410 
00411   // Make Ceres automatically detect the bundle structure. Note that the
00412   // standard solver, SPARSE_NORMAL_CHOLESKY, also works fine but it is slower
00413   // for standard bundle adjustment problems.
00414   ceres::Solver::Options options;
00415   options.linear_solver_type = ceres::DENSE_SCHUR;
00416   options.minimizer_progress_to_stdout = true;
00417   options.max_num_iterations = 1000;
00418 
00419   ceres::Solver::Summary summary;
00420   ceres::Solve(options, &problem, &summary);
00421   std::cout << summary.FullReport() << "\n";
00422 
00423 #ifdef MONO_EXCAL_DEBUG
00424   /* Print final errors */
00425   for (int i = 0; i < num_points; i++)
00426   {
00427     o = project_point(C, Pts[i]);
00428     printf("%d : Ob= %6.3lf %6.3lf ", i, Ob[i].x, Ob[i].y);
00429     printf("%d : o= %6.3lf %6.3lf Errors = %10.3lf %10.3lf\n", i, o.x, o.y, Ob[i].x - o.x, Ob[i].y - o.y);
00430     fprintf(fp_temp3, "%lf %lf;\n", o.x, o.y);
00431   }
00432   fprintf(fp_temp3, "];\n");
00433   fclose(fp_temp3);
00434 #endif  // MONO_EXCAL_DEBUG
00435   // Print final camera parameters 
00436   print_camera(C, "final parameters");
00437 
00438   // write new extrinsics to a file
00439   std::string temp(argv[4]);
00440   std::string new_ex_file = "new_" + temp;
00441   extrinsics_fp = fopen(new_ex_file.c_str(), "w");
00442   ceres::AngleAxisToRotationMatrix(C.aa, HI); // Column Major 
00443 
00444   // invert HI to get H
00445   H[0][0] = HI[0]; // first column of HI is set to first row of H
00446   H[0][1] = HI[1];
00447   H[0][2] = HI[2];
00448 
00449   H[1][0] = HI[3]; // second column of HI is set to second row of H
00450   H[1][1] = HI[4];
00451   H[1][2] = HI[5];
00452 
00453   H[2][0] = HI[6]; // third column of HI is set to third row of H
00454   H[2][1] = HI[7];
00455   H[2][2] = HI[8];
00456 
00457   H[0][3] = -(C.pos[0] * HI[0] + C.pos[1] * HI[1] + C.pos[2] * HI[2]);
00458   H[1][3] = -(C.pos[0] * HI[3] + C.pos[1] * HI[4] + C.pos[2] * HI[5]);
00459   H[2][3] = -(C.pos[0] * HI[6] + C.pos[1] * HI[7] + C.pos[2] * HI[8]);
00460 
00461   fprintf(extrinsics_fp, "%9.3lf %9.3lf %9.3lf %9.3lf\n", H[0][0], H[0][1], H[0][2], H[0][3]);
00462   fprintf(extrinsics_fp, "%9.3lf %9.3lf %9.3lf %9.3lf\n", H[1][0], H[1][1], H[1][2], H[1][3]);
00463   fprintf(extrinsics_fp, "%9.3lf %9.3lf %9.3lf %9.3lf\n", H[2][0], H[2][1], H[2][2], H[2][3]);
00464   fprintf(extrinsics_fp, "%9.3lf %9.3lf %9.3lf %9.3lf\n", 0.0, 0.0, 0.0, 1.0);
00465   fclose(extrinsics_fp);
00466 
00467   return 0;
00468 }
00469 
00470 // print a quaternion plus position as a homogeneous transform
00471 void print_QTasH(double qx, double qy, double qz, double qw, double tx, double ty, double tz)
00472 {
00473   double Rs11 = qw * qw + qx * qx - qy * qy - qz * qz;
00474   double Rs21 = 2.0 * qx * qy + 2.0 * qw * qz;
00475   double Rs31 = 2.0 * qx * qz - 2.0 * qw * qy;
00476 
00477   double Rs12 = 2.0 * qx * qy - 2.0 * qw * qz;
00478   double Rs22 = qw * qw - qx * qx + qy * qy - qz * qz;
00479   double Rs32 = 2.0 * qy * qz + 2.0 * qw * qx;
00480 
00481   double Rs13 = 2.0 * qx * qz + 2.0 * qw * qy;
00482   double Rs23 = 2.0 * qy * qz - 2.0 * qw * qx;
00483   double Rs33 = qw * qw - qx * qx - qy * qy + qz * qz;
00484 
00485   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", Rs11, Rs12, Rs13, tx);
00486   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", Rs21, Rs22, Rs23, ty);
00487   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", Rs31, Rs32, Rs33, tz);
00488   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", 0.0, 0.0, 0.0, 1.0);
00489 }
00490 
00491 // angle axis to homogeneous transform inverted
00492 void print_AATasH(double x, double y, double z, double tx, double ty, double tz)
00493 {
00494   double R[9];
00495   double aa[3];
00496   aa[0] = x;
00497   aa[1] = y;
00498   aa[2] = z;
00499   ceres::AngleAxisToRotationMatrix(aa, R);
00500   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[0], R[3], R[6], tx);
00501   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[1], R[4], R[7], ty);
00502   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[2], R[5], R[8], tz);
00503   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", 0.0, 0.0, 0.0, 1.0);
00504 }
00505 
00506 // angle axis to homogeneous transform
00507 void print_AATasHI(double x, double y, double z, double tx, double ty, double tz)
00508 {
00509   double R[9];
00510   double aa[3];
00511   aa[0] = x;
00512   aa[1] = y;
00513   aa[2] = z;
00514   ceres::AngleAxisToRotationMatrix(aa, R);
00515   double ix = -(tx * R[0] + ty * R[1] + tz * R[2]);
00516   double iy = -(tx * R[3] + ty * R[4] + tz * R[5]);
00517   double iz = -(tx * R[6] + ty * R[7] + tz * R[8]);
00518   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[0], R[1], R[2], ix);
00519   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[3], R[4], R[5], iy);
00520   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", R[6], R[7], R[8], iz);
00521   printf("%6.3lf %6.3lf %6.3lf %6.3lf\n", 0.0, 0.0, 0.0, 1.0);
00522 }
00523 
00524 void print_AAasEuler(double x, double y, double z)
00525 {
00526   double R[9];
00527   double aa[3];
00528   aa[0] = x;
00529   aa[1] = y;
00530   aa[2] = z;
00531   ceres::AngleAxisToRotationMatrix(aa, R);
00532   double rx = atan2(R[7], R[8]);
00533   double ry = atan2(-R[6], sqrt(R[7] * R[7] + R[8] * R[8]));
00534   double rz = atan2(R[3], R[0]);
00535   printf("rpy = %8.4f %8.4f %8.4f\n", rx, ry, rz);
00536 }
00537 void print_camera(Camera C, std::string words)
00538 {
00539   printf("%s\n", words.c_str());
00540   printf("Camera to World Transform:\n");
00541   print_AATasHI(C.aa[0], C.aa[1], C.aa[2], C.pos[0], C.pos[1], C.pos[2]);
00542 
00543   printf("World to Camera\n");
00544   print_AATasH(C.aa[0], C.aa[1], C.aa[2], C.pos[0], C.pos[1], C.pos[2]);
00545   print_AAasEuler(C.aa[0], C.aa[1], C.aa[2]);
00546   printf("fx = %8.3lf fy = %8.3lf\n", C.fx, C.fy);
00547   printf("k1 = %8.3lf k2 = %8.3lf k3 = %8.3lf\n", C.k1, C.k2, C.k3);
00548   printf("p1 = %8.3lf p2 = %8.3lf\n", C.p1, C.p2);
00549   printf("cx = %8.3lf cy = %8.3lf\n", C.cx, C.cy);
00550 }


industrial_extrinsic_cal
Author(s): Chris Lewis
autogenerated on Wed Aug 26 2015 12:00:27