1 // This is core/vpgl/vpgl_generic_camera.h
2 #ifndef vpgl_generic_camera_h_
3 #define vpgl_generic_camera_h_
4 //:
5 // \file
6 // \brief The generic camera
7 // \author J.L. Mundy
8 // \date April 10, 2011
9 //
10 //   A generic form of camera projection is defined by a set of 3-d rays
11 //   and a mapping between rays and image coordinates. This model has been
12 //   used to unify various camera types such as fisheye, cadadioptric, etc.
13 //   Although it is possible to encounter cameras where the rays are
14 //   general curves, this class restricts the geometry of a ray to a 3-d line.
15 //   In the generic camera it is not necessary that all the rays intersect
16 //   at a single point as in the projective camera. In this implementation,
17 //   the image-to-ray map is restricted to a 2-d array, even though in general
18 //   the map can be more complex. It is assumed that the ray field is smooth
19 //   so that local derivatives are defined
20 //
21 //   Pixels (point samples, really) are centered at integer values; consequently,
22 //   the leading edge of pixel (0,0) is technically (-0.5, -0.5).
23 
24 // \verbatim
25 //  Modifications <none>
26 // \endverbatim
27 
28 #include <iosfwd>
29 #include <string>
30 #include <vbl/vbl_array_2d.h>
31 #include <vgl/vgl_ray_3d.h>
32 #include <vgl/vgl_point_3d.h>
33 #include "vpgl_camera.h"
34 #ifdef _MSC_VER
35 #  include <vcl_msvc_warnings.h>
36 #endif
37 
38 template <class T>
39 class vpgl_generic_camera : public vpgl_camera<T>
40 {
41  public:
42 
43   vpgl_generic_camera();
44   vpgl_generic_camera( vbl_array_2d<vgl_ray_3d<T> > const& rays);
45   vpgl_generic_camera( std::vector<vbl_array_2d<vgl_ray_3d<T> > > const& rays,
46                                               std::vector<int> nrs,   std::vector<int> ncs  );
47   ~vpgl_generic_camera() override = default;
48 
type_name()49   std::string type_name() const override { return "vpgl_generic_camera"; }
50 
51   //: The generic camera interface. u represents image column, v image row. Finds projection using a pyramid search over the rays and so not particularly efficient.
52   void project(const T x, const T y, const T z, T& u, T& v) const override;
53 
54   //: the number of columns (u coordinate) in the ray image
cols(int level)55   unsigned cols(int level) const {return rays_[level].cols();}
cols()56   unsigned cols() const { return rays_[0].cols();}
57 
58   //: the number of rows (v coordinate) in the ray image
rows(int level)59   unsigned rows(int level) const {return rays_[level].rows();}
rows()60   unsigned rows() const { return rays_[0].rows();}
61 
62   //: the number of pyramid levels
n_levels()63   unsigned n_levels() {return static_cast<unsigned>(n_levels_);}
64 
65   //: the ray corresponding to a given pixel
66   vgl_ray_3d<T> ray(const T u, const T v) const;
67 
68   //: a ray passing through a given 3-d point
69   vgl_ray_3d<T> ray(vgl_point_3d<T> const& p) const;
70 
71   //: the ray index at a given level
rays(int level)72   vbl_array_2d<vgl_ray_3d<T> >& rays(int level) { return rays_[level];}
73 
74   //: the nearest ray origin to the coordinate origin
min_ray_origin()75   vgl_point_3d<T> min_ray_origin() {return min_ray_origin_;}
min_ray_direction()76   vgl_vector_3d<T> min_ray_direction() {return min_ray_direction_;}
77 
78   //: the furthest ray origin from the coordinate origin
max_ray_origin()79   vgl_point_3d<T> max_ray_origin() {return max_ray_origin_;}
max_ray_direction()80   vgl_vector_3d<T> max_ray_direction() {return max_ray_direction_;}
81 
82   //: debug function
83   void print_orig(int level);
84 
85   //: visualization
86   void print_to_vrml(int level, std::ostream& os);
87 
88   //: legal C++ because the return type is covariant with vpgl_camera<T>*
clone()89   vpgl_generic_camera<T> *clone() const override {
90     return new vpgl_generic_camera(*this);
91   }
92 
93  protected:
94   void nearest_ray_to_point(vgl_point_3d<T> const& p,
95                             int& nearest_r, int& nearest_c) const;
96   //: nearest ray at level
97   void nearest_ray(int level, vgl_point_3d<T> const& p,
98                    int start_r, int end_r, int start_c, int end_c,
99                    int& nearest_r, int& nearest_c) const;
100 
101   //: refine the projection to sub pixel
102   void refine_projection(int nearest_c, int nearest_r,
103                          vgl_point_3d<T> const& p, T& u, T& v) const;
104 
105   //: refine ray
106   void refine_ray_at_point(int nearest_c, int nearest_r,
107                            vgl_point_3d<T> const& p,
108                            vgl_ray_3d<T>& ray) const;
109 
110   // === members ===
111 
112   //: ray origin bound to support occlusion reasoning
113   vgl_point_3d<T> min_ray_origin_;
114   vgl_vector_3d<T> min_ray_direction_;
115   //: ray origin bound to support occlusion reasoning
116   vgl_point_3d<T> max_ray_origin_;
117   vgl_vector_3d<T> max_ray_direction_;
118 
119   //: a pyramid data structure for the rays to support efficient projection
120   // (level == 0 is the highest resolution)
121   unsigned long n_levels_;
122   //: num rows at each resolution level
123   std::vector<int> nr_;
124   //: num cols at each resolution level
125   std::vector<int> nc_;
126   //: the pyramid
127   std::vector<vbl_array_2d<vgl_ray_3d<T> > > rays_;
128 };
129 
130 #endif // vpgl_generic_camera_h_
131