Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

brct_plane_calibrator.cxx

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

Generated on Thu Jan 10 14:54:03 2008 for contrib/brl/bmvl/brct by  doxygen 1.4.4