contrib/brl/bmvl/brct/brct_plane_calibrator.cxx

Go to the documentation of this file.
00001 #include "brct_plane_calibrator.h"
00002 //:
00003 // \file
00004 #include <vcl_fstream.h>
00005 #include <vcl_cmath.h> // for exp()
00006 #include <vnl/vnl_math.h>
00007 #include <vnl/vnl_numeric_traits.h>
00008 #include <vgl/algo/vgl_h_matrix_2d_compute_4point.h>
00009 #include <vgl/algo/vgl_h_matrix_2d_compute_linear.h>
00010 
00011 brct_plane_calibrator::brct_plane_calibrator()
00012 {
00013   z_back_ = 0;
00014   z_front_ = 0;
00015   pts_3d_.resize(Z_FRONT+1);
00016   corrs_.resize(Z_FRONT+1);
00017   cam_width_.resize(RIGHT+1);
00018   cam_height_.resize(RIGHT+1);
00019   for (int i = 0; i<=RIGHT; i++)
00020   {
00021     cam_width_[i]=0;
00022     cam_height_[i]=0;
00023   }
00024   initial_homographies_.resize(Z_FRONT+1);
00025   current_homographies_.resize(Z_FRONT+1);
00026   for (int i = 0; i<=Z_FRONT; i++)
00027   {
00028     initial_homographies_[i].resize(RIGHT+1);
00029     current_homographies_[i].resize(RIGHT+1);
00030   }
00031   debug_ = false;
00032   points_3d_valid_ = false;
00033   initial_homographies_valid_ = false;
00034 }
00035 
00036 brct_plane_calibrator::~brct_plane_calibrator()
00037 {
00038 }
00039 
00040 void brct_plane_calibrator::init_corrs()
00041 {
00042   corrs_.clear();
00043   int n_cams = 2;//for now
00044   for (int i = 0; i<=Z_FRONT; i++)
00045   {
00046     int n_pts = pts_3d_[i].size();
00047     vcl_vector<brct_plane_corr_sptr> corrs(n_pts);
00048     for (int j =0; j<n_pts; j++)
00049       corrs[j] = new brct_plane_corr(n_cams, i, j);
00050     corrs_[i]=corrs;
00051   }
00052 }
00053 
00054 void brct_plane_calibrator::read_data(vcl_string const& point3d_file)
00055 {
00056   vcl_ifstream instr(point3d_file.c_str());
00057 
00058   if (!instr)
00059   {
00060     vcl_cout<<"cannot open the file - "<< point3d_file <<'\n';
00061     return;
00062   }
00063   vcl_string label;
00064   instr >> label;
00065   if (!(label=="Z_BACK:"))
00066   {
00067     vcl_cout << "Bad file format\n";
00068     return;
00069   }
00070   instr >> z_back_;
00071   instr >> label;
00072   if (!(label=="NPOINTS:"))
00073   {
00074     vcl_cout << "Bad file format\n";
00075     return;
00076   }
00077   int npts=0;
00078   instr >> npts;
00079   instr >> label;
00080   if (!(label=="INDEX|X|Y|"))
00081   {
00082     vcl_cout << "Bad file format\n";
00083     return;
00084   }
00085   pts_3d_[Z_BACK].resize(npts);
00086   for (int i = 0; i<npts; i++)
00087   {
00088     int index=0;
00089     instr >> index;
00090     double x = 0, y=0;
00091     instr >> x;   instr >> y;
00092     pts_3d_[Z_BACK][index]= vgl_homg_point_2d<double>(x, y);
00093   }
00094   instr >> label;
00095   if (!(label=="Z_FRONT:"))
00096   {
00097     vcl_cout << "Bad file format\n";
00098     return;
00099   }
00100   instr >> z_front_;
00101   instr >> label;
00102   if (!(label=="NPOINTS:"))
00103   {
00104     vcl_cout << "Bad file format\n";
00105     return;
00106   }
00107   instr >> npts;
00108   instr >> label;
00109   if (!(label=="INDEX|X|Y|"))
00110   {
00111     vcl_cout << "Bad file format\n";
00112     return;
00113   }
00114   pts_3d_[Z_FRONT].resize(npts);
00115   for (int i = 0; i<npts; i++)
00116   {
00117     int index=0;
00118     instr >> index;
00119     double x = 0, y=0;
00120     instr >> x;   instr >> y;
00121     pts_3d_[Z_FRONT][index]= vgl_homg_point_2d<double>(x, y);
00122   }
00123 
00124   this->init_corrs();
00125   points_3d_valid_ = true;
00126   initial_homographies_valid_ = false;
00127 }
00128 
00129 
00130 bool brct_plane_calibrator::set_image_size(const int cam,
00131                                            const int width,
00132                                            const int height)
00133 {
00134   if (cam>RIGHT)
00135     return false;
00136   cam_width_[cam]=width;
00137   cam_height_[cam]=height;
00138   return true;
00139 }
00140 
00141 static bool four_image_corners(const int width, const int height,
00142                                vcl_vector<vgl_homg_point_2d<double> >& corners)
00143 {
00144   if (!width || !height)
00145     return false;
00146   corners.clear();
00147   vgl_homg_point_2d<double> p00(0,0), p01(width,0);
00148   vgl_homg_point_2d<double> p10(width, height), p11(0, height);
00149   corners.push_back(p00);   corners.push_back(p01);
00150   corners.push_back(p10);   corners.push_back(p11);
00151   return true;
00152 }
00153 
00154 static vgl_homg_point_2d<double>
00155 closest_point(double x0, double y0,
00156               vcl_vector<vgl_homg_point_2d<double> >& pts_3d)
00157 {
00158   double d_min = vnl_numeric_traits<double>::maxval;
00159   vgl_homg_point_2d<double> closest;
00160   unsigned int i_min = 0;
00161   for (unsigned int i = 0; i<pts_3d.size(); ++i)
00162   {
00163     double x=pts_3d[i].x()/pts_3d[i].w(), y=pts_3d[i].y()/pts_3d[i].w();
00164     double d = vcl_sqrt((x-x0)*(x-x0)+(y-y0)*(y-y0));
00165     if (d<d_min)
00166     {
00167       i_min = i;
00168       d_min = d;
00169       closest = pts_3d[i];
00170     }
00171   }
00172   //replace the closest point with a remote point
00173   //so it will not be chosen again
00174   pts_3d[i_min] = vgl_homg_point_2d<double>(1e8, 1e8);
00175   return closest;
00176 }
00177 
00178 //keep in mind that the image y axis is flipped
00179 static bool four_3d_corners(vcl_vector<vgl_homg_point_2d<double> > const& pts_3d,
00180                             vcl_vector<vgl_homg_point_2d<double> >& corners)
00181 {
00182   int n = pts_3d.size();
00183   if (n<4)
00184     return false;
00185   corners.clear();
00186   // make a copy, since we will be removing found points
00187   vcl_vector<vgl_homg_point_2d<double> > temp = pts_3d;
00188  //find the bounding box of 3-d points
00189   double x_min=vnl_numeric_traits<double>::maxval, x_max=-x_min;
00190   double y_min=x_min, y_max=x_max;
00191   for (int i=0; i<n; i++)
00192     if (pts_3d[i].w()<1e-08)
00193       return false;
00194     else
00195     {
00196       double x=pts_3d[i].x()/pts_3d[i].w(), y=pts_3d[i].y()/pts_3d[i].w();
00197       x_min = vnl_math_min(x_min, x);
00198       x_max = vnl_math_max(x_max, x);
00199       y_min = vnl_math_min(y_min, y);
00200       y_max = vnl_math_max(y_max, y);
00201     }
00202   //find the point projecting into the upper left image corner
00203   corners.push_back(closest_point(x_min, y_max, temp));
00204   //find the point projecting into the upper right image corner
00205   corners.push_back(closest_point(x_max, y_max, temp));
00206   //find the point projecting into the lower right image corner
00207   corners.push_back(closest_point(x_max, y_min, temp));
00208   //find the point projecting into the lower left image corner
00209   corners.push_back(closest_point(x_min, y_min, temp));
00210 
00211   return true;
00212 }
00213 
00214 static bool
00215 four_point_homography(vcl_vector<vgl_homg_point_2d<double> > const& points_3d,
00216                       vcl_vector<vgl_homg_point_2d<double> > const& image_pts,
00217                       vgl_h_matrix_2d<double>& H)
00218 {
00219   vgl_h_matrix_2d_compute_4point mapper;
00220   if (!mapper.compute(points_3d, image_pts, H))
00221     return false;
00222   return true;
00223 }
00224 
00225 bool brct_plane_calibrator::compute_initial_homographies()
00226 {
00227   vcl_vector<vgl_homg_point_2d<double> > image_corners, corner_3d_points;
00228   vgl_h_matrix_2d<double> H;
00229 
00230   for (int plane =0; plane<=Z_FRONT; plane++)
00231     if (!four_3d_corners(pts_3d_[plane], corner_3d_points))
00232       return false;
00233     else
00234       for (int cam = 0; cam<=RIGHT; cam++)
00235         if (!four_image_corners(cam_width_[cam], cam_height_[cam], image_corners))
00236           return false;
00237         else
00238           if (four_point_homography(corner_3d_points, image_corners, H))
00239             initial_homographies_[plane][cam] = H;
00240   initial_homographies_valid_ = true;
00241   return true;
00242 }
00243 
00244 bool brct_plane_calibrator::write_corrs(vcl_string const& corrs_file)
00245 {
00246   vcl_ofstream os(corrs_file.c_str());
00247   if (!os)
00248   {
00249     vcl_cout << "In brct_plane_calibrator::write_corrs -"
00250              << " could not open file " << corrs_file << '\n';
00251     return false;
00252   }
00253   for (int plane = 0; plane <=Z_FRONT; plane++)
00254   {
00255     os << "PLANE: " << plane << '\n';
00256     int n_corrs = corrs_[plane].size();
00257     os << "NCORRS: " << n_corrs << '\n';
00258     for (int c = 0; c<n_corrs; c++)
00259     {
00260       brct_plane_corr_sptr corr = corrs_[plane][c];
00261       os << *corr << '\n';
00262     }
00263   }
00264   return true;
00265 }
00266 
00267 bool brct_plane_calibrator::read_corrs(vcl_string const& corrs_file)
00268 {
00269   vcl_ifstream is(corrs_file.c_str());
00270   if (!is)
00271   {
00272     vcl_cout << "In brct_plane_calibrator::read_corrs -"
00273              << " could not open file " << corrs_file << '\n';
00274     return false;
00275   }
00276   vcl_vector<vcl_vector<brct_plane_corr_sptr> > corrs(Z_FRONT+1);
00277   for (int p = 0; p<=Z_FRONT; p++)
00278   {
00279   vcl_string s;
00280   is >> s;
00281   if (!(s=="PLANE:"))
00282     return false;
00283   int plane=0;
00284   is >> plane;
00285   is >> s;
00286   if (!(s=="NCORRS:"))
00287     return false;
00288   int n_corrs = 0;
00289   is >> n_corrs;
00290 
00291   for (int i = 0; i<n_corrs; i++)
00292   {
00293     int n_cams = 0, plane = 0, index = 0;
00294     is>> s;
00295     if (!(s=="NCAMS:"))
00296       return false;
00297     is >> n_cams;
00298     is >> s;
00299     if (!(s=="P:"))
00300       return false;
00301     is >> plane;
00302 
00303     is >> s;
00304     if (!(s=="I:"))
00305       return false;
00306     is >> index;
00307     brct_plane_corr_sptr corr = new brct_plane_corr(n_cams, plane, index);
00308     for (int cam = 0; cam<n_cams; cam++)
00309     {
00310       double x = 0, y = 0;
00311       is >> s;
00312       if (!(s=="X:"))
00313         return false;
00314       is >> x >> s;
00315       if (!(s=="Y:"))
00316         return false;
00317       is >> y;
00318       corr->set_match(cam, x, y);
00319     }
00320     corrs[plane].push_back(corr);
00321   }
00322     //file was sucessfully parsed
00323     corrs_ = corrs;
00324   }
00325   return true;
00326 }
00327 
00328 bool brct_plane_calibrator::compute_homographies()
00329 {
00330   for (int plane = 0; plane<=Z_FRONT; plane++)
00331     for (int cam = 0; cam<=RIGHT; cam++)
00332     {
00333       //get the corrs
00334       vcl_vector<brct_plane_corr_sptr>& corrs = corrs_[plane];
00335       //collect the corresponding points
00336       vcl_vector<vgl_homg_point_2d<double> > image_pts, pts_3d;
00337       for (vcl_vector<brct_plane_corr_sptr>::iterator cit = corrs.begin();
00338            cit != corrs.end(); cit++)
00339         if ((*cit)->valid(cam))
00340         {
00341           pts_3d.push_back(pts_3d_[plane][(*cit)->index()]);
00342           image_pts.push_back((*cit)->match(cam));
00343         }
00344       int n_3d = pts_3d.size(), n_img = image_pts.size();
00345       if (n_3d < 4 || n_img < 4)
00346       {
00347         vcl_cout << "In brct_plane_calibrator::compute_homographies()-"
00348                  << " not enough correspondences\n";
00349         return false;
00350       }
00351       vgl_h_matrix_2d_compute_linear hcl;
00352       vgl_h_matrix_2d<double> H;
00353       if (!hcl.compute(pts_3d, image_pts, H))
00354       {
00355         vcl_cout << "In brct_plane_calibrator::compute_homographies()-"
00356                  << " homography computation failed\n";
00357         return false;
00358       }
00359       current_homographies_[plane][cam]=H;
00360     }
00361   return true;
00362 }
00363 
00364 bool
00365 brct_plane_calibrator::write_homographies(vcl_string const& homography_file)
00366 {
00367   vcl_ofstream os(homography_file.c_str());
00368   if (!os)
00369   {
00370     vcl_cout << "In brct_plane_calibrator::write_homographies -"
00371              << " could not open file " << homography_file << '\n';
00372     return false;
00373   }
00374   os << "N_PLANES: " <<  Z_FRONT+1 << '\n'
00375      << "N_CAMS: " <<  RIGHT+1 << '\n';
00376   for (int plane = 0; plane<=Z_FRONT; plane++)
00377     for (int cam = 0; cam<=RIGHT; cam++)
00378     {
00379       os << "PLANE: " <<  plane << '\n';
00380       if (!plane)
00381         os << "Z: " << z_back_  << '\n';
00382       else
00383         os << "Z: " << z_front_ << '\n';
00384       os << "CAM: " <<   cam << '\n'
00385          << current_homographies_[plane][cam].get_matrix();
00386     }
00387   return true;
00388 }
00389 
00390 vcl_vector<vgl_point_2d<double> >
00391 brct_plane_calibrator::projected_3d_points_initial(const int plane,
00392                                                    const int cam)
00393 {
00394   vcl_vector<vgl_point_2d<double> > temp;
00395   if (plane>Z_FRONT)
00396     return temp;
00397   if (cam>RIGHT)
00398     return temp;
00399   for (unsigned int i = 0; i<pts_3d_[plane].size(); ++i)
00400   {
00401     vgl_homg_point_2d<double> hp =
00402       initial_homographies_[plane][cam](pts_3d_[plane][i]);
00403     vgl_point_2d<double> p(hp);
00404     temp.push_back(p);
00405   }
00406   return temp;
00407 }
00408 
00409 vcl_vector<vgl_point_2d<double> >
00410 brct_plane_calibrator::projected_3d_points(const int plane, const int cam)
00411 {
00412   vcl_vector<vgl_point_2d<double> > temp;
00413   if (plane>Z_FRONT)
00414     return temp;
00415   if (cam>RIGHT)
00416     return temp;
00417   for (unsigned int i = 0; i<pts_3d_[plane].size(); ++i)
00418   {
00419     vgl_homg_point_2d<double> hp =
00420       current_homographies_[plane][cam](pts_3d_[plane][i]);
00421     vgl_point_2d<double> p(hp);
00422     temp.push_back(p);
00423   }
00424   return temp;
00425 }

Generated on Fri Nov 21 05:24:04 2008 for contrib/brl/bmvl/brct by  doxygen 1.5.1