contrib/gel/mrc/vpgl/vpgl_comp_rational_camera.txx
Go to the documentation of this file.
00001 // This is gel/mrc/vpgl/vpgl_comp_rational_camera.txx
00002 #ifndef vpgl_comp_rational_camera_txx_
00003 #define vpgl_comp_rational_camera_txx_
00004 //:
00005 // \file
00006 #include "vpgl_comp_rational_camera.h"
00007 #include <vcl_cmath.h>
00008 #include <vcl_vector.txx>
00009 #include <vcl_fstream.h>
00010 #include <vgl/vgl_point_2d.h>
00011 #include <vgl/vgl_point_3d.h>
00012 //--------------------------------------
00013 // Constructors
00014 //
00015 
00016 // Create an identity projection, i.e. (x,y,z) identically maps to (x,y)
00017 template <class T>
00018 vpgl_comp_rational_camera<T>::vpgl_comp_rational_camera():
00019   vpgl_rational_camera<T>()
00020 {
00021   matrix_[0][0] = (T)1;   matrix_[0][1] = (T)0;   matrix_[0][2] = (T)0;
00022   matrix_[1][0] = (T)0;   matrix_[1][1] = (T)1;   matrix_[1][2] = (T)0;
00023   matrix_[2][0] = (T)0;   matrix_[2][1] = (T)0;   matrix_[2][2] = (T)1;
00024 }
00025 
00026 //: Constructor from a rational camera and an affine matrix
00027 template <class T>
00028 vpgl_comp_rational_camera<T>::
00029 vpgl_comp_rational_camera(vnl_matrix_fixed<T, 3,3> const& M,
00030                           vpgl_rational_camera<T> const& rcam) :
00031   vpgl_rational_camera<T>(rcam), matrix_(M)
00032 {
00033 }
00034 
00035 //: Constructor from translation only
00036 template <class T>
00037 vpgl_comp_rational_camera<T>::
00038 vpgl_comp_rational_camera(const T tu, const T tv,
00039                           vpgl_rational_camera<T> const& rcam):
00040   vpgl_rational_camera<T>(rcam)
00041 {
00042   matrix_[0][0] = (T)1;   matrix_[0][1] = (T)0;   matrix_[0][2] = tu;
00043   matrix_[1][0] = (T)0;   matrix_[1][1] = (T)1;   matrix_[1][2] = tv;
00044   matrix_[2][0] = (T)0;   matrix_[2][1] = (T)0;   matrix_[2][2] = (T)1;
00045 }
00046 
00047 //: Constructor from translation rotation only first rotate then translate
00048 template <class T>
00049 vpgl_comp_rational_camera<T>::
00050 vpgl_comp_rational_camera(const T tu, const T tv, const T angle_in_radians,
00051                           vpgl_rational_camera<T> const& rcam):
00052   vpgl_rational_camera<T>(rcam)
00053 {
00054   this->set_trans_rotation(tu, tv, angle_in_radians);
00055   matrix_[2][0] = (T)0; matrix_[2][1] = (T)0;  matrix_[2][2] = (T)1;
00056 }
00057 
00058 //: Constructor with all transform parameters
00059 template <class T>
00060 vpgl_comp_rational_camera<T>::
00061 vpgl_comp_rational_camera(const T tu, const T tv, const T angle_in_radians,
00062                           const T su, const T sv,
00063                           vpgl_rational_camera<T> const& rcam):
00064   vpgl_rational_camera<T>(rcam)
00065 {
00066   this->set_all(tu, tv, angle_in_radians, su, sv);
00067   matrix_[2][0] = (T)0;   matrix_[2][1] = (T)0;   matrix_[2][2] = (T)1;
00068 }
00069 
00070 //: read from a file
00071 template <class T>
00072 vpgl_comp_rational_camera<T>::vpgl_comp_rational_camera(vcl_string cam_path)
00073 {
00074   vpgl_rational_camera<T> *rcam = read_rational_camera<T >(cam_path);
00075 
00076   vcl_ifstream file_inp;
00077   file_inp.open(cam_path.c_str());
00078   if (!file_inp.good()) {
00079     vcl_cout << "error: bad filename: " << cam_path << vcl_endl;
00080     return;
00081   }
00082   vnl_matrix_fixed<T, 3,3> M;
00083   vcl_string input;
00084   bool good = false;
00085   while (!file_inp.eof()&&!good) {
00086     file_inp >> input;
00087     if (input=="affine_matrix")
00088     {
00089       file_inp >> M;
00090       good = true;
00091     }
00092   }
00093   if  (!good)
00094   {
00095     vcl_cout << "error: not a composite rational camera file\n";
00096     return;
00097   }
00098   *this = vpgl_comp_rational_camera<T>(M, *rcam);
00099 }
00100 
00101 template <class T>
00102 vpgl_comp_rational_camera<T>* vpgl_comp_rational_camera<T>::clone(void) const
00103 {
00104   return new vpgl_comp_rational_camera<T>(*this);
00105 }
00106 
00107 // Base projection method
00108 template <class T>
00109 void vpgl_comp_rational_camera<T>::project(const T x, const T y, const T z,
00110                                            T& u, T& v) const
00111 {
00112   //first project with the rational camera
00113   T ur, vr;
00114   vpgl_rational_camera<T>::project(x, y, z, ur, vr);
00115   //transform by affine map
00116   vnl_vector_fixed<T, 3> p, pt;
00117   p[0]=ur;   p[1]=vr; p[2]=(T)1;
00118   pt = matrix_*p;
00119   u = pt[0];
00120   v = pt[1];
00121 }
00122 
00123 //vnl interface methods
00124 template <class T>
00125 vnl_vector_fixed<T, 2>
00126 vpgl_comp_rational_camera<T>::project(vnl_vector_fixed<T, 3> const& world_point)const
00127 {
00128   vnl_vector_fixed<T, 2> image_point;
00129   this->project(world_point[0], world_point[1], world_point[2],
00130                 image_point[0], image_point[1]);
00131   return image_point;
00132 }
00133 
00134 //vgl interface methods
00135 template <class T>
00136 vgl_point_2d<T> vpgl_comp_rational_camera<T>::project(vgl_point_3d<T> world_point)const
00137 {
00138   T u = 0, v = 0;
00139   this->project(world_point.x(), world_point.y(), world_point.z(), u, v);
00140   return vgl_point_2d<T>(u, v);
00141 }
00142 
00143 //: print the camera parameters
00144 template <class T>
00145 void vpgl_comp_rational_camera<T>::print(vcl_ostream& s) const
00146 {
00147   vpgl_scale_offset<T> sox = this->scale_offsets()[this->X_INDX];
00148   vpgl_scale_offset<T> soy = this->scale_offsets()[this->Y_INDX];
00149   vpgl_scale_offset<T> soz = this->scale_offsets()[this->Z_INDX];
00150   vpgl_scale_offset<T> sou = this->scale_offsets()[this->U_INDX];
00151   vpgl_scale_offset<T> sov = this->scale_offsets()[this->V_INDX];
00152 
00153   s << "vpgl_comp_rational_camera:\n"
00154     << "------------------------\n"
00155     << "xoff = " << sox.offset()
00156     << "  yoff = " << soy.offset()
00157     << "  zoff = " << soz.offset() << '\n'
00158     << "xscale = " << sox.scale()
00159     << "  yscale = " << soy.scale()
00160     << "  zscale = " << soz.scale() << '\n'
00161 
00162     << "uoff = " << sou.offset()
00163     << "  voff = " << sov.offset() << '\n'
00164     << "uscale = " << sou.scale()
00165     << "  vscale = " << sov.scale() << "\n\n"
00166 
00167     << "U Numerator\n"
00168     << "[0] " << this->coefficient_matrix()[0][0]
00169     << " [1] " << this->coefficient_matrix()[0][1]
00170     << " [2] " << this->coefficient_matrix()[0][2]
00171     << " [3] " << this->coefficient_matrix()[0][3] <<'\n'
00172     << "[4] " << this->coefficient_matrix()[0][4]
00173     << " [5] " << this->coefficient_matrix()[0][5]
00174     << " [6] " << this->coefficient_matrix()[0][6]
00175     << " [7] " << this->coefficient_matrix()[0][7] <<'\n'
00176     << "[8] "  << this->coefficient_matrix()[0][8]
00177     << " [9] " << this->coefficient_matrix()[0][9]
00178     << " [10] " << this->coefficient_matrix()[0][10]
00179     << " [11] " << this->coefficient_matrix()[0][11] <<'\n'
00180     << "[12] " << this->coefficient_matrix()[0][12]
00181     << " [13] " << this->coefficient_matrix()[0][13]
00182     << " [14] " << this->coefficient_matrix()[0][14]
00183     << " [15] "  << this->coefficient_matrix()[0][15] <<'\n'
00184     << "[16] " << this->coefficient_matrix()[0][16]
00185     << " [17] " << this->coefficient_matrix()[0][17]
00186     << " [18] " << this->coefficient_matrix()[0][18]
00187     << " [19] " << this->coefficient_matrix()[0][19] <<"\n\n"
00188 
00189     << "U Denominator\n"
00190     << "[0] " << this->coefficient_matrix()[1][0]
00191     << " [1] " << this->coefficient_matrix()[1][1]
00192     << " [2] " << this->coefficient_matrix()[1][2]
00193     << " [3] " << this->coefficient_matrix()[1][3] <<'\n'
00194     << "[4] " << this->coefficient_matrix()[1][4]
00195     << " [5] " << this->coefficient_matrix()[1][5]
00196     << " [6] " << this->coefficient_matrix()[1][6]
00197     << " [7] " << this->coefficient_matrix()[1][7]  <<'\n'
00198     << "[8] " << this->coefficient_matrix()[1][8]
00199     << " [9] " << this->coefficient_matrix()[1][9]
00200     << " [10] " << this->coefficient_matrix()[1][10]
00201     << " [11] " << this->coefficient_matrix()[1][11] <<'\n'
00202     << "[12] " << this->coefficient_matrix()[1][12]
00203     << " [13] " << this->coefficient_matrix()[1][13]
00204     << " [14] " << this->coefficient_matrix()[1][14]
00205     << " [15] " << this->coefficient_matrix()[1][15] <<'\n'
00206     << "[16] " << this->coefficient_matrix()[1][16]
00207     << " [17] " << this->coefficient_matrix()[1][17]
00208     << " [18] " << this->coefficient_matrix()[1][18]
00209     << " [19] " << this->coefficient_matrix()[1][19] <<"\n\n"
00210 
00211     << "V Numerator\n"
00212     << "[0] " << this->coefficient_matrix()[2][0]
00213     << " [1] " << this->coefficient_matrix()[2][1]
00214     << " [2] " << this->coefficient_matrix()[2][2]
00215     << " [3] " << this->coefficient_matrix()[2][3]<<'\n'
00216     << "[4] " << this->coefficient_matrix()[2][4]
00217     << " [5] " << this->coefficient_matrix()[2][5]
00218     << " [6] " << this->coefficient_matrix()[2][6]
00219     << " [7] " << this->coefficient_matrix()[2][7] <<'\n'
00220     << "[8] " << this->coefficient_matrix()[2][8]
00221     << " [9] " << this->coefficient_matrix()[2][9]
00222     << " [10] " << this->coefficient_matrix()[2][10]
00223     << " [11] " << this->coefficient_matrix()[2][11] <<'\n'
00224     << "[12] " << this->coefficient_matrix()[2][12]
00225     << " [13] " << this->coefficient_matrix()[2][13]
00226     << " [14] " << this->coefficient_matrix()[2][14]
00227     << " [15] " << this->coefficient_matrix()[2][15]<<'\n'
00228     << "[16] " << this->coefficient_matrix()[2][16]
00229     << " [17] " << this->coefficient_matrix()[2][17]
00230     << " [18] " << this->coefficient_matrix()[2][18]
00231     << " [19] " << this->coefficient_matrix()[2][19] <<"\n\n"
00232 
00233     << "V Denominator\n"
00234     << "[0] " << this->coefficient_matrix()[3][0]
00235     << " [1] " << this->coefficient_matrix()[3][1]
00236     << " [2] " << this->coefficient_matrix()[3][2]
00237     << " [3] " << this->coefficient_matrix()[3][3]<<'\n'
00238     << "[4] " << this->coefficient_matrix()[3][4]
00239     << " [5] " << this->coefficient_matrix()[3][5]
00240     << " [6] " << this->coefficient_matrix()[3][6]
00241     << " [7] " << this->coefficient_matrix()[3][7] <<'\n'
00242     << "[8] " << this->coefficient_matrix()[3][8]
00243     << " [9] " << this->coefficient_matrix()[3][9]
00244     << " [10] " << this->coefficient_matrix()[3][10]
00245     << " [11] " << this->coefficient_matrix()[3][11] <<'\n'
00246     << "[12] " << this->coefficient_matrix()[3][12]
00247     << " [13] " << this->coefficient_matrix()[3][13]
00248     << " [14] " << this->coefficient_matrix()[3][14]
00249     << " [15] " << this->coefficient_matrix()[3][15]<<'\n'
00250     << "[16] " << this->coefficient_matrix()[3][16]
00251     << " [17] " << this->coefficient_matrix()[3][17]
00252     << " [18] " << this->coefficient_matrix()[3][18]
00253     << " [19] " << this->coefficient_matrix()[3][19] <<'\n'
00254     << "\nAffine Matrix\n"
00255     << matrix_ << '\n'
00256     <<"------------------------------------------------\n\n";
00257 }
00258 
00259 template <class T>
00260 bool vpgl_comp_rational_camera<T>::save(vcl_string cam_path)
00261 {
00262   vcl_ofstream file_out;
00263   file_out.open(cam_path.c_str());
00264   if (!file_out.good()) {
00265     vcl_cerr << "error: bad filename: " << cam_path << vcl_endl;
00266     return false;
00267   }
00268   file_out.precision(12);
00269 
00270   int map[20];
00271   map[0]=19;
00272   map[1]=9;
00273   map[2]=15;
00274   map[3]=18;
00275   map[4]=6;
00276   map[5]=8;
00277   map[6]=14;
00278   map[7]=3;
00279   map[8]=12;
00280   map[9]=17;
00281   map[10]=5;
00282   map[11]=0;
00283   map[12]=4;
00284   map[13]=7;
00285   map[14]=1;
00286   map[15]=10;
00287   map[16]=13;
00288   map[17]=2;
00289   map[18]=11;
00290   map[19]=16;
00291 
00292   file_out << "satId = \"????\";\n"
00293            << "bandId = \"RGB\";\n"
00294            << "SpecId = \"RPC00B\";\n"
00295            << "BEGIN_GROUP = IMAGE\n"
00296            << "\n\n"  // skip errBias and errRand fields
00297            << "  lineOffset = " << this->offset(this->V_INDX) << '\n'
00298            << "  sampOffset = " << this->offset(this->U_INDX) << '\n'
00299            << "  latOffset = " << this->offset(this->Y_INDX) << '\n'
00300            << "  longOffset = " << this->offset(this->X_INDX) << '\n'
00301            << "  heightOffset = " << this->offset(this->Z_INDX) << '\n'
00302            << "  lineScale = " << this->scale(this->V_INDX) << '\n'
00303            << "  sampScale = " << this->scale(this->U_INDX) << '\n'
00304            << "  latScale = " << this->scale(this->Y_INDX) << '\n'
00305            << "  longScale = " << this->scale(this->X_INDX) << '\n'
00306            << "  heightScale = " << this->scale(this->Z_INDX) << '\n';
00307   vnl_matrix_fixed<double,4,20> coeffs = this->coefficient_matrix();
00308   file_out << "  lineNumCoef = (";
00309   for (int i=0; i<20; i++) {
00310     file_out << "\n    " << coeffs[this->NEU_V][map[i]];
00311     if (i < 19)
00312       file_out << ',';
00313   }
00314   file_out << ");\n  lineDenCoef = (";
00315   for (int i=0; i<20; i++) {
00316     file_out << "\n    " << coeffs[this->DEN_V][map[i]];
00317     if (i < 19)
00318       file_out << ',';
00319   }
00320   file_out << ");\n  sampNumCoef = (";
00321   for (int i=0; i<20; i++) {
00322     file_out << "\n    " << coeffs[this->NEU_U][map[i]];
00323     if (i < 19)
00324       file_out << ',';
00325   }
00326   file_out << ");\n  sampDenCoef = (";
00327   for (int i=0; i<20; i++) {
00328     file_out << "\n    " << coeffs[this->DEN_U][map[i]];
00329     if (i < 19)
00330       file_out << ',';
00331   }
00332   file_out << ");\n"
00333            << "END_GROUP = IMAGE\n"
00334            << "END;\n"
00335 
00336            << "affine_matrix\n"
00337            << matrix_;
00338   return true;
00339 }
00340 
00341 
00342 template <class T>
00343 void
00344 vpgl_comp_rational_camera<T>::set_transform(vnl_matrix_fixed<T, 3,3> const& M)
00345 {
00346   matrix_ = M;
00347 }
00348 
00349 template <class T>
00350 void
00351 vpgl_comp_rational_camera<T>::set_translation(const T tu, const T tv)
00352 {
00353   matrix_[0][2]=tu;
00354   matrix_[1][2]=tv;
00355 }
00356 
00357 template <class T>
00358 void
00359 vpgl_comp_rational_camera<T>::set_trans_rotation(const T tu, const T tv,
00360                                                  const T angle_in_radians)
00361 {
00362   double theta_d = static_cast<double>(angle_in_radians);
00363   double c = vcl_cos(theta_d), s = vcl_sin(theta_d);
00364   T ct = static_cast<T>(c), st = static_cast<T>(s);
00365   matrix_[0][0] = ct; matrix_[0][1] = -st; matrix_[0][2] = tu;
00366   matrix_[1][0] = st; matrix_[1][1] = ct;  matrix_[1][2] = tv;
00367 }
00368 
00369 template <class T>
00370 void
00371 vpgl_comp_rational_camera<T>::set_all(const T tu, const T tv,
00372                                       const T angle_in_radians,
00373                                       const T su, const T sv)
00374 {
00375   double theta_d = static_cast<double>(angle_in_radians);
00376   double c = vcl_cos(theta_d), s = vcl_sin(theta_d);
00377   T ct = static_cast<T>(c), st = static_cast<T>(s);
00378   matrix_[0][0] = ct*su; matrix_[0][1] = -st*sv; matrix_[0][2] = tu;
00379   matrix_[1][0] = st*su; matrix_[1][1] = ct*sv;  matrix_[1][2] = tv;
00380 }
00381 
00382 template <class T>
00383 vnl_matrix_fixed<T, 3,3> vpgl_comp_rational_camera<T>::transform()
00384 {
00385   return matrix_;
00386 }
00387 
00388 template <class T>
00389 void vpgl_comp_rational_camera<T>::translation(T& tu, T& tv)
00390 {
00391   tu = matrix_[0][2];
00392   tv = matrix_[1][2];
00393 }
00394 
00395 template <class T>
00396 T vpgl_comp_rational_camera<T>::rotation_in_radians()
00397 {
00398   double y = static_cast<double>(matrix_[1][0]);
00399   double x = static_cast<double>(matrix_[0][0]);
00400   double angle = vcl_atan2(y, x);
00401   return static_cast<T>(angle);
00402 }
00403 
00404 //: note that scale factors are not negative
00405 template <class T>
00406 void vpgl_comp_rational_camera<T>::image_scale(T& su, T& sv)
00407 {
00408   double su_sq = static_cast<double>(matrix_[0][0]*matrix_[0][0] +
00409                                      matrix_[1][0]*matrix_[1][0]);
00410   double sv_sq = static_cast<double>(matrix_[0][1]*matrix_[0][1] +
00411                                      matrix_[1][1]*matrix_[1][1]);
00412   double sud = vcl_sqrt(su_sq);
00413   double svd = vcl_sqrt(sv_sq);
00414   su = static_cast<T>(sud);
00415   sv = static_cast<T>(svd);
00416 }
00417 
00418 //: Write to stream
00419 template <class T>
00420 vcl_ostream&  operator<<(vcl_ostream& s, const vpgl_comp_rational_camera<T >& c )
00421 {
00422   c.print(s);
00423   return s;
00424 }
00425 
00426 
00427 // Code for easy instantiation.
00428 #undef vpgl_COMP_RATIONAL_CAMERA_INSTANTIATE
00429 #define vpgl_COMP_RATIONAL_CAMERA_INSTANTIATE(T) \
00430 template class vpgl_comp_rational_camera<T >; \
00431 template vcl_ostream& operator<<(vcl_ostream&, const vpgl_comp_rational_camera<T >&)
00432 
00433 
00434 #endif // vpgl_comp_rational_camera_txx_