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