vgl_p_matrix.h
Go to the documentation of this file.
1 // This is core/vgl/algo/vgl_p_matrix.h
2 #ifndef vgl_p_matrix_h_
3 #define vgl_p_matrix_h_
4 //:
5 // \file
6 // \brief General 3x4 perspective projection matrix
7 //
8 // A class to hold a perspective projection matrix and use it to
9 // perform common operations e.g. projecting point in 3d space to
10 // its image on the image plane
11 //
12 // \verbatim
13 // Modifications
14 // 01 Jul 1996 AWF Implemented get_focal_point()
15 // 01 Oct 1996 AWF Added caching vnl_svd<double>
16 // 26 Feb 1997 AWF Converted to use vnl_double_3x4
17 // 11 Mar 1997 PVr - Added operator==
18 // 22 Oct 2002 Peter Vanroose - added vgl_homg_point_2d interface
19 // 23 Oct 2002 Peter Vanroose - using fixed 3x4 matrices throughout
20 // 25 May 2003 J.L.M. converted to pure vgl infrastructure and made templated
21 // 25 May 2003 J.L.M. made the interface more consistent with plane projective transformations
22 // 27 Jun 2003 Peter Vanroose - moved doc from .hxx to .h
23 // 27 Jun 2003 Peter Vanroose - implemented 3 NYI methods (get, set, set_rows)
24 // 24 Oct 2010 Peter Vanroose - mutators and setters now return *this
25 // \endverbatim
26 
27 #include <iosfwd>
28 #ifdef _MSC_VER
29 # include <vcl_msvc_warnings.h>
30 #endif
31 
32 #include <vnl/algo/vnl_algo_fwd.h> // for vnl_svd
33 #include <vnl/vnl_matrix.h>
34 #include <vnl/vnl_vector.h>
35 #include <vnl/vnl_matrix_fixed.h>
36 #include <vnl/vnl_vector_fixed.h>
37 #include <vgl/vgl_homg_point_2d.h>
38 #include <vgl/vgl_homg_point_3d.h>
39 #include <vgl/vgl_homg_line_2d.h>
43 #include <vgl/algo/vgl_homg_operators_3d.h> //for p_matrix_ * vgl_homg_point_3d
45 
46 template <class T>
47 class vgl_p_matrix
48 {
49  public:
50 
51  // Constructors/Initializers/Destructors-------------------------------------
52 
53  //: Constructor. Set up a canonical P matrix.
54  vgl_p_matrix();
55  //: Construct by loading from std::istream.
56  // \code
57  // vgl_p_matrix P(cin);
58  // \endcode
59  vgl_p_matrix(std::istream&);
60  //: Construct from row-stored C-array of 12 elements
61  vgl_p_matrix(const T *c_matrix);
62  //: Construct from 3x4 matrix
63  explicit vgl_p_matrix(vnl_matrix_fixed<T, 3, 4> const& P);
64  //: Construct from 3x3 matrix A and vector a. P = [A a].
65  vgl_p_matrix(const vnl_matrix_fixed<T,3,3>& A, const vnl_vector_fixed<T,3>& a)
66  : svd_(nullptr) { set(A,a); }
67  //: Deprecated; use the vnl_matrix_fixed variant instead
68  vgl_p_matrix(const vnl_matrix<T>& A, const vnl_vector<T>& a)
69  : svd_(nullptr) { set(A,a); }
70 
71  vgl_p_matrix(const vgl_p_matrix& P);
72  ~vgl_p_matrix();
73 
74  //: Load from file.
75  // Static method, so you can say
76  // \code
77  // vgl_p_matrix P = vgl_p_matrix::read("file.P");
78  // \endcode
79  static vgl_p_matrix read(const char* filename);
80  //: Load from std::istream
81  static vgl_p_matrix read(std::istream&);
82 
83  // Operations----------------------------------------------------------------
84 
85  //: Return the image point which is the projection of the specified 3D point X
87  //: Return the image point which is the projection of the specified 3D point X
88  vgl_homg_point_2d<T> operator*(vgl_homg_point_3d<T> const& X) const { return (*this)(X); }
89  //: Return the image line which is the projection of the specified 3D line L
91  //: Return the image line which is the projection of the specified 3D line L
92  vgl_homg_line_2d<T> operator*(vgl_homg_line_3d_2_points<T> const& L) const { return (*this)(L);}
93  //: Return the image linesegment which is the projection of the specified 3D linesegment L
95  //: Return the image linesegment which is the projection of the specified 3D linesegment L
96  vgl_line_segment_2d<T> operator*(vgl_line_segment_3d<T> const& L) const{return (*this)(L);}
97  //: Return the 3D point $\vec X$ which is $\vec X = P^+ \vec x$.
98  // Equivalently, the 3D point of smallest norm such that $P \vec X = \vec x$.
99  // Uses svd().
101 
102  //: Return the 3D line which is the backprojection of the specified image point, x.
103  // Uses svd().
105  //: Return the 3D plane which is the backprojection of the specified line l in the image
107 
108  //: post-multiply this projection matrix with a 3-d projective transform
109  vgl_p_matrix<T> postmultiply(vnl_matrix_fixed<T,4,4> const& H) const;
110 
111  //: pre-multiply this projection matrix with a 2-d projective transform
112  vgl_p_matrix<T> premultiply(vnl_matrix_fixed<T,3,3> const& H) const;
113  //: pre-multiply this projection matrix with a 2-d projective transform
114  vgl_p_matrix<T> operator*(vnl_matrix_fixed<T, 3,3> const& C)const{return vgl_p_matrix(C * p_matrix_);}
115 
116  //: Compute the svd of this P and cache it, so that future operations that require it need not recompute it.
117  vnl_svd<T>* svd() const; // mutable const
118  //: Discredit the cached svd.
119  // This is necessary only in order to recover the space used by it if the vgl_p_matrix is not being deleted.
120  void clear_svd() const;
121 
122  //: Return the 3D point representing the focal point of the camera.
123  // Uses svd().
125 
126  //: Return the 3D H-matrix s.t. P * H = [I 0].
127  // If P = [A a], then H = [inv(A) -inv(A)*a; 0 0 0 1];
129  //: Return true iff P is [I 0].
130  // Equality is assumed if the max abs diff is less than tol.
131  bool is_canonical(T tol = 0) const;
132 
133  //: Return true if the 3D point X is behind the camera represented by this P.
134  // This depends on the overall sign of the P matrix having been set correctly,
135  // a la Hartley cheirality paper.
137  //: Change the overall sign of the P matrix.
139  //: Splendid hack that tries to detect if the P is an image-coords P or a normalized P.
140  bool looks_conditioned();
141  //: Scale P so determinant of first 3x3 is 1.
143 
144  // Data Access---------------------------------------------------------------
145 
147 
148  bool operator==(vgl_p_matrix const& p) const { return p_matrix_ == p.get_matrix(); }
149 
150  //: Return the 3x3 matrix and 3x1 column vector of P = [A a].
151  void get(vnl_matrix_fixed<T,3,3>* A, vnl_vector_fixed<T,3>* a) const;
152  //: Deprecated; use the vnl_matrix_fixed variant instead
153  void get(vnl_matrix<T>* A, vnl_vector<T>* a) const;
154 
155  //: Return the rows of P = [a b c]'.
156  void get_rows(vnl_vector<T>* a, vnl_vector<T>* b, vnl_vector<T>* c) const;
157  //: Return the rows of P = [a b c]'.
158  void get_rows(vnl_vector_fixed<T,4>* a, vnl_vector_fixed<T,4>* b, vnl_vector_fixed<T,4>* c) const;
159  //: Set P = [a b c]' from its rows a, b, c.
160  vgl_p_matrix& set_rows(const vnl_vector_fixed<T,4>& a, const vnl_vector_fixed<T,4>& b, const vnl_vector_fixed<T,4>& c);
161 
162  //: Return the element of the matrix at the specified index pair
163  T get(unsigned int row_index, unsigned int col_index) const;
164  //: Return the 3x4 projection matrix in the C-array, c_matrix
165  void get(T *c_matrix) const;
166  //: Return the 3x4 projection matrix in p_matrix
167  void get(vnl_matrix_fixed<T, 3, 4>& p_matrix) const { p_matrix = p_matrix_; }
168  //: Deprecated; use the vnl_matrix_fixed variant instead
169  void get(vnl_matrix<T>& p_matrix) const { p_matrix = p_matrix_.as_ref(); }
170 
171  //: Set the internal matrix using the 3x4 p_matrix.
172  vgl_p_matrix& set(vnl_matrix_fixed<T,3,4> const& p_matrix) { p_matrix_ = p_matrix; clear_svd(); return *this; }
173  //: Deprecated; use the vnl_matrix_fixed variant instead
174  vgl_p_matrix& set(const vnl_matrix<T>& p_matrix) { p_matrix_ = p_matrix; clear_svd(); return *this; }
175  //: Set from 3x3 matrix and 3x1 column vector of P = [A a].
176  vgl_p_matrix& set(vnl_matrix_fixed<T,3,3> const& A, vnl_vector_fixed<T,3> const& a);
177  //: Deprecated; use the vnl_matrix_fixed variant instead
178  vgl_p_matrix& set(vnl_matrix<T> const& A, vnl_vector<T> const& a);
179  //: Set the projective matrix with the matrix in the 3x4 C-array, p_matrix
180  vgl_p_matrix& set(const T* p_matrix);
181  //: Set the projective matrix with the matrix in the 3x4 C-array, p_matrix
182  vgl_p_matrix& set(const T p_matrix [3][4]);
183 
184  const vnl_matrix_fixed<T, 3, 4>& get_matrix() const { return p_matrix_; }
185 
186  //: Set the camera to an identity projection. X->u, Y->v
188 
189  // Utility Methods-----------------------------------------------------------
190 
191  //: Load from file.
192  // \code
193  // P.read_ascii("file.P");
194  // \endcode
195  bool read_ascii(std::istream& f);
196 
197  // Data Members--------------------------------------------------------------
198  protected:
199  vnl_matrix_fixed<T, 3,4> p_matrix_;
200  mutable vnl_svd<T>* svd_;
201 };
202 
203 //: Postmultiply P-matrix P by 3D H-matrix H
204 template <class T>
206 
207 //: Print p on an ostream
208 template <class T> std::ostream& operator<<(std::ostream& s, const vgl_p_matrix<T>& p);
209 //: Load p from an ascii istream
210 template <class T> std::istream& operator>>(std::istream& i, vgl_p_matrix<T>& p);
211 
212 #define VGL_P_MATRIX_INSTANTIATE(T) extern "please include vgl/algo/vgl_p_matrix.hxx first"
213 
214 #endif // vgl_p_matrix_h_
point in projective 3D space
const vnl_matrix_fixed< T, 3, 4 > & get_matrix() const
Definition: vgl_p_matrix.h:184
vgl_homg_point_2d< T > operator *(vgl_homg_point_3d< T > const &X) const
Return the image point which is the projection of the specified 3D point X.
Definition: vgl_p_matrix.h:88
vgl_p_matrix & flip_sign()
Change the overall sign of the P matrix.
Represents a homogeneous 2D line.
Definition: vgl_fwd.h:14
bool is_behind_camera(vgl_homg_point_3d< T > const &)
Return true if the 3D point X is behind the camera represented by this P.
void get(vnl_matrix_fixed< T, 3, 4 > &p_matrix) const
Return the 3x4 projection matrix in p_matrix.
Definition: vgl_p_matrix.h:167
void get(vnl_matrix_fixed< T, 3, 3 > *A, vnl_vector_fixed< T, 3 > *a) const
Return the 3x3 matrix and 3x1 column vector of P = [A a].
bool read_ascii(std::istream &f)
Load from file.
vgl_homg_point_3d< T > get_focal() const
Return the 3D point representing the focal point of the camera.
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
vgl_h_matrix_3d< T > get_canonical_H() const
Return the 3D H-matrix s.t. P * H = [I 0].
line in projective 2D space
bool is_canonical(T tol=0) const
Return true iff P is [I 0].
Represents a homogeneous 3D point.
Definition: vgl_fwd.h:9
void get(vnl_matrix< T > &p_matrix) const
Deprecated; use the vnl_matrix_fixed variant instead.
Definition: vgl_p_matrix.h:169
void clear_svd() const
Discredit the cached svd.
static vgl_p_matrix read(const char *filename)
Load from file.
line segment in 3D nonhomogeneous space
vgl_p_matrix & set(const vnl_matrix< T > &p_matrix)
Deprecated; use the vnl_matrix_fixed variant instead.
Definition: vgl_p_matrix.h:174
vnl_matrix_fixed< T, 3, 4 > p_matrix_
Definition: vgl_p_matrix.h:199
A class to hold a 3-d projective transformation matrix and to perform common operations using it e....
Definition: vgl_algo_fwd.h:12
vgl_p_matrix & operator=(const vgl_p_matrix &)
Represents a 3D line segment using two points.
Definition: vgl_fwd.h:19
vgl_p_matrix()
Constructor. Set up a canonical P matrix.
vgl_p_matrix(const vnl_matrix_fixed< T, 3, 3 > &A, const vnl_vector_fixed< T, 3 > &a)
Construct from 3x3 matrix A and vector a. P = [A a].
Definition: vgl_p_matrix.h:65
vgl_p_matrix & set_identity()
Set the camera to an identity projection. X->u, Y->v.
vgl_p_matrix & set(vnl_matrix_fixed< T, 3, 4 > const &p_matrix)
Set the internal matrix using the 3x4 p_matrix.
Definition: vgl_p_matrix.h:172
vgl_homg_line_3d_2_points< T > backproject(vgl_homg_point_2d< T > const &x) const
Return the 3D line which is the backprojection of the specified image point, x.
point in projective 2D space
vgl_p_matrix & set_rows(const vnl_vector_fixed< T, 4 > &a, const vnl_vector_fixed< T, 4 > &b, const vnl_vector_fixed< T, 4 > &c)
Set P = [a b c]' from its rows a, b, c.
3D homogeneous functions
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
vgl_homg_point_3d< T > backproject_pseudoinverse(vgl_homg_point_2d< T > const &x) const
Return the 3D point $\vec X$ which is $\vec X = P^+ \vec x$.
#define l
bool operator==(vgl_p_matrix const &p) const
Definition: vgl_p_matrix.h:148
vgl_homg_point_1d< T > operator *(vnl_matrix_fixed< T, 2, 2 > const &m, vgl_homg_point_1d< T > const &p)
Transform a point through a 2x2 projective transformation matrix.
vnl_svd< T > * svd_
Definition: vgl_p_matrix.h:200
Represents a homogeneous 2D point.
Definition: vgl_fwd.h:8
4x4 3D-to-3D projectivity
vgl_p_matrix< T > postmultiply(vnl_matrix_fixed< T, 4, 4 > const &H) const
post-multiply this projection matrix with a 3-d projective transform.
vgl_p_matrix(const vnl_matrix< T > &A, const vnl_vector< T > &a)
Deprecated; use the vnl_matrix_fixed variant instead.
Definition: vgl_p_matrix.h:68
bool looks_conditioned()
Splendid hack that tries to detect if the P is an image-coords P or a normalized P.
void get_rows(vnl_vector< T > *a, vnl_vector< T > *b, vnl_vector< T > *c) const
Return the rows of P = [a b c]'.
vgl_p_matrix & fix_cheirality()
Scale P so determinant of first 3x3 is 1.
vgl_homg_point_2d< T > operator()(vgl_homg_point_3d< T > const &X) const
Return the image point which is the projection of the specified 3D point X.
Definition: vgl_p_matrix.h:86
vgl_p_matrix< T > premultiply(vnl_matrix_fixed< T, 3, 3 > const &H) const
pre-multiply this projection matrix with a 2-d projective transform.
Represents a homogeneous 3D line using two points.
Definition: vgl_fwd.h:15
vnl_svd< T > * svd() const
Compute the svd of this P and cache it, so that future operations that require it need not recompute ...