00001
00002 #ifndef vpgl_rational_camera_txx_
00003 #define vpgl_rational_camera_txx_
00004
00005
00006
00007 #include "vpgl_rational_camera.h"
00008 #include <vcl_vector.txx>
00009 #include <vcl_fstream.h>
00010 #include <vsl/vsl_binary_io.h>
00011
00012 #include <vgl/vgl_point_2d.h>
00013 #include <vgl/vgl_point_3d.h>
00014
00015
00016
00017
00018
00019 template <class T>
00020 vpgl_rational_camera<T>::vpgl_rational_camera()
00021 {
00022 rational_coeffs_.fill(0);
00023 rational_coeffs_[DEN_U][19]=1;
00024 rational_coeffs_[DEN_V][19]=1;
00025 rational_coeffs_[NEU_U][9]=1;
00026 rational_coeffs_[NEU_V][15]=1;
00027 vpgl_scale_offset<T> soff;
00028 scale_offsets_.resize(5, soff);
00029 }
00030
00031
00032 template <class T>
00033 vpgl_rational_camera<T>::
00034 vpgl_rational_camera(vcl_vector<vcl_vector<T> > const& rational_coeffs,
00035 vcl_vector<vpgl_scale_offset<T> > const& scale_offsets)
00036 {
00037 this->set_coefficients(rational_coeffs);
00038 this->set_scale_offsets(scale_offsets);
00039 }
00040
00041 template <class T>
00042 vpgl_rational_camera<T>::
00043 vpgl_rational_camera(vcl_vector<T> const& neu_u,
00044 vcl_vector<T> const& den_u,
00045 vcl_vector<T> const& neu_v,
00046 vcl_vector<T> const& den_v,
00047 const T x_scale, const T x_off,
00048 const T y_scale, const T y_off,
00049 const T z_scale, const T z_off,
00050 const T u_scale, const T u_off,
00051 const T v_scale, const T v_off
00052 )
00053 {
00054 for (unsigned i = 0; i<20; ++i)
00055 {
00056 rational_coeffs_[NEU_U][i] = neu_u[i];
00057 rational_coeffs_[DEN_U][i] = den_u[i];
00058 rational_coeffs_[NEU_V][i] = neu_v[i];
00059 rational_coeffs_[DEN_V][i] = den_v[i];
00060 }
00061 scale_offsets_.resize(5);
00062 scale_offsets_[X_INDX] = vpgl_scale_offset<T>(x_scale, x_off);
00063 scale_offsets_[Y_INDX] = vpgl_scale_offset<T>(y_scale, y_off);
00064 scale_offsets_[Z_INDX] = vpgl_scale_offset<T>(z_scale, z_off);
00065 scale_offsets_[U_INDX] = vpgl_scale_offset<T>(u_scale, u_off);
00066 scale_offsets_[V_INDX] = vpgl_scale_offset<T>(v_scale, v_off);
00067 }
00068
00069
00070 template <class T>
00071 vpgl_rational_camera<T>::
00072 vpgl_rational_camera(const double* neu_u,
00073 const double* den_u,
00074 const double* neu_v,
00075 const double* den_v,
00076 const T x_scale, const T x_off,
00077 const T y_scale, const T y_off,
00078 const T z_scale, const T z_off,
00079 const T u_scale, const T u_off,
00080 const T v_scale, const T v_off
00081 )
00082 {
00083 for (unsigned i = 0; i<20; ++i)
00084 {
00085 rational_coeffs_[NEU_U][i] = T(neu_u[i]);
00086 rational_coeffs_[DEN_U][i] = T(den_u[i]);
00087 rational_coeffs_[NEU_V][i] = T(neu_v[i]);
00088 rational_coeffs_[DEN_V][i] = T(den_v[i]);
00089 }
00090 scale_offsets_.resize(5);
00091 scale_offsets_[X_INDX] = vpgl_scale_offset<T>(x_scale, x_off);
00092 scale_offsets_[Y_INDX] = vpgl_scale_offset<T>(y_scale, y_off);
00093 scale_offsets_[Z_INDX] = vpgl_scale_offset<T>(z_scale, z_off);
00094 scale_offsets_[U_INDX] = vpgl_scale_offset<T>(u_scale, u_off);
00095 scale_offsets_[V_INDX] = vpgl_scale_offset<T>(v_scale, v_off);
00096 }
00097
00098 template <class T>
00099 vpgl_rational_camera<T>* vpgl_rational_camera<T>::clone(void) const
00100 {
00101 return new vpgl_rational_camera<T>(*this);
00102 }
00103
00104 template <class T>
00105 void vpgl_rational_camera<T>::
00106 set_coefficients(vcl_vector<vcl_vector<T> > const& rational_coeffs)
00107 {
00108 for (unsigned j = 0; j<4; ++j)
00109 for (unsigned i = 0; i<20; ++i)
00110 rational_coeffs_[j][i] = rational_coeffs[j][i];
00111 }
00112
00113 template <class T>
00114 void vpgl_rational_camera<T>::
00115 set_scale_offsets(vcl_vector<vpgl_scale_offset<T> > const& scale_offsets)
00116 {
00117 scale_offsets_=scale_offsets;
00118 }
00119
00120 template <class T>
00121 vcl_vector<vcl_vector<T> > vpgl_rational_camera<T>::coefficients() const
00122 {
00123 vcl_vector<vcl_vector<T> > result(4);
00124 for (unsigned j = 0; j<4; ++j)
00125 {
00126 result[j].resize(20);
00127 for (unsigned i = 0; i<20; ++i)
00128 result[j][i]=rational_coeffs_[j][i];
00129 }
00130 return result;
00131 }
00132
00133
00134 template <class T>
00135 vnl_vector_fixed<T, 20>
00136 vpgl_rational_camera<T>::power_vector(const T x, const T y, const T z) const
00137 {
00138
00139 double w = 1;
00140 double xx = x*x;
00141 double xy = x*y;
00142 double xz = x*z;
00143 double yy = y*y;
00144 double yz = y*z;
00145 double zz = z*z;
00146 double xxx = x*xx;
00147 double xxy = x*xy;
00148 double xxz = x*xz;
00149 double xyy = x*yy;
00150 double xyz = x*yz;
00151 double xzz = x*zz;
00152 double yyy = y*yy;
00153 double yyz = y*yz;
00154 double yzz = y*zz;
00155 double zzz = z*zz;
00156 double xww = x*w*w;
00157 double yww = y*w*w;
00158 double zww = z*w*w;
00159 double www = w*w*w;
00160 double xxw = xx*w;
00161 double xyw = xy*w;
00162 double xzw = xz*w;
00163 double yyw = yy*w;
00164 double yzw = yz*w;
00165 double zzw = zz*w;
00166
00167
00168 vnl_vector_fixed<T, 20> pv;
00169 pv.put( 0, T(xxx));
00170 pv.put( 1, T(xxy));
00171 pv.put( 2, T(xxz));
00172 pv.put( 3, T(xxw));
00173 pv.put( 4, T(xyy));
00174 pv.put( 5, T(xyz));
00175 pv.put( 6, T(xyw));
00176 pv.put( 7, T(xzz));
00177 pv.put( 8, T(xzw));
00178 pv.put( 9, T(xww));
00179 pv.put(10, T(yyy));
00180 pv.put(11, T(yyz));
00181 pv.put(12, T(yyw));
00182 pv.put(13, T(yzz));
00183 pv.put(14, T(yzw));
00184 pv.put(15, T(yww));
00185 pv.put(16, T(zzz));
00186 pv.put(17, T(zzw));
00187 pv.put(18, T(zww));
00188 pv.put(19, T(www));
00189 return pv;
00190 }
00191
00192
00193 template <class T>
00194 void vpgl_rational_camera<T>::project(const T x, const T y, const T z,
00195 T& u, T& v) const
00196 {
00197
00198 T sx = scale_offsets_[X_INDX].normalize(x);
00199 T sy = scale_offsets_[Y_INDX].normalize(y);
00200 T sz = scale_offsets_[Z_INDX].normalize(z);
00201 vnl_vector_fixed<T, 4> polys = rational_coeffs_*power_vector(sx, sy, sz);
00202 T su = polys[NEU_U]/polys[DEN_U];
00203 T sv = polys[NEU_V]/polys[DEN_V];
00204
00205 u = scale_offsets_[U_INDX].un_normalize(su);
00206 v = scale_offsets_[V_INDX].un_normalize(sv);
00207 }
00208
00209
00210 template <class T>
00211 vnl_vector_fixed<T, 2>
00212 vpgl_rational_camera<T>::project(vnl_vector_fixed<T, 3> const& world_point)const
00213 {
00214 vnl_vector_fixed<T, 2> image_point;
00215 this->project(world_point[0], world_point[1], world_point[2],
00216 image_point[0], image_point[1]);
00217 return image_point;
00218 }
00219
00220
00221 template <class T>
00222 vgl_point_2d<T> vpgl_rational_camera<T>::project(vgl_point_3d<T> world_point)const
00223 {
00224 T u = 0, v = 0;
00225 this->project(world_point.x(), world_point.y(), world_point.z(), u, v);
00226 return vgl_point_2d<T>(u, v);
00227 }
00228
00229
00230 template <class T>
00231 void vpgl_rational_camera<T>::print(vcl_ostream& s) const
00232 {
00233 vpgl_scale_offset<T> sox = scale_offsets_[X_INDX];
00234 vpgl_scale_offset<T> soy = scale_offsets_[Y_INDX];
00235 vpgl_scale_offset<T> soz = scale_offsets_[Z_INDX];
00236 vpgl_scale_offset<T> sou = scale_offsets_[U_INDX];
00237 vpgl_scale_offset<T> sov = scale_offsets_[V_INDX];
00238
00239 s << "vpgl_rational_camera:\n"
00240 << "------------------------\n"
00241 << "xoff = " << sox.offset()
00242 << " yoff = " << soy.offset()
00243 << " zoff = " << soz.offset() << '\n'
00244 << "xscale = " << sox.scale()
00245 << " yscale = " << soy.scale()
00246 << " zscale = " << soz.scale() << '\n'
00247
00248 << "uoff = " << sou.offset()
00249 << " voff = " << sov.offset() << '\n'
00250 << "uscale = " << sou.scale()
00251 << " vscale = " << sov.scale() << "\n\n"
00252
00253 << "U Numerator\n"
00254 << "[0] " << rational_coeffs_[0][0]
00255 << " [1] " << rational_coeffs_[0][1]
00256 << " [2] " << rational_coeffs_[0][2]
00257 << " [3] " << rational_coeffs_[0][3] <<'\n'
00258 << "[4] " << rational_coeffs_[0][4]
00259 << " [5] " << rational_coeffs_[0][5]
00260 << " [6] " << rational_coeffs_[0][6]
00261 << " [7] " << rational_coeffs_[0][7] <<'\n'
00262 << "[8] " << rational_coeffs_[0][8]
00263 << " [9] " << rational_coeffs_[0][9]
00264 << " [10] " << rational_coeffs_[0][10]
00265 << " [11] " << rational_coeffs_[0][11] <<'\n'
00266 << "[12] " << rational_coeffs_[0][12]
00267 << " [13] " << rational_coeffs_[0][13]
00268 << " [14] " << rational_coeffs_[0][14]
00269 << " [15] " << rational_coeffs_[0][15] <<'\n'
00270 << "[16] " << rational_coeffs_[0][16]
00271 << " [17] " << rational_coeffs_[0][17]
00272 << " [18] " << rational_coeffs_[0][18]
00273 << " [19] " << rational_coeffs_[0][19] <<"\n\n"
00274
00275 << "U Denominator\n"
00276 << "[0] " << rational_coeffs_[1][0]
00277 << " [1] " << rational_coeffs_[1][1]
00278 << " [2] " << rational_coeffs_[1][2]
00279 << " [3] " << rational_coeffs_[1][3] <<'\n'
00280 << "[4] " << rational_coeffs_[1][4]
00281 << " [5] " << rational_coeffs_[1][5]
00282 << " [6] " << rational_coeffs_[1][6]
00283 << " [7] " << rational_coeffs_[1][7] <<'\n'
00284 << "[8] " << rational_coeffs_[1][8]
00285 << " [9] " << rational_coeffs_[1][9]
00286 << " [10] " << rational_coeffs_[1][10]
00287 << " [11] " << rational_coeffs_[1][11] <<'\n'
00288 << "[12] " << rational_coeffs_[1][12]
00289 << " [13] " << rational_coeffs_[1][13]
00290 << " [14] " << rational_coeffs_[1][14]
00291 << " [15] " << rational_coeffs_[1][15] <<'\n'
00292 << "[16] " << rational_coeffs_[1][16]
00293 << " [17] " << rational_coeffs_[1][17]
00294 << " [18] " << rational_coeffs_[1][18]
00295 << " [19] " << rational_coeffs_[1][19] <<"\n\n"
00296
00297 << "V Numerator\n"
00298 << "[0] " << rational_coeffs_[2][0]
00299 << " [1] " << rational_coeffs_[2][1]
00300 << " [2] " << rational_coeffs_[2][2]
00301 << " [3] " << rational_coeffs_[2][3]<<'\n'
00302 << "[4] " << rational_coeffs_[2][4]
00303 << " [5] " << rational_coeffs_[2][5]
00304 << " [6] " << rational_coeffs_[2][6]
00305 << " [7] " << rational_coeffs_[2][7] <<'\n'
00306 << "[8] " << rational_coeffs_[2][8]
00307 << " [9] " << rational_coeffs_[2][9]
00308 << " [10] " << rational_coeffs_[2][10]
00309 << " [11] " << rational_coeffs_[2][11] <<'\n'
00310 << "[12] " << rational_coeffs_[2][12]
00311 << " [13] " << rational_coeffs_[2][13]
00312 << " [14] " << rational_coeffs_[2][14]
00313 << " [15] " << rational_coeffs_[2][15]<<'\n'
00314 << "[16] " << rational_coeffs_[2][16]
00315 << " [17] " << rational_coeffs_[2][17]
00316 << " [18] " << rational_coeffs_[2][18]
00317 << " [19] " << rational_coeffs_[2][19] <<"\n\n"
00318
00319 << "V Denominator\n"
00320 << "[0] " << rational_coeffs_[3][0]
00321 << " [1] " << rational_coeffs_[3][1]
00322 << " [2] " << rational_coeffs_[3][2]
00323 << " [3] " << rational_coeffs_[3][3]<<'\n'
00324 << "[4] " << rational_coeffs_[3][4]
00325 << " [5] " << rational_coeffs_[3][5]
00326 << " [6] " << rational_coeffs_[3][6]
00327 << " [7] " << rational_coeffs_[3][7] <<'\n'
00328 << "[8] " << rational_coeffs_[3][8]
00329 << " [9] " << rational_coeffs_[3][9]
00330 << " [10] " << rational_coeffs_[3][10]
00331 << " [11] " << rational_coeffs_[3][11] <<'\n'
00332 << "[12] " << rational_coeffs_[3][12]
00333 << " [13] " << rational_coeffs_[3][13]
00334 << " [14] " << rational_coeffs_[3][14]
00335 << " [15] " << rational_coeffs_[3][15]<<'\n'
00336 << "[16] " << rational_coeffs_[3][16]
00337 << " [17] " << rational_coeffs_[3][17]
00338 << " [18] " << rational_coeffs_[3][18]
00339 << " [19] " << rational_coeffs_[3][19] <<'\n'
00340 <<"------------------------------------------------\n\n";
00341 }
00342
00343 template <class T>
00344 bool vpgl_rational_camera<T>::save(vcl_string cam_path)
00345 {
00346 vcl_ofstream file_out;
00347 file_out.open(cam_path.c_str());
00348 if (!file_out.good()) {
00349 vcl_cerr << "error: bad filename: " << cam_path << vcl_endl;
00350 return false;
00351 }
00352 file_out.precision(12);
00353
00354 int map[20];
00355 map[0]=19;
00356 map[1]=9;
00357 map[2]=15;
00358 map[3]=18;
00359 map[4]=6;
00360 map[5]=8;
00361 map[6]=14;
00362 map[7]=3;
00363 map[8]=12;
00364 map[9]=17;
00365 map[10]=5;
00366 map[11]=0;
00367 map[12]=4;
00368 map[13]=7;
00369 map[14]=1;
00370 map[15]=10;
00371 map[16]=13;
00372 map[17]=2;
00373 map[18]=11;
00374 map[19]=16;
00375
00376 file_out << "satId = \"????\";\n"
00377 << "bandId = \"RGB\";\n"
00378 << "SpecId = \"RPC00B\";\n"
00379 << "BEGIN_GROUP = IMAGE\n"
00380 << "\n\n"
00381 << " lineOffset = " << offset(V_INDX) << '\n'
00382 << " sampOffset = " << offset(U_INDX) << '\n'
00383 << " latOffset = " << offset(Y_INDX) << '\n'
00384 << " longOffset = " << offset(X_INDX) << '\n'
00385 << " heightOffset = " << offset(Z_INDX) << '\n'
00386 << " lineScale = " << scale(V_INDX) << '\n'
00387 << " sampScale = " << scale(U_INDX) << '\n'
00388 << " latScale = " << scale(Y_INDX) << '\n'
00389 << " longScale = " << scale(X_INDX) << '\n'
00390 << " heightScale = " << scale(Z_INDX) << '\n';
00391 vnl_matrix_fixed<T,4,20> coeffs = this->coefficient_matrix();
00392 file_out << " lineNumCoef = (";
00393 for (int i=0; i<20; i++) {
00394 file_out << "\n " << coeffs[NEU_V][map[i]];
00395 if (i < 19)
00396 file_out << ',';
00397 }
00398 file_out << ");\n lineDenCoef = (";
00399 for (int i=0; i<20; i++) {
00400 file_out << "\n " << coeffs[DEN_V][map[i]];
00401 if (i < 19)
00402 file_out << ',';
00403 }
00404 file_out << ");\n sampNumCoef = (";
00405 for (int i=0; i<20; i++) {
00406 file_out << "\n " << coeffs[NEU_U][map[i]];
00407 if (i < 19)
00408 file_out << ',';
00409 }
00410 file_out << ");\n sampDenCoef = (";
00411 for (int i=0; i<20; i++) {
00412 file_out << "\n " << coeffs[DEN_U][map[i]];
00413 if (i < 19)
00414 file_out << ',';
00415 }
00416 file_out << ");\n"
00417 << "END_GROUP = IMAGE\n"
00418 << "END;\n";
00419
00420 return true;
00421 }
00422
00423
00424 template <class T>
00425 vcl_ostream& operator<<(vcl_ostream& s, const vpgl_rational_camera<T >& c )
00426 {
00427 c.print(s);
00428 return s;
00429 }
00430
00431
00432 template <class T>
00433 vpgl_rational_camera<T>* read_rational_camera(vcl_string cam_path)
00434 {
00435 vcl_ifstream file_inp;
00436 file_inp.open(cam_path.c_str());
00437 if (!file_inp.good()) {
00438 vcl_cout << "error: bad filename: " << cam_path << vcl_endl;
00439 return 0;
00440 }
00441 vpgl_rational_camera<T>* rcam = read_rational_camera<T>(file_inp);
00442 file_inp.close();
00443 return rcam;
00444 }
00445
00446 template <class T>
00447 vpgl_rational_camera<T>* read_rational_camera(vcl_istream& istr)
00448 {
00449 vcl_vector<T> neu_u;
00450 vcl_vector<T> den_u;
00451 vcl_vector<T> neu_v;
00452 vcl_vector<T> den_v;
00453 T x_scale,x_off,y_scale,y_off,z_scale,z_off,u_scale,u_off,v_scale,v_off;
00454
00455 vcl_string input;
00456 char bulk[100];
00457
00458 while (!istr.eof()) {
00459 istr >> input;
00460
00461 if (input=="sampScale") {
00462 istr >> input;
00463 istr >> u_scale;
00464 }
00465 if (input=="sampOffset") {
00466 istr >> input;
00467 istr >> u_off;
00468 }
00469
00470 if (input=="lineScale") {
00471 istr >> input;
00472 istr >> v_scale;
00473 }
00474 if (input=="lineOffset") {
00475 istr >> input;
00476 istr >> v_off;
00477 }
00478
00479 if (input=="longScale") {
00480 istr >> input;
00481 istr >> x_scale;
00482 }
00483 if (input=="longOffset") {
00484 istr >> input;
00485 istr >> x_off;
00486 }
00487
00488 if (input=="latScale") {
00489 istr >> input;
00490 istr >> y_scale;
00491 }
00492 if (input=="latOffset") {
00493 istr >> input;
00494 istr >> y_off;
00495 }
00496
00497 if (input=="heightScale") {
00498 istr >> input;
00499 istr >> z_scale;
00500 }
00501 if (input=="heightOffset") {
00502 istr >> input;
00503 istr >> z_off;
00504 }
00505
00506 T temp_dbl;
00507 if (input=="lineNumCoef") {
00508 istr >> input;
00509 istr >> input;
00510 for (int i=0; i<20; i++) {
00511 istr >> temp_dbl;
00512 neu_v.push_back(temp_dbl);
00513 istr.getline(bulk,200);
00514 }
00515 }
00516
00517 if (input=="lineDenCoef") {
00518 istr >> input;
00519 istr >> input;
00520 for (int i=0; i<20; i++) {
00521 istr >> temp_dbl;
00522 den_v.push_back(temp_dbl);
00523 istr.getline(bulk,200);
00524 }
00525 }
00526
00527 if (input=="sampNumCoef") {
00528 istr >> input;
00529 istr >> input;
00530 for (int i=0; i<20; i++) {
00531 istr >> temp_dbl;
00532 neu_u.push_back(temp_dbl);
00533 istr.getline(bulk,200);
00534 }
00535 }
00536
00537 if (input=="sampDenCoef") {
00538 istr >> input;
00539 istr >> input;
00540 for (int i=0; i<20; i++) {
00541 istr >> temp_dbl;
00542 den_u.push_back(temp_dbl);
00543 istr.getline(bulk,200);
00544 }
00545 break;
00546 }
00547 }
00548 istr >> input;
00549 if (input!="END_GROUP")
00550 return 0;
00551 istr >> input;
00552 if (input!="=")
00553 return 0;
00554 istr >> input;
00555 if (input!="IMAGE")
00556 return 0;
00557 istr >> input;
00558 if (input!="END;")
00559 return 0;
00560 int map[20];
00561 map[0]=19;
00562 map[1]=9;
00563 map[2]=15;
00564 map[3]=18;
00565 map[4]=6;
00566 map[5]=8;
00567 map[6]=14;
00568 map[7]=3;
00569 map[8]=12;
00570 map[9]=17;
00571 map[10]=5;
00572 map[11]=0;
00573 map[12]=4;
00574 map[13]=7;
00575 map[14]=1;
00576 map[15]=10;
00577 map[16]=13;
00578 map[17]=2;
00579 map[18]=11;
00580 map[19]=16;
00581
00582 if ((neu_u.size() != 20) || (den_u.size() != 20)) {
00583 vcl_cerr << "the input is not a valid rational camera\n";
00584 return 0;
00585 }
00586
00587 T temp_vector[20];
00588 for (int j=0; j<20; j++) {
00589 temp_vector[j] = neu_u[j];
00590 }
00591 for (int j=0; j<20; j++) {
00592 neu_u[map[j]] = temp_vector[j];
00593 }
00594 for (int j=0; j<20; j++) {
00595 temp_vector[j] = den_u[j];
00596 }
00597 for (int j=0; j<20; j++) {
00598 den_u[map[j]] = temp_vector[j];
00599 }
00600 for (int j=0; j<20; j++) {
00601 temp_vector[j] = neu_v[j];
00602 }
00603 for (int j=0; j<20; j++) {
00604 neu_v[map[j]] = temp_vector[j];
00605 }
00606 for (int j=0; j<20; j++) {
00607 temp_vector[j] = den_v[j];
00608 }
00609 for (int j=0; j<20; j++) {
00610 den_v[map[j]] = temp_vector[j];
00611 }
00612
00613 vpgl_rational_camera<T>* cam = new vpgl_rational_camera<T>(neu_u, den_u, neu_v, den_v,
00614 x_scale, x_off, y_scale, y_off, z_scale, z_off,
00615 u_scale, u_off, v_scale, v_off);
00616 return cam;
00617 }
00618
00619
00620 template <class T>
00621 vcl_istream& operator >>(vcl_istream& s, vpgl_rational_camera<T >& c )
00622 {
00623 vpgl_rational_camera<T>* cptr = read_rational_camera<T>(s);
00624 c = *cptr;
00625 return s;
00626 }
00627
00628
00629 #undef vpgl_RATIONAL_CAMERA_INSTANTIATE
00630 #define vpgl_RATIONAL_CAMERA_INSTANTIATE(T) \
00631 template class vpgl_scale_offset<T >; \
00632 template class vpgl_rational_camera<T >; \
00633 template vcl_ostream& operator<<(vcl_ostream&, const vpgl_rational_camera<T >&); \
00634 template vcl_istream& operator>>(vcl_istream&, vpgl_rational_camera<T >&); \
00635 template vpgl_rational_camera<T > * read_rational_camera(vcl_string); \
00636 template vpgl_rational_camera<T > * read_rational_camera(vcl_istream&); \
00637 typedef vpgl_scale_offset<T > soff; \
00638 VCL_VECTOR_INSTANTIATE(soff)
00639
00640
00641 #endif // vpgl_rational_camera_txx_