1 // This is core/vpgl/vpgl_affine_camera.h
2 #ifndef vpgl_affine_camera_h_
3 #define vpgl_affine_camera_h_
4 //:
5 // \file
6 // \brief A class for the affine camera model.
7 // \author Thomas Pollard
8 // \date January 28, 2005
9 // \author Joseph Mundy, Matt Leotta, Vishal Jain
10 // \verbatim
11 //  Modifications
12 //  March 14, 2010 J.L. Mundy brought in virtual functions of proj_camera
13 //  that require special treatment for the affine case. Added a default
14 //  viewing distance to allow these methods to construct finite objects when
15 //  the camera center is infinity.
16 //  at infinity.
17 // \endverbatim
18 
19 #include <vnl/vnl_fwd.h>
20 #include <vgl/vgl_fwd.h>
21 #include "vpgl_proj_camera.h"
22 
23 template <class T>
24 class vpgl_affine_camera : public vpgl_proj_camera<T>
25 {
26  public:
27 
28   //: Default constructor creates the canonical affine camera.
29   vpgl_affine_camera();
30 
31   //: Construct from the first two rows.
32   vpgl_affine_camera( const vnl_vector_fixed<T,4>& row1,
33                       const vnl_vector_fixed<T,4>& row2 );
34 
35   //: Construct from the first two rows as a 2x4 matrix.
vpgl_affine_camera(const vnl_matrix_fixed<T,2,4> & camera_matrix)36   vpgl_affine_camera( const vnl_matrix_fixed<T,2,4>& camera_matrix ) {
37     *this = vpgl_affine_camera(camera_matrix.get_row(0), camera_matrix.get_row(1));
38   }
39 
40   //: Construct from a 3x4 matrix, sets the last row to 0001.
41   // The bottom right entry had better not be 0.
42   vpgl_affine_camera( const vnl_matrix_fixed<T,3,4>& camera_matrix );
43 
44   //: Construct from a ray direction, up vector, 3-d stare point: vgl interface
45   // \a p projects to (\a u0, \a v0), \a su and \a sv are calibration scale factors
46   vpgl_affine_camera(vgl_vector_3d<T> ray, vgl_vector_3d<T> up,
47                      vgl_point_3d<T> stare_pt, T u0, T v0, T su, T sv);
48 
49   //: Construct from a ray direction, up vector, 3-d stare point: vnl interface
50   // \a p projects to (\a u0, \a v0), \a su and \a sv are calibration scale factors
vpgl_affine_camera(vnl_vector_fixed<T,3> ray,vnl_vector_fixed<T,3> up,vnl_vector_fixed<T,3> stare_pt,T u0,T v0,T su,T sv)51   vpgl_affine_camera(vnl_vector_fixed<T, 3> ray, vnl_vector_fixed<T, 3> up,
52                      vnl_vector_fixed<T, 3> stare_pt, T u0, T v0, T su, T sv) {
53     vgl_vector_3d<T> ry(ray[0], ray[1], ray[2]), u(up[0], up[1], up[2]);
54     vgl_point_3d<T> pt(stare_pt[0], stare_pt[1], stare_pt[2]);
55     (*this) = vpgl_affine_camera<T>(ry, u, pt, u0, v0, su, sv);
56   }
57 
58   bool set_matrix( const vnl_matrix_fixed<T,3,4>& new_camera_matrix ) override;
59   bool set_matrix( const T* new_camera_matrix ) override; // i.e., T new_camera_matrix[12]
60 
type_name()61   std::string type_name() const override { return "vpgl_affine_camera"; }
62 
63   //: Set the top two rows.
64   void set_rows( const vnl_vector_fixed<T,4>& row1,
65                  const vnl_vector_fixed<T,4>& row2 );
66 
67 
68   // === The following virtual functions require special treatment for the affine camera ===
69 
70   //: set a finite viewing distance to allow the methods below to return finite objects
set_viewing_distance(T dist)71   void set_viewing_distance(T dist) {view_distance_ = dist;}
viewing_distance()72   T viewing_distance() const {return view_distance_;}
73 
74   //: flip the ray direction so that dot product with look_dir is positive
75   void orient_ray_direction(vgl_vector_3d<T> const& look_dir);
76 
77   //: Equality test
78   inline bool operator==(vpgl_affine_camera<T> const &that) const
79   { return this == &that ||
80            (this->get_matrix()==that.get_matrix() &&
81             this->viewing_distance() == that.viewing_distance() );
82   }
83 
84   //: Find the 3d coordinates of the center of the camera. Will be an ideal point with the sense of the ray direction.
85   vgl_homg_point_3d<T> camera_center() const override;
86 
87   //: Find the 3d ray that goes through the camera center.
88   // The finite point of the ray is at the viewing distance from the origin
89    vgl_homg_line_3d_2_points<T> backproject( const vgl_homg_point_2d<T>& image_point ) const override;
90 
91   //: Find the 3d ray that goes through the camera center and the provided image point.
92   vgl_ray_3d<T> backproject_ray( const vgl_homg_point_2d<T>& image_point ) const override;
93 
94   //: Find the world plane perpendicular to the camera rays at viewing distance from the origin
95    vgl_homg_plane_3d<T> principal_plane() const override;
96 
97   //: Clone `this': creation of a new object and initialization
98   // legal C++ because the return type is covariant with vpgl_camera<T>*
99    vpgl_affine_camera<T> *clone() const override;
100 
101    //: the direction of all affine camera rays
ray_dir()102    vgl_vector_3d<T> ray_dir() const { return ray_dir_; }
103 
104  private:
105   T view_distance_; // distance from origin along rays
106   vgl_vector_3d<T> ray_dir_;//needed to assign a consistent sense to the ray
107 };
108 
109 //: Return the 3D H-matrix s.t. A * H = [1 0 0 0]
110 //                                      [0 1 0 0]
111 //                                      [0 0 0 1]
112 template <class T>
113 vgl_h_matrix_3d<T> get_canonical_h( const vpgl_affine_camera<T>& camera );
114 
115 //: compute At = H_3x3 * A
116 //(note the _a suffix is needed to prevent compiler confustion with the parent proj_camera's premultiply)
117 template <class T>
118 vpgl_affine_camera<T> premultiply_a( const vpgl_affine_camera<T>& in_camera,
119                                      const vnl_matrix_fixed<T,3,3>& transform );
120 //: compute At = H_3x3 * A
121 template <class T>
premultiply_a(const vpgl_affine_camera<T> & in_camera,const vgl_h_matrix_2d<T> & transform)122 vpgl_affine_camera<T> premultiply_a( const vpgl_affine_camera<T>& in_camera,
123                                      const vgl_h_matrix_2d<T>& transform ){
124   return premultiply_a(in_camera, transform.get_matrix());
125 }
126 
127 //: compute At = A*H_4x4;
128 template <class T>
129 vpgl_affine_camera<T> postmultiply_a( const vpgl_affine_camera<T>& in_camera,
130                                       const vnl_matrix_fixed<T,4,4>& transform );
131 //: compute At = A*H;
132 template <class T>
postmultiply_a(const vpgl_affine_camera<T> & in_camera,const vgl_h_matrix_3d<T> & transform)133 vpgl_affine_camera<T> postmultiply_a( const vpgl_affine_camera<T>& in_camera,
134                                       const vgl_h_matrix_3d<T>& transform ){
135   return postmultiply_a(in_camera, transform.get_matrix());
136 }
137 
138 //: compute At = A*H, where H is just 3-d translation
139 template <class T>
140 vpgl_affine_camera<T> postmultiply_a( const vpgl_affine_camera<T>& in_camera,
141                                       const vnl_vector_fixed<T,3>& translation );
142 
143 //: compute At = A*H, where H is just 3-d translation
144 template <class T>
postmultiply_a(const vpgl_affine_camera<T> & in_camera,const vgl_vector_3d<T> & translation)145 vpgl_affine_camera<T> postmultiply_a( const vpgl_affine_camera<T>& in_camera,
146                                       const vgl_vector_3d<T>& translation ){
147   vnl_vector_fixed<T, 3> tr(translation.x(), translation.y(), translation.z());
148   return postmultiply_a(in_camera, tr);
149 }
150 
151 //: Read vpgl_affine_camera  from stream
152 template <class Type>
153 std::istream&  operator>>(std::istream& s, vpgl_affine_camera<Type>& c);
154 
155 //: Write vpgl_affine_camera to stream
156 template <class Type>
157 std::ostream&  operator<<(std::ostream& s, vpgl_affine_camera<Type> const& c);
158 
159 #endif // vpgl_affine_camera_h_
160