vpgl_proj_camera.h
Go to the documentation of this file.
1 // This is core/vpgl/vpgl_proj_camera.h
2 #ifndef vpgl_proj_camera_h_
3 #define vpgl_proj_camera_h_
4 //:
5 // \file
6 // \brief A camera model using the standard 3x4 matrix representation.
7 // \author Thomas Pollard
8 // \date January 28, 2005
9 // \author Joseph Mundy, Matt Leotta, Vishal Jain
10 //
11 // \verbatim
12 // Modifications
13 // May 6, 2005 Ricardo Fabbri Added binary I/O
14 // March 14, 2010 J.L. Mundy made some methods virtual to handle affine case
15 // \endverbatim
16 //
17 // This is the most general camera class based around the 3x4 matrix camera model.
18 // In reality the 3x4 matrix should be rank 3, but this is only checked when an action
19 // needing an SVD decomposition is called, and only gives a warning.
20 //
21 // Once the camera is constructed, the camera matrix can only be accessed through
22 // the "get_matrix" and "set_matrix" functions. These are also the only ways for
23 // subclasses to access the matrix, as the automatic SVD handling is done in them.
24 //
25 // Some camera operations require an SVD decomposition of the camera matrix. When
26 // such a function is first called, an SVD is automatically computed and cached for
27 // all future calls. When the camera matrix is changed by "set_matrix", the cached SVD
28 // is automatically nulled and will only be recomputed when another function that
29 // needs it is called. The SVD can be viewed at any time via the "svd" function.
30 //
31 // Only elementary methods on the camera are included in the class itself. In addition,
32 // there several external functions at the end of the file for important camera operations
33 // deemed too specialized to be included in the vpgl_proj_camera class itself. Some
34 // functions lifted from vgl_p_matrix.h.
35 //
36 // NOTE FOR DEVELOPERS: If you write any member functions that change the
37 // underlying matrix P_ you should call set_matrix to change it, rather than
38 // changing P_ itself. The automatic SVD caching will be screwed up otherwise.
39 
40 #include <iosfwd>
41 #include <vnl/vnl_fwd.h>
42 #include <vgl/vgl_fwd.h>
43 #include <vnl/vnl_matrix_fixed.h>
44 #include <vnl/algo/vnl_svd.h>
45 #include <vgl/vgl_homg_point_3d.h>
46 #include <vgl/vgl_homg_point_2d.h>
50 #include <vgl/vgl_homg_line_2d.h>
51 #include <vgl/vgl_line_2d.h>
53 #include <vgl/vgl_homg_plane_3d.h>
56 #ifdef _MSC_VER
57 # include <vcl_msvc_warnings.h>
58 #endif
59 
60 
61 
62 #include "vpgl_camera.h"
63 
64 template <class T>
66 
67 
68 template <class T>
69 class vpgl_proj_camera : public vpgl_camera<T>
70 {
71  public:
72  // ----------------- Constructors:----------------------
73 
74  //: Default constructor makes an identity camera.
76 
77  //: Construct from a vnl_matrix.
78  vpgl_proj_camera( const vnl_matrix_fixed<T,3,4>& camera_matrix );
79 
80  //: Construct from an array. The array should be in the order row1, row2, row3.
81  vpgl_proj_camera( const T* camera_matrix );
82 
83  //: Copy constructor.
84  vpgl_proj_camera( const vpgl_proj_camera& cam );
85 
86  std::string type_name() const override { return "vpgl_proj_camera"; }
87 
88  //: Clone `this': creation of a new object and initialization
89  // See Prototype pattern
90  virtual vpgl_proj_camera<T>* clone(void) const;
91 
92  //: Assignment.
93  const vpgl_proj_camera<T>& operator=( const vpgl_proj_camera& cam );
94 
95  ~vpgl_proj_camera() override;
96 
97  //: Equality test
98  inline bool operator==(vpgl_proj_camera<T> const &that) const
99  { return this == &that || this->get_matrix()==that.get_matrix(); }
100 
101  // ----------------- Projections and Backprojections:------------------------
102 
103  //: Projection from base class
104  void project(const T x, const T y, const T z, T& u, T& v) const override;
105 
106  //: Project a point in world coordinates onto the image plane.
107  virtual vgl_homg_point_2d<T> project( const vgl_homg_point_3d<T>& world_point ) const;
108 
109  //: Non-homogeneous version of the above.
110  vgl_homg_point_2d<T> project( const vgl_point_3d<T>& world_point ) const {
111  return project( vgl_homg_point_3d<T>( world_point ) ); }
112 
113  //: A shortcut to the above function.
115  return this->project( world_point ); }
116 
117  //: Project a line in the world onto a line in the image plane.
118  vgl_line_segment_2d<T> project( const vgl_line_segment_3d<T>& world_line ) const;
119 
120  //: Standard () forward projection operator
122  { return project( world_line ); }
123 
124  //: Project an infinite line in the world onto an infinite line in the image plane.
125  vgl_line_2d<T> project( const vgl_infinite_line_3d<T>& world_line ) const;
126 
127  //: Standard () forward projection operator
129  { return project( world_line ); }
130 
131  //: Find the 3d ray that goes through the camera center and the provided image point.
132  virtual vgl_ray_3d<T> backproject_ray( const vgl_homg_point_2d<T>& image_point ) const;
133 
134  //: Find the 3d ray that goes through the camera center and the provided image point.
135  virtual vgl_homg_line_3d_2_points<T> backproject( const vgl_homg_point_2d<T>& image_point ) const;
136 
137  //: Find the 3d plane that contains the camera center and the provided line in the image plane.
138  vgl_homg_plane_3d<T> backproject( const vgl_homg_line_2d<T>& image_line ) const;
139 
140  // --------------------- Misc Camera Functions:-------------------
141 
142  //: Find the 3d coordinates of the center of the camera.
143  virtual vgl_homg_point_3d<T> camera_center() const;
144 
145  //: Find the world plane parallel to the image plane intersecting the camera center.
147 
148  //: Find the image coordinates of the vanishing points of the world coordinate axes.
149  vgl_homg_point_2d<T> x_vanishing_point() const{ return vgl_homg_point_2d<T>( P_(0,0), P_(1,0), P_(2,0) ); }
150  vgl_homg_point_2d<T> y_vanishing_point() const{ return vgl_homg_point_2d<T>( P_(0,1), P_(1,1), P_(2,1) ); }
151  vgl_homg_point_2d<T> z_vanishing_point() const{ return vgl_homg_point_2d<T>( P_(0,2), P_(1,2), P_(2,2) ); }
152 
153  // --------------------- Getters and Setters:---------------------
154 
155  //: Return a copy of the camera matrix.
156  const vnl_matrix_fixed<T,3,4>& get_matrix() const{ return P_; }
157 
158  //: Get a copy of the svd of the get_matrix.
159  // The svd is cached when first computed and automatically recomputed when the matrix is changed.
160  vnl_svd<T>* svd() const;
161 
162  //: Setters mirror the constructors and return true if the setting was successful.
163  // In subclasses these should be redefined so that they won't allow setting of
164  // matrices with improper form.
165  virtual bool set_matrix( const vnl_matrix_fixed<T,3,4>& new_camera_matrix );
166  virtual bool set_matrix( const T* new_camera_matrix ); // i.e., T new_camera_matrix[12]
167 
168  // --------------------- I/O :---------------------
169 
170  //: Save in ascii format
171  virtual void save(std::string cam_path);
172 
173  private:
174  //: The internal representation of the get_matrix.
175  // It is private so subclasses will need to access it through "get_matrix" and "set_matrix".
177 
179 };
180 
181 
182 // External Functions:-------------------------------------------------------------
183 
184 //: Return the 3D H-matrix s.t. P * H = [I 0].
185 template <class T>
187 
188 //: Scale the camera matrix so determinant of first 3x3 is 1.
189 template <class T>
190 void fix_cheirality( vpgl_proj_camera<T>& camera );
191 
192 //: Set the camera matrix to [ I | 0 ].
193 template <class T>
194 void make_canonical( vpgl_proj_camera<T>& camera );
195 
196 //: Pre-multiply this projection matrix with a 2-d projective transform.
197 template <class T>
199  const vnl_matrix_fixed<T,3,3>& transform );
200 
201 //: Pre-multiply this projection matrix with a 2-d projective transform.
202 template <class T>
204  const vgl_h_matrix_2d<T>& transform )
205 {
206  return premultiply(in_camera, transform.get_matrix());
207 }
208 
209 
210 //: Post-multiply this projection matrix with a 3-d projective transform.
211 template <class T>
213  const vnl_matrix_fixed<T,4,4>& transform );
214 
215 //: Post-multiply this projection matrix with a 3-d projective transform.
216 template <class T>
218  const vgl_h_matrix_3d<T>& transform )
219 {
220  return postmultiply(in_camera, transform.get_matrix());
221 }
222 //: Linearly intersect two camera rays to form a 3-d point
223 template <class T>
225  const vgl_point_2d<T>& x1,
226  const vpgl_proj_camera<T>& c2,
227  const vgl_point_2d<T>& x2);
228 
229 //: Compute the image projection Jacobians at each point
230 // The returned matrices map a differential change in 3D
231 // to a differential change in the 2D image at each specified 3D point
232 template <class T>
233 std::vector<vnl_matrix_fixed<T,2,3> >
235  const std::vector<vgl_point_3d<T> >& pts);
236 
237 
238 // I/O ---
239 
240 //: Write vpgl_perspective_camera to stream
241 template <class Type>
242 std::ostream& operator<<(std::ostream& s, vpgl_proj_camera<Type> const& p);
243 
244 //: Read vpgl_perspective_camera from stream
245 template <class Type>
246 std::istream& operator>>(std::istream& s, vpgl_proj_camera<Type>& p);
247 
248 #endif // vpgl_proj_camera_h_
bool operator==(vpgl_proj_camera< T > const &that) const
Equality test.
virtual vgl_homg_plane_3d< T > principal_plane() const
Find the world plane parallel to the image plane intersecting the camera center.
void make_canonical(vpgl_proj_camera< T > &camera)
Set the camera matrix to [ I | 0 ].
vnl_matrix_fixed< T, 3, 3 > const & get_matrix() const
vnl_svd< T > * svd() const
Get a copy of the svd of the get_matrix.
~vpgl_proj_camera() override
std::vector< vnl_matrix_fixed< T, 2, 3 > > image_jacobians(const vpgl_proj_camera< T > &camera, const std::vector< vgl_point_3d< T > > &pts)
Compute the image projection Jacobians at each point.
std::istream & operator>>(std::istream &is, vpgl_local_rational_camera< T > &p)
Read from stream.
vnl_matrix_fixed< T, 3, 4 > P_
The internal representation of the get_matrix.
void project(const T x, const T y, const T z, T &u, T &v) const override
Projection from base class.
vpgl_proj_camera< T > premultiply(const vpgl_proj_camera< T > &in_camera, const vnl_matrix_fixed< T, 3, 3 > &transform)
Pre-multiply this projection matrix with a 2-d projective transform.
vgl_homg_point_2d< T > x_vanishing_point() const
Find the image coordinates of the vanishing points of the world coordinate axes.
virtual vpgl_proj_camera< T > * clone(void) const
Clone ‘this’: creation of a new object and initialization.
vgl_line_segment_2d< T > operator()(const vgl_line_segment_3d< T > &world_line) const
Standard () forward projection operator.
vgl_point_3d< T > triangulate_3d_point(const vpgl_proj_camera< T > &c1, const vgl_point_2d< T > &x1, const vpgl_proj_camera< T > &c2, const vgl_point_2d< T > &x2)
Linearly intersect two camera rays to form a 3-d point.
virtual bool set_matrix(const vnl_matrix_fixed< T, 3, 4 > &new_camera_matrix)
Setters mirror the constructors and return true if the setting was successful.
vnl_svd< T > * cached_svd_
virtual vgl_homg_line_3d_2_points< T > backproject(const vgl_homg_point_2d< T > &image_point) const
Find the 3d ray that goes through the camera center and the provided image point.
vgl_homg_point_2d< T > y_vanishing_point() const
virtual vgl_homg_point_3d< T > camera_center() const
Find the 3d coordinates of the center of the camera.
vgl_homg_point_2d< T > operator()(const vgl_homg_point_3d< T > &world_point) const
A shortcut to the above function.
vpgl_proj_camera< T > postmultiply(const vpgl_proj_camera< T > &in_camera, const vnl_matrix_fixed< T, 4, 4 > &transform)
Post-multiply this projection matrix with a 3-d projective transform.
void fix_cheirality(vpgl_proj_camera< T > &camera)
Scale the camera matrix so determinant of first 3x3 is 1.
A general camera class.
std::ostream & operator<<(std::ostream &s, const vpgl_local_rational_camera< T > &p)
Write to stream.
virtual vgl_ray_3d< T > backproject_ray(const vgl_homg_point_2d< T > &image_point) const
Find the 3d ray that goes through the camera center and the provided image point.
vgl_h_matrix_3d< T > get_canonical_h(vpgl_proj_camera< T > &camera)
Return the 3D H-matrix s.t. P * H = [I 0].
This class implements the perspective camera class as described in Hartley & Zisserman as a finite ca...
const vpgl_proj_camera< T > & operator=(const vpgl_proj_camera &cam)
Assignment.
vnl_matrix_fixed< T, 4, 4 > const & get_matrix() const
const vnl_matrix_fixed< T, 3, 4 > & get_matrix() const
Return a copy of the camera matrix.
virtual void save(std::string cam_path)
Save in ascii format.
vgl_homg_point_2d< T > project(const vgl_point_3d< T > &world_point) const
Non-homogeneous version of the above.
vgl_line_2d< T > operator()(const vgl_infinite_line_3d< T > &world_line) const
Standard () forward projection operator.
vgl_homg_point_2d< T > z_vanishing_point() const
std::string type_name() const override
class identity functions for casting.
vpgl_proj_camera()
Default constructor makes an identity camera.