libcvd
camera.h
1 #ifndef CVD_INCLUDE_CAMERA_H
2 #define CVD_INCLUDE_CAMERA_H
3 
4 #include <TooN/TooN.h>
5 #include <TooN/helpers.h>
6 #include <cmath>
7 
8 namespace CVD
9 {
10 template <class T>
11 inline T SAT(T x) { return (x < -1.0 / 3 ? -1e9 : x); }
12 
15 namespace Camera
16 {
17 
20  class Linear
21  {
22  public:
24  static const int num_parameters = 4;
25 
28  void load(std::istream& is)
29  {
30  is >> my_camera_parameters;
31  }
34  void save(std::ostream& os) const
35  {
36  os << my_camera_parameters;
37  }
38 
40  inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, TooN::DefaultPrecision scale) const
41  {
42  return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0, 2>()) + my_camera_parameters.slice<2, 2>());
43  }
45  inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const
46  {
47  return TooN::Vector<2>(diagmult(camframe, my_camera_parameters.slice<0, 2>()) + my_camera_parameters.slice<2, 2>());
48  }
50  inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const
51  {
52  TooN::Vector<2> my_last_camframe;
53  my_last_camframe[0] = (imframe[0] - my_camera_parameters[2]) / my_camera_parameters[0];
54  my_last_camframe[1] = (imframe[1] - my_camera_parameters[3]) / my_camera_parameters[1];
55  return my_last_camframe;
56  }
57 
60  TooN::Matrix<2, 2> get_derivative_at(const TooN::Vector<2>&) const
61  {
62  TooN::Matrix<2, 2> result;
63  result(0, 0) = my_camera_parameters[0];
64  result(1, 1) = my_camera_parameters[1];
65  result(0, 1) = result(1, 0) = 0;
66  return result;
67  }
68 
72  TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& pos, const TooN::Vector<2>& direction) const
73  {
74  TooN::Vector<num_parameters> result;
75  result[0] = pos[0] * direction[0];
76  result[1] = pos[1] * direction[1];
77  result[2] = direction[0];
78  result[3] = direction[1];
79 
80  return result;
81  }
82 
83  TooN::Matrix<num_parameters, 2> get_parameter_derivs(const TooN::Vector<2>& pos) const
84  {
85  TooN::Matrix<num_parameters, 2> result;
86  result(0, 0) = pos[0];
87  result(0, 1) = 0;
88  result(1, 0) = 0;
89  result(1, 1) = pos[1];
90  result(2, 0) = 1;
91  result(2, 1) = 0;
92  result(3, 0) = 0;
93  result(3, 1) = 1;
94  return result;
95  }
96 
100  void update(const TooN::Vector<num_parameters>& updates)
101  {
102  my_camera_parameters += updates;
103  }
104 
107  inline TooN::Vector<num_parameters>& get_parameters() { return my_camera_parameters; }
108  inline const TooN::Vector<num_parameters>& get_parameters() const { return my_camera_parameters; }
109 
110  private:
111  TooN::Vector<num_parameters> my_camera_parameters;
112  };
113 
116  class Cubic
117  {
118  public:
120  static const int num_parameters = 5;
121 
124  inline void load(std::istream& is);
127  inline void save(std::ostream& os) const;
128 
130  inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, TooN::DefaultPrecision scale = 1) const;
132  inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const;
134  inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const;
135 
138  inline TooN::Matrix<2, 2> get_derivative_at(const TooN::Vector<2>&) const;
139 
143  inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& pos, const TooN::Vector<2>& direction) const;
144 
145  inline TooN::Matrix<Camera::Cubic::num_parameters, 2> get_parameter_derivs(const TooN::Vector<2>& pos) const;
146 
150  inline void update(const TooN::Vector<num_parameters>& updates);
151 
154  inline TooN::Vector<num_parameters>& get_parameters() { return my_camera_parameters; }
155  inline const TooN::Vector<num_parameters>& get_parameters() const { return my_camera_parameters; }
156 
157  private:
158  TooN::Vector<num_parameters> my_camera_parameters; // f_u, f_v, u_0, v_0
159  };
160 
163  class Quintic
164  {
165  public:
167  static const int num_parameters = 6;
168 
171  inline void load(std::istream& is);
174  inline void save(std::ostream& os) const;
175 
177  inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, TooN::DefaultPrecision scale = 1) const;
179 
180  inline TooN::Vector<2> project_vector(const TooN::Vector<2>& x, const TooN::Vector<2>& d) const
181  {
182  const TooN::DefaultPrecision xsq = x * x;
183  const TooN::DefaultPrecision& a = my_camera_parameters[4];
184  const TooN::DefaultPrecision& b = my_camera_parameters[5];
185  return (2 * (a + 2 * b * xsq) * (x * d) * TooN::diagmult(my_camera_parameters.slice<0, 2>(), x) + (1 + a * xsq + b * xsq * xsq) * TooN::diagmult(my_camera_parameters.slice<0, 2>(), d));
186  }
187 
188  inline TooN::Vector<2> project_vector(const TooN::Vector<2>& d) const
189  {
190  return diagmult(my_camera_parameters.slice<0, 2>(), d);
191  }
192  inline TooN::Vector<2> unproject_vector(const TooN::Vector<2>& d) const
193  {
194  TooN::Vector<2> v;
195  v[0] = d[0] / my_camera_parameters[0];
196  v[1] = d[1] / my_camera_parameters[1];
197  return v;
198  }
199  inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const;
200  inline std::pair<TooN::Vector<2>, TooN::Matrix<2>> project(const TooN::Vector<2>& camframe, const TooN::Matrix<2>& R) const;
201 
203  inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const;
204 
205  inline std::pair<TooN::Vector<2>, TooN::Matrix<2>> unproject(const TooN::Vector<2>& imframe, const TooN::Matrix<2>& R) const;
206 
209  inline TooN::Matrix<2, 2> get_derivative() const;
210  inline TooN::Matrix<2, 2> get_derivative(const TooN::Vector<2>& x) const;
211 
212  inline TooN::Matrix<2, 2> get_inv_derivative() const;
213  inline TooN::Matrix<2, 2> get_inv_derivative(const TooN::Vector<2>& x) const;
214 
216  inline TooN::Matrix<num_parameters, 2> get_parameter_derivs() const;
217 
221  inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const;
222 
226  inline void update(const TooN::Vector<num_parameters>& updates);
227 
230  inline const TooN::Vector<num_parameters>& get_parameters() const { return my_camera_parameters; }
233  inline TooN::Vector<num_parameters>& get_parameters() { return my_camera_parameters; }
234 
235  private:
236  TooN::Vector<num_parameters> my_camera_parameters; // f_u, f_v, u_0, v_0
237  mutable TooN::Vector<2> my_last_camframe;
238 
239  inline TooN::DefaultPrecision sat(TooN::DefaultPrecision x)
240  {
241  TooN::DefaultPrecision a;
242  a = (-3 * my_camera_parameters[4] - sqrt(9 * my_camera_parameters[4] * my_camera_parameters[4] - 20 * my_camera_parameters[5])) / (10 * my_camera_parameters[5]);
243 
244  if(x < a)
245  return x;
246  else
247  return 1e9; //(inf)
248  }
249  };
250 
261  class Harris
262  {
263 
264  private:
265  TooN::Vector<2> radial_distort(const TooN::Vector<2>& camframe) const
266  {
267  TooN::DefaultPrecision r2 = camframe * camframe;
268  return camframe / sqrt(1 + my_camera_parameters[4] * r2);
269  }
270 
271  public:
273  static const int num_parameters = 5;
274 
277  inline void load(std::istream& is)
278  {
279  is >> my_camera_parameters;
280  }
281 
284  inline void save(std::ostream& os) const
285  {
286  os << my_camera_parameters;
287  }
288 
290  inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, TooN::DefaultPrecision scale = 1) const
291  {
292  return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0, 2>()) + my_camera_parameters.slice<2, 2>());
293  }
294 
296  inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const
297  {
298  return linearproject(radial_distort(camframe));
299  }
300 
302  inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const
303  {
304  //Undo the focal length and optic axis.
305  TooN::Vector<2> mod_camframe;
306  mod_camframe[0] = (imframe[0] - my_camera_parameters[2]) / my_camera_parameters[0];
307  mod_camframe[1] = (imframe[1] - my_camera_parameters[3]) / my_camera_parameters[1];
308  TooN::DefaultPrecision rprime2 = mod_camframe * mod_camframe;
309  return mod_camframe / sqrt(1 - my_camera_parameters[4] * rprime2);
310  }
311 
316  inline TooN::Matrix<2, 2> get_derivative_at(const TooN::Vector<2>& pt) const
317  {
318  TooN::Matrix<2, 2> J;
319 
320  TooN::DefaultPrecision xc = pt[0];
321  TooN::DefaultPrecision yc = pt[1];
322 
323  TooN::DefaultPrecision fu = my_camera_parameters[0];
324  TooN::DefaultPrecision fv = my_camera_parameters[1];
325  TooN::DefaultPrecision a = my_camera_parameters[4];
326 
327  TooN::DefaultPrecision g = 1 / sqrt(1 + a * (xc * xc + yc * yc));
328  TooN::DefaultPrecision g3 = g * g * g;
329 
330  J[0][0] = fu * (g - a * xc * xc * g3);
331  J[0][1] = -fu * a * xc * yc * g3;
332  J[1][0] = -fv * a * xc * yc * g3;
333  J[1][1] = fv * (g - a * yc * yc * g3);
334 
335  return J;
336  }
337 
340  inline TooN::Matrix<num_parameters, 2> get_parameter_derivs_at(const TooN::Vector<2>& pt) const
341  {
342  TooN::Vector<2> mod_camframe = radial_distort(pt);
343 
344  TooN::Matrix<5, 2> result;
345 
346  TooN::DefaultPrecision xc = pt[0];
347  TooN::DefaultPrecision yc = pt[1];
348  TooN::DefaultPrecision r2 = xc * xc + yc * yc;
349 
350  TooN::DefaultPrecision fu = my_camera_parameters[0];
351  TooN::DefaultPrecision fv = my_camera_parameters[1];
352  TooN::DefaultPrecision a = my_camera_parameters[4];
353 
354  TooN::DefaultPrecision g = 1 / sqrt(1 + a * r2);
355  TooN::DefaultPrecision g3 = g * g * g;
356 
357  //Derivatives of x_image:
358  result[0][0] = mod_camframe[0];
359  result[1][0] = 0;
360  result[2][0] = 1;
361  result[3][0] = 0;
362  result[4][0] = -fu * xc * r2 / 2 * g3;
363 
364  //Derivatives of y_image:
365  result[0][1] = 0;
366  result[1][1] = mod_camframe[1];
367  result[2][1] = 0;
368  result[3][1] = 1;
369  result[4][1] = -fv * yc * r2 / 2 * g3;
370 
371  return result;
372  }
373 
377  inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& position, const TooN::Vector<2>& direction) const
378  {
379  return get_parameter_derivs_at(position) * direction;
380  }
381 
385  //inline void update(const TooN::Vector<num_parameters>& updates);
386 
389  inline TooN::Vector<num_parameters>& get_parameters()
390  {
391  return my_camera_parameters;
392  }
393  inline const TooN::Vector<num_parameters>& get_parameters() const
394  {
395  return my_camera_parameters;
396  }
397 
398  private:
399  TooN::Vector<num_parameters> my_camera_parameters; // f_u, f_v, u_0, v_0, alpha
400  };
401 
405  {
406 
407  private:
408  TooN::Vector<2> radial_distort(const TooN::Vector<2>& camframe) const
409  {
410  TooN::DefaultPrecision r2 = camframe * camframe;
411  return camframe / sqrt(1 + my_camera_parameters[4] * r2);
412  }
413 
414  public:
416  static const int num_parameters = 5;
417 
420  inline void load(std::istream& is)
421  {
422  is >> my_camera_parameters;
423  }
424 
427  inline void save(std::ostream& os) const
428  {
429  os << my_camera_parameters;
430  }
431 
433  inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, TooN::DefaultPrecision scale = 1) const
434  {
435  return TooN::Vector<2>(scale * (camframe * my_camera_parameters[0]) + my_camera_parameters.slice<2, 2>());
436  }
437 
439  inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const
440  {
441  my_last_camframe = camframe;
442  return linearproject(radial_distort(camframe));
443  }
444 
446  inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const
447  {
448  //Undo the focal length and optic axis.
449  TooN::Vector<2> mod_camframe;
450  mod_camframe[0] = (imframe[0] - my_camera_parameters[2]) / my_camera_parameters[0];
451  mod_camframe[1] = (imframe[1] - my_camera_parameters[3]) / my_camera_parameters[0];
452  TooN::DefaultPrecision rprime2 = mod_camframe * mod_camframe;
453  my_last_camframe = mod_camframe / sqrt(1 - my_camera_parameters[4] * rprime2);
454  return my_last_camframe;
455  }
456 
459  inline TooN::Matrix<2, 2> get_derivative() const
460  {
461  TooN::Matrix<2, 2> J;
462 
463  TooN::DefaultPrecision xc = my_last_camframe[0];
464  TooN::DefaultPrecision yc = my_last_camframe[1];
465 
466  TooN::DefaultPrecision f = my_camera_parameters[0];
467  TooN::DefaultPrecision a = my_camera_parameters[4];
468 
469  TooN::DefaultPrecision g = 1 / sqrt(1 + a * (xc * xc + yc * yc));
470  TooN::DefaultPrecision g3 = g * g * g;
471 
472  J[0][0] = f * (g - 2 * a * xc * xc * g3);
473  J[0][1] = -2 * f * a * xc * yc * g3;
474  J[1][0] = -2 * f * a * xc * yc * g3;
475  J[1][1] = f * (g - 2 * a * yc * yc * g3);
476 
477  return J;
478  }
479 
481  inline TooN::Matrix<num_parameters, 2> get_parameter_derivs() const
482  {
483  TooN::Vector<2> mod_camframe = radial_distort(my_last_camframe);
484 
485  TooN::Matrix<5, 2> result;
486 
487  TooN::DefaultPrecision xc = my_last_camframe[0];
488  TooN::DefaultPrecision yc = my_last_camframe[1];
489  TooN::DefaultPrecision r2 = xc * xc + yc * yc;
490 
491  TooN::DefaultPrecision f = my_camera_parameters[0];
492  TooN::DefaultPrecision a = my_camera_parameters[4];
493 
494  TooN::DefaultPrecision g = 1 / sqrt(1 + a * r2);
495  TooN::DefaultPrecision g3 = g * g * g;
496 
497  //Derivatives of x_image:
498  result[0][0] = mod_camframe[0];
499  result[1][0] = 0;
500  result[2][0] = 1;
501  result[3][0] = 0;
502  result[4][0] = -f * xc * r2 / 2 * g3;
503 
504  //Derivatives of y_image:
505  result[0][1] = mod_camframe[1];
506  result[1][1] = 0;
507  result[2][1] = 0;
508  result[3][1] = 1;
509  result[4][1] = -f * yc * r2 / 2 * g3;
510 
511  return result;
512  }
513 
517  inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const
518  {
519  return get_parameter_derivs() * direction;
520  }
521 
525  //inline void update(const TooN::Vector<num_parameters>& updates);
526 
529  inline TooN::Vector<num_parameters>& get_parameters()
530  {
531  my_camera_parameters[1] = 0;
532  return my_camera_parameters;
533  }
534 
535  private:
536  TooN::Vector<num_parameters> my_camera_parameters; // f_u, f_v, u_0, v_0, alpha
537  mutable TooN::Vector<2> my_last_camframe;
538  };
539 
549  class ArcTan
550  {
551 
552  private:
553  TooN::Vector<2> radial_distort(const TooN::Vector<2>& camframe) const
554  {
555  const TooN::DefaultPrecision r2 = camframe * camframe;
556  const TooN::DefaultPrecision w2 = my_camera_parameters[4] * my_camera_parameters[4];
557  const TooN::DefaultPrecision factor = w2 * r2;
558  TooN::DefaultPrecision term = 1.0;
559  TooN::DefaultPrecision scale = term;
560  term *= factor;
561  scale -= term / 3.0;
562  term *= factor;
563  scale += term / 5.0;
564  term *= factor;
565  scale -= term / 7.0;
566  return (scale * camframe);
567  }
568 
569  public:
571  static const int num_parameters = 5;
572 
575  inline void load(std::istream& is)
576  {
577  is >> my_camera_parameters;
578  }
579 
582  inline void save(std::ostream& os) const
583  {
584  os << my_camera_parameters;
585  }
586 
588  inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, TooN::DefaultPrecision scale = 1) const
589  {
590  return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0, 2>()) + my_camera_parameters.slice<2, 2>());
591  }
592 
594  inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const
595  {
596  return linearproject(radial_distort(camframe));
597  }
598 
600  inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const
601  {
602  //Undo the focal length and optic axis.
603  TooN::Vector<2> mod_camframe;
604  mod_camframe[0] = (imframe[0] - my_camera_parameters[2]) / my_camera_parameters[0];
605  mod_camframe[1] = (imframe[1] - my_camera_parameters[3]) / my_camera_parameters[1];
606  const TooN::DefaultPrecision rprime2 = mod_camframe * mod_camframe;
607 
608  // first guess
609  TooN::DefaultPrecision scale = mod_camframe * mod_camframe;
610 
611  const TooN::DefaultPrecision w2 = my_camera_parameters[4] * my_camera_parameters[4];
612  const TooN::DefaultPrecision k3 = -w2 / 3.0;
613  const TooN::DefaultPrecision k5 = w2 * w2 / 5.0;
614  const TooN::DefaultPrecision k7 = -w2 * w2 * w2 / 7.0;
615 
616  // 3 iterations of Newton-Raphson
617  for(int i = 0; i < 3; i++)
618  {
619  TooN::DefaultPrecision temp = 1 + scale * (k3 + scale * (k5 + scale * k7));
620  TooN::DefaultPrecision error = rprime2 - scale * temp * temp;
621  TooN::DefaultPrecision deriv = temp * (temp + 2 * scale * (k3 + 2 * scale * (k5 + 1.5 * scale * k7)));
622  scale += error / deriv;
623  }
624  return mod_camframe / (1 + scale * (k3 + scale * (k5 + scale * k7)));
625  }
626 
630  inline TooN::Matrix<2, 2> get_derivative(const TooN::Vector<2>& pt) const
631  {
632  TooN::Matrix<2, 2> J = TooN::Identity;
633  TooN::DefaultPrecision r2 = pt * pt;
634  const TooN::DefaultPrecision w2 = my_camera_parameters[4] * my_camera_parameters[4];
635  const TooN::DefaultPrecision k3 = -w2 / 3.0;
636  const TooN::DefaultPrecision k5 = w2 * w2 / 5.0;
637  const TooN::DefaultPrecision k7 = -w2 * w2 * w2 / 7.0;
638  J *= (1 + k3 * r2 + k5 * r2 * r2 + k7 * r2 * r2 * r2);
639  J += ((2 * k3 + 4 * k5 * r2 + 6 * k7 * r2 * r2) * pt.as_col()) * pt.as_row();
640  J[0] *= my_camera_parameters[0];
641  J[1] *= my_camera_parameters[1];
642  return J;
643  }
644 
647  inline TooN::Matrix<num_parameters, 2> get_parameter_derivs_at(const TooN::Vector<2>& pt) const
648  {
649  TooN::Vector<2> mod_camframe = radial_distort(pt);
650 
651  TooN::Matrix<5, 2> result;
652 
653  const TooN::DefaultPrecision xc = pt[0];
654  const TooN::DefaultPrecision yc = pt[1];
655  const TooN::DefaultPrecision r2 = xc * xc + yc * yc;
656  const TooN::DefaultPrecision r4 = r2 * r2;
657  const TooN::DefaultPrecision r6 = r4 * r2;
658 
659  const TooN::DefaultPrecision fu = my_camera_parameters[0];
660  const TooN::DefaultPrecision fv = my_camera_parameters[1];
661 
662  const TooN::DefaultPrecision w = my_camera_parameters[4];
663  const TooN::DefaultPrecision w3 = w * w * w;
664  const TooN::DefaultPrecision w5 = w3 * w * w;
665 
666  const TooN::DefaultPrecision k1 = -(2.0 / 3.0) * w * r2;
667  const TooN::DefaultPrecision k2 = (4.0 / 5.0) * w3 * r4;
668  const TooN::DefaultPrecision k3 = -(6.0 / 7.0) * w5 * r6;
669 
670  //Derivatives of x_image:
671  result[0][0] = mod_camframe[0];
672  result[1][0] = 0;
673  result[2][0] = 1;
674  result[3][0] = 0;
675  result[4][0] = fu * (k1 + k2 + k3) * xc;
676 
677  //Derivatives of y_image:
678  result[0][1] = 0;
679  result[1][1] = mod_camframe[1];
680  result[2][1] = 0;
681  result[3][1] = 1;
682  result[4][1] = fv * (k1 + k2 + k3) * yc;
683 
684  return result;
685  }
686 
690  inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& pos, const TooN::Vector<2>& direction) const
691  {
692  return get_parameter_derivs_at(pos) * direction;
693  }
694 
698  //inline void update(const TooN::Vector<num_parameters>& updates);
699 
702  inline TooN::Vector<num_parameters>& get_parameters()
703  {
704  return my_camera_parameters;
705  }
706  inline const TooN::Vector<num_parameters>& get_parameters() const
707  {
708  return my_camera_parameters;
709  }
710 
711  private:
712  TooN::Vector<num_parameters> my_camera_parameters; // f_u, f_v, u_0, v_0, omega
713  };
714 
719  template <class C>
720  class OldCameraAdapter : public C
721  {
722  public:
723  using C::num_parameters;
724  TooN::Vector<2> project(const TooN::Vector<2>& v) const
725  {
726  my_last_camframe = v;
727  return C::project(v);
728  }
729 
730  TooN::Matrix<2> get_derivative() const
731  {
732  return C::get_derivative_at(my_last_camframe);
733  }
734 
735  TooN::Matrix<num_parameters, 2> get_parameter_derivs() const
736  {
737  return C::get_parameter_derivs_at(my_last_camframe);
738  }
739 
740  TooN::Vector<2> unproject(const TooN::Vector<2>& v) const
741  {
742  my_last_camframe = C::unproject(v);
743  return my_last_camframe;
744  }
745 
746  private:
747  mutable TooN::Vector<2> my_last_camframe;
748  };
749 
750 }
751 
753 // Camera::Cubic inline functions //
755 
756 void Camera::Cubic::load(std::istream& is)
757 {
758  is >> my_camera_parameters;
759 }
760 
761 void Camera::Cubic::save(std::ostream& os) const
762 {
763  os << my_camera_parameters;
764 }
765 
766 inline TooN::Vector<2> Camera::Cubic::linearproject(const TooN::Vector<2>& camframe, TooN::DefaultPrecision scale) const
767 {
768  return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0, 2>()) + my_camera_parameters.slice<2, 2>());
769 }
770 
771 inline TooN::Vector<2> Camera::Cubic::project(const TooN::Vector<2>& camframe) const
772 {
773  TooN::Vector<2> mod_camframe = camframe * (1 + SAT(my_camera_parameters[4] * (camframe * camframe)));
774  return TooN::Vector<2>(diagmult(mod_camframe, my_camera_parameters.slice<0, 2>()) + my_camera_parameters.slice<2, 2>());
775 }
776 
777 inline TooN::Vector<2> Camera::Cubic::unproject(const TooN::Vector<2>& imframe) const
778 {
779  TooN::Vector<2> mod_camframe;
780  mod_camframe[0] = (imframe[0] - my_camera_parameters[2]) / my_camera_parameters[0];
781  mod_camframe[1] = (imframe[1] - my_camera_parameters[3]) / my_camera_parameters[1];
782 
783  // first guess
784  TooN::DefaultPrecision scale = 1 + my_camera_parameters[4] * (mod_camframe * mod_camframe);
785 
786  // 3 iterations of Newton-Rapheson
787  for(int i = 0; i < 3; i++)
788  {
789  TooN::DefaultPrecision error = my_camera_parameters[4] * (mod_camframe * mod_camframe) - scale * scale * (scale - 1);
790  TooN::DefaultPrecision deriv = (3 * scale - 2) * scale;
791  scale += error / deriv;
792  }
793  return mod_camframe / scale;
794 }
795 
796 TooN::Matrix<2, 2> Camera::Cubic::get_derivative_at(const TooN::Vector<2>& pos) const
797 {
798  TooN::Matrix<2, 2> result = TooN::Identity;
799  result *= 1 + my_camera_parameters[4] * (pos * pos);
800  result += (2 * my_camera_parameters[4] * pos.as_col()) * pos.as_row();
801  result[0] *= my_camera_parameters[0];
802  result[1] *= my_camera_parameters[1];
803  return result;
804 }
805 
806 TooN::Matrix<Camera::Cubic::num_parameters, 2> Camera::Cubic::get_parameter_derivs(const TooN::Vector<2>& pos) const
807 {
808  TooN::Vector<2> mod_camframe = pos * (1 + my_camera_parameters[4] * (pos * pos));
809  TooN::Matrix<num_parameters, 2> result;
810  result(0, 0) = mod_camframe[0] * my_camera_parameters[0];
811  result(0, 1) = 0;
812  result(1, 0) = 0;
813  result(1, 1) = mod_camframe[1] * my_camera_parameters[1];
814  result(2, 0) = 1 * my_camera_parameters[0];
815  result(2, 1) = 0;
816  result(3, 0) = 0;
817  result(3, 1) = 1 * my_camera_parameters[1];
818  result[4] = diagmult(pos, my_camera_parameters.slice<0, 2>()) * (pos * pos);
819  return result;
820 }
821 
822 TooN::Vector<Camera::Cubic::num_parameters> Camera::Cubic::get_parameter_derivs(const TooN::Vector<2>& pos, const TooN::Vector<2>& direction) const
823 {
824  TooN::Vector<2> mod_camframe = pos * (1 + my_camera_parameters[4] * (pos * pos));
825  TooN::Vector<num_parameters> result;
826  result[0] = mod_camframe[0] * direction[0] * my_camera_parameters[0];
827  result[1] = mod_camframe[1] * direction[1] * my_camera_parameters[1];
828  result[2] = direction[0] * my_camera_parameters[0];
829  result[3] = direction[1] * my_camera_parameters[1];
830  result[4] = (diagmult(pos, my_camera_parameters.slice<0, 2>()) * direction) * (pos * pos);
831  return result;
832 }
833 
834 void Camera::Cubic::update(const TooN::Vector<num_parameters>& updates)
835 {
836  TooN::DefaultPrecision fu = my_camera_parameters[0];
837  TooN::DefaultPrecision fv = my_camera_parameters[1];
838  my_camera_parameters[0] += fu * updates[0];
839  my_camera_parameters[1] += fv * updates[1];
840  my_camera_parameters[2] += fu * updates[2];
841  my_camera_parameters[3] += fv * updates[3];
842  my_camera_parameters[4] += updates[4];
843  //my_camera_parameters+=updates;
844 }
845 
847 // Camera::Quintic inline functions //
849 
850 void Camera::Quintic::load(std::istream& is)
851 {
852  is >> my_camera_parameters;
853 }
854 
855 void Camera::Quintic::save(std::ostream& os) const
856 {
857  os << my_camera_parameters;
858 }
859 
860 inline TooN::Vector<2> Camera::Quintic::linearproject(const TooN::Vector<2>& camframe, TooN::DefaultPrecision scale) const
861 {
862  return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0, 2>()) + my_camera_parameters.slice<2, 2>());
863 }
864 
865 inline TooN::Vector<2> Camera::Quintic::project(const TooN::Vector<2>& camframe) const
866 {
867  my_last_camframe = camframe;
868  TooN::DefaultPrecision sc = /*sat*/ (camframe * camframe);
869  TooN::Vector<2> mod_camframe = camframe * (1 + sc * (my_camera_parameters[4] + sc * my_camera_parameters[5]));
870  return TooN::Vector<2>(diagmult(mod_camframe, my_camera_parameters.slice<0, 2>()) + my_camera_parameters.slice<2, 2>());
871 }
872 
873 inline std::pair<TooN::Vector<2>, TooN::Matrix<2>> Camera::Quintic::project(const TooN::Vector<2>& camframe, const TooN::Matrix<2>& R) const
874 {
875  std::pair<TooN::Vector<2>, TooN::Matrix<2>> result;
876  result.first = this->project(camframe);
877  const TooN::Matrix<2> J = this->get_derivative();
878  result.second = J * R * J.T();
879  return result;
880 }
881 
882 inline TooN::Vector<2> Camera::Quintic::unproject(const TooN::Vector<2>& imframe) const
883 {
884  TooN::Vector<2> mod_camframe;
885  mod_camframe[0] = (imframe[0] - my_camera_parameters[2]) / my_camera_parameters[0];
886  mod_camframe[1] = (imframe[1] - my_camera_parameters[3]) / my_camera_parameters[1];
887 
888  // first guess
889  TooN::DefaultPrecision scale = mod_camframe * mod_camframe;
890 
891  // 3 iterations of Newton-Rapheson
892  for(int i = 0; i < 3; i++)
893  {
894  TooN::DefaultPrecision temp = 1 + scale * (my_camera_parameters[4] + my_camera_parameters[5] * scale);
895  TooN::DefaultPrecision error = mod_camframe * mod_camframe - scale * temp * temp;
896  TooN::DefaultPrecision deriv = temp * (temp + 2 * scale * (my_camera_parameters[4] + 2 * my_camera_parameters[5] * scale));
897  scale += error / deriv;
898  }
899  my_last_camframe = mod_camframe / (1 + scale * (my_camera_parameters[4] + my_camera_parameters[5] * scale));
900 
901  //std::cout<<"Done inverse on "<<imframe<<" - when reprojected get "<<project(my_last_camframe)<<std::endl;
902 
903  return my_last_camframe;
904 }
905 
906 inline std::pair<TooN::Vector<2>, TooN::Matrix<2>> Camera::Quintic::unproject(const TooN::Vector<2>& imframe, const TooN::Matrix<2>& R) const
907 {
908  std::pair<TooN::Vector<2>, TooN::Matrix<2>> result;
909  result.first = this->unproject(imframe);
910  TooN::Matrix<2> J = get_derivative();
911  TooN::DefaultPrecision rdet = 1 / (J[0][0] * J[1][1] - J[0][1] * J[1][0]);
912  TooN::Matrix<2> Jinv;
913  Jinv[0][0] = rdet * J[1][1];
914  Jinv[1][1] = rdet * J[0][0];
915  Jinv[0][1] = -rdet * J[0][1];
916  Jinv[1][0] = -rdet * J[1][0];
917  result.second = Jinv * R * Jinv.T();
918  return result;
919 }
920 
921 TooN::Matrix<2, 2> Camera::Quintic::get_derivative() const
922 {
923  TooN::Matrix<2, 2> result = TooN::Identity;
924  TooN::DefaultPrecision temp1 = my_last_camframe * my_last_camframe;
925  TooN::DefaultPrecision temp2 = my_camera_parameters[5] * temp1;
926  result *= 1 + temp1 * (my_camera_parameters[4] + temp2);
927  result += (2 * (my_camera_parameters[4] + 2 * temp2) * my_last_camframe.as_col()) * my_last_camframe.as_row();
928  result[0] *= my_camera_parameters[0];
929  result[1] *= my_camera_parameters[1];
930  return result;
931 }
932 
933 TooN::Matrix<2, 2> Camera::Quintic::get_inv_derivative() const
934 {
935  TooN::Matrix<2, 2> result = TooN::Identity;
936  TooN::DefaultPrecision temp1 = my_last_camframe * my_last_camframe;
937  TooN::DefaultPrecision temp2 = my_camera_parameters[5] * temp1;
938  TooN::DefaultPrecision temp3 = 2 * (my_camera_parameters[4] + 2 * temp2);
939 
940  result *= 1 + temp1 * (my_camera_parameters[4] + temp2);
941 
942  result[0][0] += my_last_camframe[1] * my_last_camframe[1] * temp3;
943  result[0][1] = -(temp3 * my_last_camframe[0] * my_last_camframe[1]);
944 
945  result[1][1] += my_last_camframe[0] * my_last_camframe[0] * temp3;
946  result[1][0] = -(temp3 * my_last_camframe[0] * my_last_camframe[1]);
947 
948  (result.T())[0] *= my_camera_parameters[1];
949  (result.T())[1] *= my_camera_parameters[0];
950 
951  result /= (result[0][0] * result[1][1] - result[1][0] * result[0][1]);
952 
953  return result;
954 }
955 
956 TooN::Matrix<2, 2> Camera::Quintic::get_inv_derivative(const TooN::Vector<2>& x) const
957 {
958 
959  TooN::Matrix<2, 2> result = TooN::Identity;
960  TooN::DefaultPrecision temp1 = x * x;
961  TooN::DefaultPrecision temp2 = my_camera_parameters[5] * temp1;
962  TooN::DefaultPrecision temp3 = 2 * (my_camera_parameters[4] + 2 * temp2);
963 
964  result *= 1 + temp1 * (my_camera_parameters[4] + temp2);
965  //Identity(result,1+temp1*(my_camera_parameters[4]+temp2));
966 
967  result[0][0] += x[1] * x[1] * temp3;
968  result[0][1] = -(temp3 * x[0] * x[1]);
969 
970  result[1][1] += x[0] * x[0] * temp3;
971  result[1][0] = -(temp3 * x[0] * x[1]);
972 
973  (result.T())[0] *= my_camera_parameters[1];
974  (result.T())[1] *= my_camera_parameters[0];
975 
976  result /= (result[0][0] * result[1][1] - result[1][0] * result[0][1]);
977 
978  return result;
979 }
980 
981 TooN::Matrix<2, 2> Camera::Quintic::get_derivative(const TooN::Vector<2>& x) const
982 {
983  TooN::Matrix<2, 2> result = TooN::Identity;
984  TooN::DefaultPrecision temp1 = x * x;
985  TooN::DefaultPrecision temp2 = my_camera_parameters[5] * temp1;
986  result *= 1 + temp1 * (my_camera_parameters[4] + temp2);
987  //Identity(result,1+temp1*(my_camera_parameters[4]+temp2));
988  result += (2 * (my_camera_parameters[4] + 2 * temp2) * x.as_col()) * x.as_row();
989  result[0] *= my_camera_parameters[0];
990  result[1] *= my_camera_parameters[1];
991  return result;
992 }
993 
994 TooN::Matrix<Camera::Quintic::num_parameters, 2> Camera::Quintic::get_parameter_derivs() const
995 {
996  TooN::Matrix<num_parameters, 2> result;
997  TooN::DefaultPrecision r2 = my_last_camframe * my_last_camframe;
998  TooN::DefaultPrecision r4 = r2 * r2;
999  TooN::Vector<2> mod_camframe = my_last_camframe * (1 + r2 * (my_camera_parameters[4] + r2 * my_camera_parameters[5]));
1000 
1001  result(0, 0) = mod_camframe[0];
1002  result(1, 0) = 0;
1003  result(2, 0) = 1;
1004  result(3, 0) = 0;
1005  result(4, 0) = my_camera_parameters[0] * my_last_camframe[0] * r2;
1006  result(5, 0) = my_camera_parameters[0] * my_last_camframe[0] * r4;
1007 
1008  result(0, 1) = 0;
1009  result(1, 1) = mod_camframe[1];
1010  result(2, 1) = 0;
1011  result(3, 1) = 1;
1012  result(4, 1) = my_camera_parameters[1] * my_last_camframe[1] * r2;
1013  result(5, 1) = my_camera_parameters[1] * my_last_camframe[1] * r4;
1014 
1015  //cout<<"Finish me!\n";
1016  return result;
1017 }
1018 
1019 TooN::Vector<Camera::Quintic::num_parameters> Camera::Quintic::get_parameter_derivs(const TooN::Vector<2>& direction) const
1020 {
1021  //TooN::Vector<num_parameters> result;
1022  //cout<<"Finish me!\n";
1023  //FIXME improve this somewhat
1024  return get_parameter_derivs() * direction;
1025 }
1026 
1027 void Camera::Quintic::update(const TooN::Vector<num_parameters>& updates)
1028 {
1029  TooN::DefaultPrecision fu = my_camera_parameters[0];
1030  TooN::DefaultPrecision fv = my_camera_parameters[1];
1031 
1032  my_camera_parameters[0] += updates[0] * fu;
1033  my_camera_parameters[1] += updates[1] * fv;
1034  my_camera_parameters[2] += updates[2] * fu;
1035  my_camera_parameters[3] += updates[3] * fv;
1036  my_camera_parameters[4] += updates[4];
1037  my_camera_parameters[5] += updates[5];
1038 }
1039 }
1040 #endif
TooN::Vector< num_parameters > & get_parameters()
Returns the vector of camera parameters in the format .
Definition: camera.h:107
TooN::Vector< 2 > unproject(const TooN::Vector< 2 > &imframe) const
Project from image plane to a Euclidean camera.
Definition: camera.h:777
TooN::Vector< num_parameters > & get_parameters()
Returns the vector of camera parameters in the format .
Definition: camera.h:233
TooN::Vector< 2 > unproject(const TooN::Vector< 2 > &imframe) const
Project from image plane to a Euclidean camera.
Definition: camera.h:50
void save(std::ostream &os) const
Save parameters to a stream.
Definition: camera.h:855
TooN::Matrix< 2, 2 > get_derivative() const
Get the derivative of image frame wrt camera frame at the last computed projection in the form ...
Definition: camera.h:459
All classes and functions are within the CVD namespace.
Definition: argb.h:6
TooN::Vector< num_parameters > & get_parameters()
Update the internal camera parameters by adding the vector given.
Definition: camera.h:529
void save(std::ostream &os) const
Save parameters to a stream.
Definition: camera.h:761
void save(std::ostream &os) const
Save parameters to a stream.
Definition: camera.h:582
void load(std::istream &is)
Load parameters from a stream.
Definition: camera.h:277
void update(const TooN::Vector< num_parameters > &updates)
Update the internal camera parameters by adding the vector given.
Definition: camera.h:1027
TooN::Vector< 2 > linearproject(const TooN::Vector< 2 > &camframe, TooN::DefaultPrecision scale=1) const
Fast linear projection for working out what&#39;s there.
Definition: camera.h:588
TooN::Vector< num_parameters > & get_parameters()
Update the internal camera parameters by adding the vector given.
Definition: camera.h:389
TooN::Vector< num_parameters > get_parameter_derivs(const TooN::Vector< 2 > &pos, const TooN::Vector< 2 > &direction) const
Get the component of the motion of a point in the direction provided with respect to each of the inte...
Definition: camera.h:822
TooN::Matrix< 2, 2 > get_derivative_at(const TooN::Vector< 2 > &) const
Get the derivative of image frame wrt camera frame in the form .
Definition: camera.h:60
static const int num_parameters
The number of parameters in the camera.
Definition: camera.h:24
void load(std::istream &is)
Load parameters from a stream.
Definition: camera.h:575
TooN::Matrix< 2, 2 > get_derivative() const
Get the derivative of image frame wrt camera frame at the last computed projection in the form ...
Definition: camera.h:921
This camera class is a very similar to the Harris model.
Definition: camera.h:404
TooN::Vector< 2 > unproject(const TooN::Vector< 2 > &imframe) const
Project from image plane to a Euclidean camera.
Definition: camera.h:446
TooN::Vector< 2 > linearproject(const TooN::Vector< 2 > &camframe, TooN::DefaultPrecision scale=1) const
Fast linear projection for working out what&#39;s there.
Definition: camera.h:290
TooN::Vector< num_parameters > get_parameter_derivs(const TooN::Vector< 2 > &pos, const TooN::Vector< 2 > &direction) const
Get the component of the motion of a point in the direction provided with respect to each of the inte...
Definition: camera.h:72
TooN::Vector< 2 > project(const TooN::Vector< 2 > &camframe) const
Project from Euclidean camera frame to image plane.
Definition: camera.h:296
TooN::Matrix< 2, 2 > get_derivative_at(const TooN::Vector< 2 > &) const
Get the derivative of image frame wrt camera frame at the last computed projection in the form ...
Definition: camera.h:796
TooN::Vector< 2 > project(const TooN::Vector< 2 > &camframe) const
Project from Euclidean camera frame to image plane.
Definition: camera.h:594
void save(std::ostream &os) const
Save parameters to a stream.
Definition: camera.h:427
TooN::Vector< num_parameters > get_parameter_derivs(const TooN::Vector< 2 > &direction) const
Get the component of the motion of a point in the direction provided with respect to each of the inte...
Definition: camera.h:517
A Camera for lenses which attempt to maintain a constant view angle per pixel.
Definition: camera.h:549
TooN::Vector< num_parameters > get_parameter_derivs(const TooN::Vector< 2 > &pos, const TooN::Vector< 2 > &direction) const
Get the component of the motion of a point in the direction provided with respect to each of the inte...
Definition: camera.h:690
void load(std::istream &is)
Load parameters from a stream.
Definition: camera.h:28
TooN::Vector< 2 > linearproject(const TooN::Vector< 2 > &camframe, TooN::DefaultPrecision scale=1) const
Fast linear projection for working out what&#39;s there.
Definition: camera.h:433
TooN::Vector< 2 > linearproject(const TooN::Vector< 2 > &camframe, TooN::DefaultPrecision scale=1) const
Fast linear projection for working out what&#39;s there.
Definition: camera.h:860
TooN::Matrix< 2, 2 > get_derivative_at(const TooN::Vector< 2 > &pt) const
Evaluate the derivative of image frame wrt camera frame at an arbitrary point pt. ...
Definition: camera.h:316
A Camera with zero skew and Harris distortion.
Definition: camera.h:261
void save(std::ostream &os) const
Save parameters to a stream.
Definition: camera.h:34
void save(std::ostream &os) const
Save parameters to a stream.
Definition: camera.h:284
void load(std::istream &is)
Load parameters from a stream.
Definition: camera.h:420
TooN::Vector< 2 > project_vector(const TooN::Vector< 2 > &x, const TooN::Vector< 2 > &d) const
Project from Euclidean camera frame to image plane.
Definition: camera.h:180
TooN::Vector< num_parameters > & get_parameters()
Update the internal camera parameters by adding the vector given.
Definition: camera.h:702
TooN::Matrix< num_parameters, 2 > get_parameter_derivs_at(const TooN::Vector< 2 > &pt) const
Evaluate the derivative of the image coordinates of a given point pt in camera coordinates with respe...
Definition: camera.h:647
TooN::Matrix< num_parameters, 2 > get_parameter_derivs() const
Get the motion of a point with respect to each of the internal camera parameters. ...
Definition: camera.h:481
void update(const TooN::Vector< num_parameters > &updates)
Update the internal camera parameters by adding the vector given.
Definition: camera.h:834
A camera with zero skew and cubic distortion.
Definition: camera.h:116
TooN::Matrix< 2, 2 > get_derivative(const TooN::Vector< 2 > &pt) const
Evaluate the derivative of image frame wrt camera frame at an arbitrary point pt. ...
Definition: camera.h:630
A camera with zero skew and quintic distortion.
Definition: camera.h:163
An adapter to make old-style cameras which remember the last projected point.
Definition: camera.h:720
TooN::Matrix< num_parameters, 2 > get_parameter_derivs() const
Get the motion of a point with respect to each of the internal camera parameters. ...
Definition: camera.h:994
const TooN::Vector< num_parameters > & get_parameters() const
Returns the vector of camera parameters in the format .
Definition: camera.h:230
TooN::Matrix< num_parameters, 2 > get_parameter_derivs_at(const TooN::Vector< 2 > &pt) const
Evaluate the derivative of the image coordinates of a given point pt in camera coordinates with respe...
Definition: camera.h:340
TooN::Vector< 2 > linearproject(const TooN::Vector< 2 > &camframe, TooN::DefaultPrecision scale=1) const
Fast linear projection for working out what&#39;s there.
Definition: camera.h:766
TooN::Vector< 2 > linearproject(const TooN::Vector< 2 > &camframe, TooN::DefaultPrecision scale) const
Fast linear projection for working out what&#39;s there.
Definition: camera.h:40
TooN::Vector< 2 > project(const TooN::Vector< 2 > &camframe) const
Project from Euclidean camera frame to image plane.
Definition: camera.h:45
TooN::Vector< 2 > unproject(const TooN::Vector< 2 > &imframe) const
Project from image plane to a Euclidean camera.
Definition: camera.h:882
TooN::Vector< 2 > project(const TooN::Vector< 2 > &camframe) const
Project from Euclidean camera frame to image plane.
Definition: camera.h:771
TooN::Vector< 2 > unproject(const TooN::Vector< 2 > &imframe) const
Project from image plane to a Euclidean camera.
Definition: camera.h:600
void update(const TooN::Vector< num_parameters > &updates)
Update the internal camera parameters by adding the vector given.
Definition: camera.h:100
Definition: Camera.h:7
TooN::Vector< num_parameters > get_parameter_derivs(const TooN::Vector< 2 > &position, const TooN::Vector< 2 > &direction) const
Get the component of the motion of a point in the direction provided with respect to each of the inte...
Definition: camera.h:377
TooN::Vector< 2 > project(const TooN::Vector< 2 > &camframe) const
Project from Euclidean camera frame to image plane.
Definition: camera.h:439
void load(std::istream &is)
Load parameters from a stream.
Definition: camera.h:850
TooN::Vector< 2 > unproject(const TooN::Vector< 2 > &imframe) const
Project from image plane to a Euclidean camera.
Definition: camera.h:302
void load(std::istream &is)
Load parameters from a stream.
Definition: camera.h:756
TooN::Vector< num_parameters > & get_parameters()
Returns the vector of camera parameters in the format .
Definition: camera.h:154
A linear camera with zero skew.
Definition: camera.h:20