vpgl_rational_camera.hxx
Go to the documentation of this file.
1 // This is core/vpgl/vpgl_rational_camera.hxx
2 #ifndef vpgl_rational_camera_hxx_
3 #define vpgl_rational_camera_hxx_
4 //:
5 // \file
6 
7 #include <vector>
8 #include <fstream>
9 #include "vpgl_rational_camera.h"
10 #ifdef _MSC_VER
11 # include <vcl_msvc_warnings.h>
12 #endif
13 #include <vsl/vsl_binary_io.h>
14 //#include <vnl/io/vnl_io_matrix_fixed.h>
15 #include <vgl/vgl_point_2d.h>
16 #include <vgl/vgl_point_3d.h>
17 //--------------------------------------
18 // Constructors
19 //
20 
21 // Create an identity projection, i.e. (x,y) identically maps to (u,v)
22 template <class T>
24 {
25  rational_coeffs_.fill(0);
26  rational_coeffs_[DEN_U][19]=1;
27  rational_coeffs_[DEN_V][19]=1;
28  rational_coeffs_[NEU_U][9]=1; // x coefficient
29  rational_coeffs_[NEU_V][15]=1;// y coefficient
31  scale_offsets_.resize(5, soff);
32 }
33 
34 //: Constructor with an array encoding of the coefficients
35 template <class T>
37 vpgl_rational_camera(std::vector<std::vector<T> > const& rational_coeffs,
38  std::vector<vpgl_scale_offset<T> > const& scale_offsets)
39 {
40  this->set_coefficients(rational_coeffs);
41  this->set_scale_offsets(scale_offsets);
42 }
43 
44 template <class T>
46 vpgl_rational_camera(std::vector<T> const& neu_u,
47  std::vector<T> const& den_u,
48  std::vector<T> const& neu_v,
49  std::vector<T> const& den_v,
50  const T x_scale, const T x_off,
51  const T y_scale, const T y_off,
52  const T z_scale, const T z_off,
53  const T u_scale, const T u_off,
54  const T v_scale, const T v_off
55  )
56 {
57  for (unsigned i = 0; i<20; ++i)
58  {
59  rational_coeffs_[NEU_U][i] = neu_u[i];
60  rational_coeffs_[DEN_U][i] = den_u[i];
61  rational_coeffs_[NEU_V][i] = neu_v[i];
62  rational_coeffs_[DEN_V][i] = den_v[i];
63  }
64  scale_offsets_.resize(5);
65  scale_offsets_[X_INDX] = vpgl_scale_offset<T>(x_scale, x_off);
66  scale_offsets_[Y_INDX] = vpgl_scale_offset<T>(y_scale, y_off);
67  scale_offsets_[Z_INDX] = vpgl_scale_offset<T>(z_scale, z_off);
68  scale_offsets_[U_INDX] = vpgl_scale_offset<T>(u_scale, u_off);
69  scale_offsets_[V_INDX] = vpgl_scale_offset<T>(v_scale, v_off);
70 }
71 
72 //: Constructor from 4 coefficient arrays and 5 scale, offset pairs.
73 template <class T>
75 vpgl_rational_camera(const double* neu_u,
76  const double* den_u,
77  const double* neu_v,
78  const double* den_v,
79  const T x_scale, const T x_off,
80  const T y_scale, const T y_off,
81  const T z_scale, const T z_off,
82  const T u_scale, const T u_off,
83  const T v_scale, const T v_off
84  )
85 {
86  for (unsigned i = 0; i<20; ++i)
87  {
88  rational_coeffs_[NEU_U][i] = T(neu_u[i]);
89  rational_coeffs_[DEN_U][i] = T(den_u[i]);
90  rational_coeffs_[NEU_V][i] = T(neu_v[i]);
91  rational_coeffs_[DEN_V][i] = T(den_v[i]);
92  }
93  scale_offsets_.resize(5);
94  scale_offsets_[X_INDX] = vpgl_scale_offset<T>(x_scale, x_off);
95  scale_offsets_[Y_INDX] = vpgl_scale_offset<T>(y_scale, y_off);
96  scale_offsets_[Z_INDX] = vpgl_scale_offset<T>(z_scale, z_off);
97  scale_offsets_[U_INDX] = vpgl_scale_offset<T>(u_scale, u_off);
98  scale_offsets_[V_INDX] = vpgl_scale_offset<T>(v_scale, v_off);
99 }
100 
101 template <class T>
103 {
104  return new vpgl_rational_camera<T>(*this);
105 }
106 
107 template <class T>
109 set_coefficients(std::vector<std::vector<T> > const& rational_coeffs)
110 {
111  for (unsigned j = 0; j<4; ++j)
112  for (unsigned i = 0; i<20; ++i)
113  rational_coeffs_[j][i] = rational_coeffs[j][i];
114 }
115 
116 template <class T>
118 set_scale_offsets(std::vector<vpgl_scale_offset<T> > const& scale_offsets)
119 {
120  scale_offsets_=scale_offsets;
121 }
122 
123 template <class T>
124 std::vector<std::vector<T> > vpgl_rational_camera<T>::coefficients() const
125 {
126  std::vector<std::vector<T> > result(4);
127  for (unsigned j = 0; j<4; ++j)
128  {
129  result[j].resize(20);
130  for (unsigned i = 0; i<20; ++i)
131  result[j][i]=rational_coeffs_[j][i];
132  }
133  return result;
134 }
135 
136 //: Create a vector with the standard order of monomial terms
137 template <class T>
139 vpgl_rational_camera<T>::power_vector(const T x, const T y, const T z) const
140 {
141  // Form the monomials in homogeneous form
142  double w = 1;
143  double xx = x*x;
144  double xy = x*y;
145  double xz = x*z;
146  double yy = y*y;
147  double yz = y*z;
148  double zz = z*z;
149  double xxx = x*xx;
150  double xxy = x*xy;
151  double xxz = x*xz;
152  double xyy = x*yy;
153  double xyz = x*yz;
154  double xzz = x*zz;
155  double yyy = y*yy;
156  double yyz = y*yz;
157  double yzz = y*zz;
158  double zzz = z*zz;
159  double xww = x*w*w;
160  double yww = y*w*w;
161  double zww = z*w*w;
162  double www = w*w*w;
163  double xxw = xx*w;
164  double xyw = xy*w;
165  double xzw = xz*w;
166  double yyw = yy*w;
167  double yzw = yz*w;
168  double zzw = zz*w;
169 
170  //fill the vector
172  pv.put( 0, T(xxx));
173  pv.put( 1, T(xxy));
174  pv.put( 2, T(xxz));
175  pv.put( 3, T(xxw));
176  pv.put( 4, T(xyy));
177  pv.put( 5, T(xyz));
178  pv.put( 6, T(xyw));
179  pv.put( 7, T(xzz));
180  pv.put( 8, T(xzw));
181  pv.put( 9, T(xww));
182  pv.put(10, T(yyy));
183  pv.put(11, T(yyz));
184  pv.put(12, T(yyw));
185  pv.put(13, T(yzz));
186  pv.put(14, T(yzw));
187  pv.put(15, T(yww));
188  pv.put(16, T(zzz));
189  pv.put(17, T(zzw));
190  pv.put(18, T(zww));
191  pv.put(19, T(www));
192  return pv;
193 }
194 
195 // Base projection method
196 template <class T>
197 void vpgl_rational_camera<T>::project(const T x, const T y, const T z,
198  T& u, T& v) const
199 {
200  // scale, offset the world point before projection
201  T sx = scale_offsets_[X_INDX].normalize(x);
202  T sy = scale_offsets_[Y_INDX].normalize(y);
203  T sz = scale_offsets_[Z_INDX].normalize(z);
204  vnl_vector_fixed<T, 4> polys = rational_coeffs_*power_vector(sx, sy, sz);
205  T su = polys[NEU_U]/polys[DEN_U];
206  T sv = polys[NEU_V]/polys[DEN_V];
207  // unscale the resulting image coordinates
208  u = scale_offsets_[U_INDX].un_normalize(su);
209  v = scale_offsets_[V_INDX].un_normalize(sv);
210 }
211 
212 //vnl interface methods
213 template <class T>
216 {
217  vnl_vector_fixed<T, 2> image_point;
218  this->project(world_point[0], world_point[1], world_point[2],
219  image_point[0], image_point[1]);
220  return image_point;
221 }
222 
223 //vgl interface methods
224 template <class T>
226 {
227  T u = 0, v = 0;
228  this->project(world_point.x(), world_point.y(), world_point.z(), u, v);
229  return vgl_point_2d<T>(u, v);
230 }
231 
232 //: print the camera parameters
233 template <class T>
234 void vpgl_rational_camera<T>::print(std::ostream& s) const
235 {
236  vpgl_scale_offset<T> sox = scale_offsets_[X_INDX];
237  vpgl_scale_offset<T> soy = scale_offsets_[Y_INDX];
238  vpgl_scale_offset<T> soz = scale_offsets_[Z_INDX];
239  vpgl_scale_offset<T> sou = scale_offsets_[U_INDX];
240  vpgl_scale_offset<T> sov = scale_offsets_[V_INDX];
241 
242  s << "vpgl_rational_camera:\n"
243  << "------------------------\n"
244  << "xoff = " << sox.offset()
245  << " yoff = " << soy.offset()
246  << " zoff = " << soz.offset() << '\n'
247  << "xscale = " << sox.scale()
248  << " yscale = " << soy.scale()
249  << " zscale = " << soz.scale() << '\n'
250 
251  << "uoff = " << sou.offset()
252  << " voff = " << sov.offset() << '\n'
253  << "uscale = " << sou.scale()
254  << " vscale = " << sov.scale() << "\n\n"
255 
256  << "U Numerator\n"
257  << "[0] " << rational_coeffs_[0][0]
258  << " [1] " << rational_coeffs_[0][1]
259  << " [2] " << rational_coeffs_[0][2]
260  << " [3] " << rational_coeffs_[0][3] <<'\n'
261  << "[4] " << rational_coeffs_[0][4]
262  << " [5] " << rational_coeffs_[0][5]
263  << " [6] " << rational_coeffs_[0][6]
264  << " [7] " << rational_coeffs_[0][7] <<'\n'
265  << "[8] " << rational_coeffs_[0][8]
266  << " [9] " << rational_coeffs_[0][9]
267  << " [10] " << rational_coeffs_[0][10]
268  << " [11] " << rational_coeffs_[0][11] <<'\n'
269  << "[12] " << rational_coeffs_[0][12]
270  << " [13] " << rational_coeffs_[0][13]
271  << " [14] " << rational_coeffs_[0][14]
272  << " [15] " << rational_coeffs_[0][15] <<'\n'
273  << "[16] " << rational_coeffs_[0][16]
274  << " [17] " << rational_coeffs_[0][17]
275  << " [18] " << rational_coeffs_[0][18]
276  << " [19] " << rational_coeffs_[0][19] <<"\n\n"
277 
278  << "U Denominator\n"
279  << "[0] " << rational_coeffs_[1][0]
280  << " [1] " << rational_coeffs_[1][1]
281  << " [2] " << rational_coeffs_[1][2]
282  << " [3] " << rational_coeffs_[1][3] <<'\n'
283  << "[4] " << rational_coeffs_[1][4]
284  << " [5] " << rational_coeffs_[1][5]
285  << " [6] " << rational_coeffs_[1][6]
286  << " [7] " << rational_coeffs_[1][7] <<'\n'
287  << "[8] " << rational_coeffs_[1][8]
288  << " [9] " << rational_coeffs_[1][9]
289  << " [10] " << rational_coeffs_[1][10]
290  << " [11] " << rational_coeffs_[1][11] <<'\n'
291  << "[12] " << rational_coeffs_[1][12]
292  << " [13] " << rational_coeffs_[1][13]
293  << " [14] " << rational_coeffs_[1][14]
294  << " [15] " << rational_coeffs_[1][15] <<'\n'
295  << "[16] " << rational_coeffs_[1][16]
296  << " [17] " << rational_coeffs_[1][17]
297  << " [18] " << rational_coeffs_[1][18]
298  << " [19] " << rational_coeffs_[1][19] <<"\n\n"
299 
300  << "V Numerator\n"
301  << "[0] " << rational_coeffs_[2][0]
302  << " [1] " << rational_coeffs_[2][1]
303  << " [2] " << rational_coeffs_[2][2]
304  << " [3] " << rational_coeffs_[2][3]<<'\n'
305  << "[4] " << rational_coeffs_[2][4]
306  << " [5] " << rational_coeffs_[2][5]
307  << " [6] " << rational_coeffs_[2][6]
308  << " [7] " << rational_coeffs_[2][7] <<'\n'
309  << "[8] " << rational_coeffs_[2][8]
310  << " [9] " << rational_coeffs_[2][9]
311  << " [10] " << rational_coeffs_[2][10]
312  << " [11] " << rational_coeffs_[2][11] <<'\n'
313  << "[12] " << rational_coeffs_[2][12]
314  << " [13] " << rational_coeffs_[2][13]
315  << " [14] " << rational_coeffs_[2][14]
316  << " [15] " << rational_coeffs_[2][15]<<'\n'
317  << "[16] " << rational_coeffs_[2][16]
318  << " [17] " << rational_coeffs_[2][17]
319  << " [18] " << rational_coeffs_[2][18]
320  << " [19] " << rational_coeffs_[2][19] <<"\n\n"
321 
322  << "V Denominator\n"
323  << "[0] " << rational_coeffs_[3][0]
324  << " [1] " << rational_coeffs_[3][1]
325  << " [2] " << rational_coeffs_[3][2]
326  << " [3] " << rational_coeffs_[3][3]<<'\n'
327  << "[4] " << rational_coeffs_[3][4]
328  << " [5] " << rational_coeffs_[3][5]
329  << " [6] " << rational_coeffs_[3][6]
330  << " [7] " << rational_coeffs_[3][7] <<'\n'
331  << "[8] " << rational_coeffs_[3][8]
332  << " [9] " << rational_coeffs_[3][9]
333  << " [10] " << rational_coeffs_[3][10]
334  << " [11] " << rational_coeffs_[3][11] <<'\n'
335  << "[12] " << rational_coeffs_[3][12]
336  << " [13] " << rational_coeffs_[3][13]
337  << " [14] " << rational_coeffs_[3][14]
338  << " [15] " << rational_coeffs_[3][15]<<'\n'
339  << "[16] " << rational_coeffs_[3][16]
340  << " [17] " << rational_coeffs_[3][17]
341  << " [18] " << rational_coeffs_[3][18]
342  << " [19] " << rational_coeffs_[3][19] <<'\n'
343  <<"------------------------------------------------\n\n";
344 }
345 
346 template <class T>
347 bool vpgl_rational_camera<T>::save(std::string cam_path)
348 {
349  std::ofstream file_out;
350  file_out.open(cam_path.c_str());
351  if (!file_out.good()) {
352  std::cerr << "error: bad filename: " << cam_path << std::endl;
353  return false;
354  }
355  file_out.precision(12);
356 
357  int map[20];
358  map[0]=19;
359  map[1]=9;
360  map[2]=15;
361  map[3]=18;
362  map[4]=6;
363  map[5]=8;
364  map[6]=14;
365  map[7]=3;
366  map[8]=12;
367  map[9]=17;
368  map[10]=5;
369  map[11]=0;
370  map[12]=4;
371  map[13]=7;
372  map[14]=1;
373  map[15]=10;
374  map[16]=13;
375  map[17]=2;
376  map[18]=11;
377  map[19]=16;
378 
379  file_out << "satId = \"????\";\n"
380  << "bandId = \"RGB\";\n"
381  << "SpecId = \"RPC00B\";\n"
382  << "BEGIN_GROUP = IMAGE\n"
383  << "\n\n" // skip errBias and errRand fields
384  << " lineOffset = " << offset(V_INDX) << '\n'
385  << " sampOffset = " << offset(U_INDX) << '\n'
386  << " latOffset = " << offset(Y_INDX) << '\n'
387  << " longOffset = " << offset(X_INDX) << '\n'
388  << " heightOffset = " << offset(Z_INDX) << '\n'
389  << " lineScale = " << scale(V_INDX) << '\n'
390  << " sampScale = " << scale(U_INDX) << '\n'
391  << " latScale = " << scale(Y_INDX) << '\n'
392  << " longScale = " << scale(X_INDX) << '\n'
393  << " heightScale = " << scale(Z_INDX) << '\n';
394  vnl_matrix_fixed<T,4,20> coeffs = this->coefficient_matrix();
395  file_out << " lineNumCoef = (";
396  for (int i=0; i<20; i++) {
397  file_out << "\n " << coeffs[NEU_V][map[i]];
398  if (i < 19)
399  file_out << ',';
400  }
401  file_out << ");\n lineDenCoef = (";
402  for (int i=0; i<20; i++) {
403  file_out << "\n " << coeffs[DEN_V][map[i]];
404  if (i < 19)
405  file_out << ',';
406  }
407  file_out << ");\n sampNumCoef = (";
408  for (int i=0; i<20; i++) {
409  file_out << "\n " << coeffs[NEU_U][map[i]];
410  if (i < 19)
411  file_out << ',';
412  }
413  file_out << ");\n sampDenCoef = (";
414  for (int i=0; i<20; i++) {
415  file_out << "\n " << coeffs[DEN_U][map[i]];
416  if (i < 19)
417  file_out << ',';
418  }
419  file_out << ");\n"
420  << "END_GROUP = IMAGE\n"
421  << "END;\n";
422 
423  return true;
424 }
425 
426 //: Write to stream
427 template <class T>
428 std::ostream& operator<<(std::ostream& s, const vpgl_rational_camera<T >& c )
429 {
430  c.print(s);
431  return s;
432 }
433 
434 //: read from a file
435 template <class T>
437 {
438  std::ifstream file_inp;
439  file_inp.open(cam_path.c_str());
440  if (!file_inp.good()) {
441  std::cout << "error: bad filename: " << cam_path << std::endl;
442  return nullptr;
443  }
444  vpgl_rational_camera<T>* rcam = read_rational_camera<T>(file_inp);
445  file_inp.close();
446  return rcam;
447 }
448 //: read from an open istream
449 template <class T>
451 {
452  std::vector<T> neu_u;
453  std::vector<T> den_u;
454  std::vector<T> neu_v;
455  std::vector<T> den_v;
456  T x_scale,x_off,y_scale,y_off,z_scale,z_off,u_scale,u_off,v_scale,v_off;
457 
458  std::string input;
459  char bulk[100];
460 
461  while (!istr.eof()) {
462  istr >> input;
463 
464  if (input=="sampScale") {
465  istr >> input;
466  istr >> u_scale;
467  }
468  if (input=="sampOffset") {
469  istr >> input;
470  istr >> u_off;
471  }
472 
473  if (input=="lineScale") {
474  istr >> input;
475  istr >> v_scale;
476  }
477  if (input=="lineOffset") {
478  istr >> input;
479  istr >> v_off;
480  }
481 
482  if (input=="longScale") {
483  istr >> input;
484  istr >> x_scale;
485  }
486  if (input=="longOffset") {
487  istr >> input;
488  istr >> x_off;
489  }
490 
491  if (input=="latScale") {
492  istr >> input;
493  istr >> y_scale;
494  }
495  if (input=="latOffset") {
496  istr >> input;
497  istr >> y_off;
498  }
499 
500  if (input=="heightScale") {
501  istr >> input;
502  istr >> z_scale;
503  }
504  if (input=="heightOffset") {
505  istr >> input;
506  istr >> z_off;
507  }
508 
509  T temp_dbl;
510  if (input=="lineNumCoef") {
511  istr >> input;
512  istr >> input;
513  for (int i=0; i<20; i++) {
514  istr >> temp_dbl;
515  neu_v.push_back(temp_dbl);
516  istr.getline(bulk,200);
517  }
518  }
519 
520  if (input=="lineDenCoef") {
521  istr >> input;
522  istr >> input;
523  for (int i=0; i<20; i++) {
524  istr >> temp_dbl;
525  den_v.push_back(temp_dbl);
526  istr.getline(bulk,200);
527  }
528  }
529 
530  if (input=="sampNumCoef") {
531  istr >> input;
532  istr >> input;
533  for (int i=0; i<20; i++) {
534  istr >> temp_dbl;
535  neu_u.push_back(temp_dbl);
536  istr.getline(bulk,200);
537  }
538  }
539 
540  if (input=="sampDenCoef") {
541  istr >> input;
542  istr >> input;
543  for (int i=0; i<20; i++) {
544  istr >> temp_dbl;
545  den_u.push_back(temp_dbl);
546  istr.getline(bulk,200);
547  }
548  break;
549  }
550  }
551  istr >> input;
552  if (input!="END_GROUP")
553  return nullptr;
554  istr >> input;
555  if (input!="=")
556  return nullptr;
557  istr >> input;
558  if (input!="IMAGE")
559  return nullptr;
560  istr >> input;
561  if (input!="END;")
562  return nullptr;
563  int map[20];
564  map[0]=19;
565  map[1]=9;
566  map[2]=15;
567  map[3]=18;
568  map[4]=6;
569  map[5]=8;
570  map[6]=14;
571  map[7]=3;
572  map[8]=12;
573  map[9]=17;
574  map[10]=5;
575  map[11]=0;
576  map[12]=4;
577  map[13]=7;
578  map[14]=1;
579  map[15]=10;
580  map[16]=13;
581  map[17]=2;
582  map[18]=11;
583  map[19]=16;
584 
585  if ((neu_u.size() != 20) || (den_u.size() != 20)) {
586  std::cerr << "the input is not a valid rational camera\n";
587  return nullptr;
588  }
589 
590  T temp_vector[20];
591  for (int j=0; j<20; j++) {
592  temp_vector[j] = neu_u[j];
593  }
594  for (int j=0; j<20; j++) {
595  neu_u[map[j]] = temp_vector[j];
596  }
597  for (int j=0; j<20; j++) {
598  temp_vector[j] = den_u[j];
599  }
600  for (int j=0; j<20; j++) {
601  den_u[map[j]] = temp_vector[j];
602  }
603  for (int j=0; j<20; j++) {
604  temp_vector[j] = neu_v[j];
605  }
606  for (int j=0; j<20; j++) {
607  neu_v[map[j]] = temp_vector[j];
608  }
609  for (int j=0; j<20; j++) {
610  temp_vector[j] = den_v[j];
611  }
612  for (int j=0; j<20; j++) {
613  den_v[map[j]] = temp_vector[j];
614  }
615 
616  vpgl_rational_camera<T>* cam = new vpgl_rational_camera<T>(neu_u, den_u, neu_v, den_v,
617  x_scale, x_off, y_scale, y_off, z_scale, z_off,
618  u_scale, u_off, v_scale, v_off);
619  return cam;
620 }
621 
622 //: Creates a rational camera from a txt file
623 // \relatesalso vpgl_rational_camera
624 template <class T>
626 {
627  std::ifstream istr;
628  istr.open(cam_path.c_str());
629  if (!istr.good()) {
630  std::cout << "error: bad filename: " << cam_path << std::endl;
631  return nullptr;
632  }
633 
634  std::vector<T> neu_u;
635  std::vector<T> den_u;
636  std::vector<T> neu_v;
637  std::vector<T> den_v;
638  T x_scale,x_off,y_scale,y_off,z_scale,z_off,u_scale,u_off,v_scale,v_off;
639 
640  std::string input;
641  char bulk[100];
642 
643  while (!istr.eof()) {
644  istr >> input;
645 
646  if (input=="SAMP_SCALE:") {
647  //istr >> input;
648  istr >> u_scale;
649  }
650  if (input=="SAMP_OFF:") {
651  //istr >> input;
652  istr >> u_off;
653  }
654 
655  if (input=="LINE_SCALE:") {
656  //istr >> input;
657  istr >> v_scale;
658  }
659  if (input=="LINE_OFF:") {
660  //istr >> input;
661  istr >> v_off;
662  }
663 
664  if (input=="LONG_SCALE:") {
665  //istr >> input;
666  istr >> x_scale;
667  }
668  if (input=="LONG_OFF:") {
669  //istr >> input;
670  istr >> x_off;
671  }
672 
673  if (input=="LAT_SCALE:") {
674  //istr >> input;
675  istr >> y_scale;
676  }
677  if (input=="LAT_OFF:") {
678  //istr >> input;
679  istr >> y_off;
680  }
681 
682  if (input=="HEIGHT_SCALE:") {
683  //istr >> input;
684  istr >> z_scale;
685  }
686  if (input=="HEIGHT_OFF:") {
687  //istr >> input;
688  istr >> z_off;
689  }
690 
691  T temp_dbl;
692  if (input=="LINE_NUM_COEFF_1:") {
693  //istr >> input;
694  //istr >> input;
695  istr >> temp_dbl;
696  neu_v.push_back(temp_dbl);
697  for (int i=1; i<20; i++) {
698  istr >> input;
699  istr >> temp_dbl;
700  neu_v.push_back(temp_dbl);
701  istr.getline(bulk,200);
702  }
703  }
704 
705  if (input=="LINE_DEN_COEFF_1:") {
706  //istr >> input;
707  //istr >> input;
708  istr >> temp_dbl;
709  den_v.push_back(temp_dbl);
710  for (int i=1; i<20; i++) {
711  istr >> input;
712  istr >> temp_dbl;
713  den_v.push_back(temp_dbl);
714  istr.getline(bulk,200);
715  }
716  }
717 
718  if (input=="SAMP_NUM_COEFF_1:") {
719  //istr >> input;
720  //istr >> input;
721  istr >> temp_dbl;
722  neu_u.push_back(temp_dbl);
723  for (int i=1; i<20; i++) {
724  istr >> input;
725  istr >> temp_dbl;
726  neu_u.push_back(temp_dbl);
727  istr.getline(bulk,200);
728  }
729  }
730 
731  if (input=="SAMP_DEN_COEFF_1:") {
732  //istr >> input;
733  //istr >> input;
734  istr >> temp_dbl;
735  den_u.push_back(temp_dbl);
736  for (int i=1; i<20; i++) {
737  istr >> input;
738  istr >> temp_dbl;
739  den_u.push_back(temp_dbl);
740  istr.getline(bulk,200);
741  }
742  break;
743  }
744  }
745 
746  int map[20];
747  map[0]=19;
748  map[1]=9;
749  map[2]=15;
750  map[3]=18;
751  map[4]=6;
752  map[5]=8;
753  map[6]=14;
754  map[7]=3;
755  map[8]=12;
756  map[9]=17;
757  map[10]=5;
758  map[11]=0;
759  map[12]=4;
760  map[13]=7;
761  map[14]=1;
762  map[15]=10;
763  map[16]=13;
764  map[17]=2;
765  map[18]=11;
766  map[19]=16;
767 
768  if ((neu_u.size() != 20) || (den_u.size() != 20)) {
769  std::cerr << "the input is not a valid rational camera\n";
770  return nullptr;
771  }
772 
773  T temp_vector[20];
774  for (int j=0; j<20; j++) {
775  temp_vector[j] = neu_u[j];
776  }
777  for (int j=0; j<20; j++) {
778  neu_u[map[j]] = temp_vector[j];
779  }
780  for (int j=0; j<20; j++) {
781  temp_vector[j] = den_u[j];
782  }
783  for (int j=0; j<20; j++) {
784  den_u[map[j]] = temp_vector[j];
785  }
786  for (int j=0; j<20; j++) {
787  temp_vector[j] = neu_v[j];
788  }
789  for (int j=0; j<20; j++) {
790  neu_v[map[j]] = temp_vector[j];
791  }
792  for (int j=0; j<20; j++) {
793  temp_vector[j] = den_v[j];
794  }
795  for (int j=0; j<20; j++) {
796  den_v[map[j]] = temp_vector[j];
797  }
798 
799  vpgl_rational_camera<T>* cam = new vpgl_rational_camera<T>(neu_u, den_u, neu_v, den_v,
800  x_scale, x_off, y_scale, y_off, z_scale, z_off,
801  u_scale, u_off, v_scale, v_off);
802 
803  istr.close();
804  return cam;
805 }
806 
807 
808 //: Read from stream
809 template <class T>
810 std::istream& operator >>(std::istream& s, vpgl_rational_camera<T >& c )
811 {
812  vpgl_rational_camera<T>* cptr = read_rational_camera<T>(s);
813  c = *cptr;
814  return s;
815 }
816 
817 // Code for easy instantiation.
818 #undef vpgl_RATIONAL_CAMERA_INSTANTIATE
819 #define vpgl_RATIONAL_CAMERA_INSTANTIATE(T) \
820 template class vpgl_scale_offset<T >; \
821 template class vpgl_rational_camera<T >; \
822 template std::ostream& operator<<(std::ostream&, const vpgl_rational_camera<T >&); \
823 template std::istream& operator>>(std::istream&, vpgl_rational_camera<T >&); \
824 template vpgl_rational_camera<T > * read_rational_camera(std::string); \
825 template vpgl_rational_camera<T > * read_rational_camera(std::istream&); \
826 template vpgl_rational_camera<T > * read_rational_camera_from_txt(std::string);
827 
828 
829 #endif // vpgl_rational_camera_hxx_
A camera model based on ratios of cubic polynomials.
vpgl_rational_camera< T > * read_rational_camera(std::string cam_path)
Creates a rational camera from a file.
#define v
virtual bool save(std::string cam_path)
std::istream & operator >>(std::istream &s, vpgl_rational_camera< T > &c)
Read from stream.
void set_scale_offsets(std::vector< vpgl_scale_offset< T > > const &scale_offsets)
set coordinate scale and offsets.
vnl_vector_fixed< T, 20 > power_vector(const T x, const T y, const T z) const
Create a vector with the standard order of monomial terms.
vpgl_rational_camera()
default constructor.
std::vector< std::vector< T > > coefficients() const
get the rational polynomial coefficients in a vcl array.
std::ostream & operator<<(std::ostream &s, const vpgl_local_rational_camera< T > &p)
Write to stream.
virtual vpgl_rational_camera< T > * clone(void) const
Clone ‘this’: creation of a new object and initialization.
virtual void print(std::ostream &s=std::cout) const
print the camera parameters.
void set_coefficients(std::vector< std::vector< T > > const &rational_coeffs)
set rational polynomial coefficients.
void put(unsigned int i, T const &v)
vpgl_rational_camera< T > * read_rational_camera_from_txt(std::string cam_path)
Creates a rational camera from a txt file.
void project(const T x, const T y, const T z, T &u, T &v) const override
The generic camera interface. u represents image column, v image row.