00001
00002 #ifndef vpgl_comp_rational_camera_txx_
00003 #define vpgl_comp_rational_camera_txx_
00004
00005
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
00014
00015
00016
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
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
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
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
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
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
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
00113 T ur, vr;
00114 vpgl_rational_camera<T>::project(x, y, z, ur, vr);
00115
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
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
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
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"
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
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
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
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_