vgl_h_matrix_3d.h
Go to the documentation of this file.
1 // This is core/vgl/algo/vgl_h_matrix_3d.h
2 #ifndef vgl_h_matrix_3d_h_
3 #define vgl_h_matrix_3d_h_
4 //:
5 // \file
6 // \brief 4x4 3D-to-3D projectivity
7 //
8 // A class to hold a 3D projective transformation matrix
9 // and to perform common operations using it e.g. transfer point.
10 //
11 // \verbatim
12 // Modifications
13 // 22 Oct 2002 - Peter Vanroose - added vgl_homg_point_2d interface
14 // 23 Oct 2002 - Peter Vanroose - using fixed 3x3 matrices throughout
15 // 22 Mar 2003 - J. L. Mundy - prep for moving to vgl
16 // 31 Jul 2010 - Peter Vanroose - made more similar to 1d and 2d variants
17 // 24 Oct 2010 - Peter Vanroose - mutators and setters now return *this
18 // 27 Oct 2010 - Peter Vanroose - moved Doxygen docs from .hxx to .h
19 // 26 Jul 2011 - Peter Vanroose - added correlation(),set_affine(),is_identity()
20 // \endverbatim
21 
22 #include <vector>
23 #include <iosfwd>
24 #include <vnl/vnl_fwd.h> // for vnl_vector_fixed<T,3>
25 #include <vnl/vnl_matrix_fixed.h>
26 #include <vgl/vgl_homg_point_3d.h>
27 #include <vgl/vgl_homg_plane_3d.h>
28 #include <vgl/vgl_pointset_3d.h>
29 #ifdef _MSC_VER
30 # include <vcl_msvc_warnings.h>
31 #endif
32 
33 //:
34 // A class to hold a 3-d projective transformation matrix
35 // and to perform common operations using it e.g. transform point.
36 template <class T>
37 class vgl_h_matrix_3d
38 {
39  protected:
40  vnl_matrix_fixed<T,4,4> t12_matrix_;
41  public:
42  vgl_h_matrix_3d() = default;
43  ~vgl_h_matrix_3d() = default;
44  //: Copy constructor
46  //: Constructor from a 4x4 matrix, and implicit cast from vnl_matrix_fixed<T,4,4>
47  vgl_h_matrix_3d(vnl_matrix_fixed<T,4,4> const& M) : t12_matrix_(M) {}
48  //: Construct an affine vgl_h_matrix_3d from 3x3 M and 3x1 m.
49  vgl_h_matrix_3d(vnl_matrix_fixed<T,3,3> const& M,
50  vnl_vector_fixed<T,3> const& m);
51  //: Constructor from 4x4 row-storage C-array
52  explicit vgl_h_matrix_3d(T const* M) : t12_matrix_(M) {}
53  //: Load from ASCII std::istream.
54  explicit vgl_h_matrix_3d(std::istream& s);
55  //: Load from file
56  explicit vgl_h_matrix_3d(char const* filename);
57  //: Constructor - calculate homography between two sets of 3D points (minimum 5)
58  vgl_h_matrix_3d(std::vector<vgl_homg_point_3d<T> > const& points1,
59  std::vector<vgl_homg_point_3d<T> > const& points2);
60 
61  // Operations----------------------------------------------------------------
62 
63  //: Return the transformed point given by $q = {\tt H} p$
65  //: Return the transformed point given by $q = {\tt H} p$
66  vgl_homg_point_3d<T> operator* (vgl_homg_point_3d<T> const& p) const {return (*this)(p);}
67 
68  bool operator==(vgl_h_matrix_3d<T> const& M) const { return t12_matrix_ == M.get_matrix(); }
69 
70  //: Return the preimage of a transformed plane: $m = {\tt H} l$
74 
75 
76  //: operate directly on Euclidean points for convenience (no ideal points allowed)
77 
79  vgl_homg_point_3d<T> hp(p); return (*this)(hp);}
80 
81  vgl_point_3d<T> operator* (vgl_point_3d<T> const& p) const {return (*this)(p);}
82 
84 
85  //the following require computing the inverse homography
86 
87  //: Return the preimage of a transformed point: $p = {\tt H}^{-1} q$
88  // (requires an inverse)
91 
92  //: Return the transformed plane given by $m = {\tt H}^{-1} l$
93  // (requires an inverse)
95  //: Return the transformed plane given by $m = {\tt H}^{-1} l$
96  // (requires an inverse)
97  vgl_homg_plane_3d<T> operator*(vgl_homg_plane_3d<T> const& l) const { return (*this)(l);}
98 
99  //:composition (*this) * H
102 
103  // Data Access---------------------------------------------------------------
104 
105  //: Return the 4x4 homography matrix
106  vnl_matrix_fixed<T,4,4> const& get_matrix() const { return t12_matrix_; }
107  //: Fill M with contents of the 4x4 homography matrix
108  void get (vnl_matrix_fixed<T,4,4>* M) const;
109  //:
110  // \deprecated use the vnl_matrix_fixed variant instead
111  void get (vnl_matrix<T>* M) const;
112  //: Fill M with contents of the 4x4 homography matrix
113  void get (T* M) const;
114  //: Return an element from the 4x4 homography matrix
115  T get (unsigned int row_index, unsigned int col_index) const;
116  //: Return the inverse homography
118 
119  //: Set an element of the 4x4 homography matrix
120  vgl_h_matrix_3d& set (unsigned int row_index, unsigned int col_index, T value)
121  { t12_matrix_[row_index][col_index]=value; return *this; }
122 
123  //: Set to 4x4 row-stored matrix
124  vgl_h_matrix_3d& set(T const* M);
125  //: Set to given 4x4 matrix
126  vgl_h_matrix_3d& set(vnl_matrix_fixed<T,4,4> const& M);
127 
128  // various affine transformations that set the corresponding parts of the matrix
129 
130  //: initialize the transformation to identity
132  //: set H[0][3] = tx, H[1][3] = ty, and H[2][3] = tz, other elements unaltered
133  vgl_h_matrix_3d& set_translation(T tx, T ty, T tz);
134  //: compose the current transform with a uniform scaling transformation, S.
135  // $S = \left[ \begin{array}{cccc}
136  // s & 0 & 0 & 0 \\%
137  // 0 & s & 0 & 0 \\%
138  // 0 & 0 & s & 0 \\%
139  // 0 & 0 & 0 & 1
140  // \end{array}\right]$ , Ts = S*T.
141  vgl_h_matrix_3d& set_scale(T scale);
142 
143  //: set the transform to a general affine transform matrix
144  // $A = \left[ \begin{array}{ccc}
145  // a00 & a01 & a02 & a03 \\%
146  // a10 & a11 & a12 & a13 \\%
147  // a20 & a21 & a22 & a23 \\%
148  // 0 & 0 & 0 & 1
149  // \end{array}\right]$
150  vgl_h_matrix_3d& set_affine(vnl_matrix_fixed<T,3,4> const& M34);
151 
152  //: Just the upper 3x3 part of the matrix is replaced by a rotation matrix.
153  vgl_h_matrix_3d& set_rotation_matrix(vnl_matrix_fixed<T,3,3> const& R);
154  //: Set to rotation about an axis
155  // Just the upper 3x3 part of the matrix is replaced by a rotation matrix.
156  // rotation angle theta is in radians
157  vgl_h_matrix_3d& set_rotation_about_axis(vnl_vector_fixed<T,3> const& axis, T theta);
158  //: Set to roll, pitch and yaw specified rotation.
159  // - roll is rotation about z
160  // - pitch is rotation about y
161  // - yaw is rotation about x
162  // Just the upper 3x3 part of the matrix is replaced by a rotation matrix.
163  vgl_h_matrix_3d& set_rotation_roll_pitch_yaw(T yaw, T pitch, T roll);
164  //: Set to rotation specified by Euler angles
165  // Just the upper 3x3 part of the matrix is replaced by a rotation matrix.
166  vgl_h_matrix_3d& set_rotation_euler(T rz1, T ry, T rz2);
167 
168  //: set the transformation to a reflection about a plane
170 
171  bool is_rotation() const;
172  bool is_identity() const;
173  bool is_euclidean() const;
174  bool is_affine() const;
175 
176  //: Compute transform to projective basis given five points, no 4 of which coplanar
177  // Transformation to projective basis (canonical frame)
178  // Compute the homography that takes the input set of points to the
179  // canonical frame. The points act as the projective basis for
180  // the canonical coordinate system. In the canonical frame the points
181  // have coordinates:
182  // $\begin{array}{cccc}
183  // p[0] & p[1] & p[2] & p[3] & p[4] \\%
184  // 1 & 0 & 0 & 0 & 1 \\%
185  // 0 & 1 & 0 & 0 & 1 \\%
186  // 0 & 0 & 1 & 0 & 1 \\%
187  // 0 & 0 & 0 & 1 & 1
188  // \end{array}$
189  bool projective_basis(std::vector<vgl_homg_point_3d<T> > const& five_points);
190 
191  //: transformation to projective basis (canonical frame)
192  // Compute the homography that takes the input set of planes to the canonical
193  // frame. The planes act as the dual projective basis for the canonical
194  // coordinate system. In the canonical frame the planes have equations:
195  // x=0; y=0; z=0; w=0; x+y+z+w=0. (The latter plane is the plane at infinity.)
196  bool projective_basis(std::vector<vgl_homg_plane_3d<T> > const& five_planes);
197 
198  // ---------- extract components as transformations ----------
199 
200  //: corresponds to rotation for Euclidean transformations
202  vnl_matrix_fixed<T,3,3> get_upper_3x3_matrix() const;
203 
204  //: corresponds to translation for affine transformations
206  vnl_vector_fixed<T,3> get_translation_vector() const;
207 
208  //: polar decomposition of the upper 3x3 matrix, M = S*R, where S is a symmetric matrix and R is an orthonormal matrix
209  // useful for interpreting affine transformations
210  void polar_decomposition(vnl_matrix_fixed<T, 3, 3>& S, vnl_matrix_fixed<T, 3, 3>& R) const;
211 
212  //: Load H from ASCII file.
213  bool read(std::istream& s);
214  //: Read H from file
215  bool read(char const* filename);
216 };
217 
218 //: Print H on std::ostream
219 template <class T> std::ostream& operator<<(std::ostream& s, vgl_h_matrix_3d<T> const& H);
220 //: Load H from ASCII file.
221 template <class T> std::istream& operator>>(std::istream& s, vgl_h_matrix_3d<T>& H)
222 { H.read(s); return s; }
223 
224 #define VGL_H_MATRIX_3D_INSTANTIATE(T) extern "please include vgl/algo/vgl_h_matrix_3d.hxx first"
225 
226 #endif // vgl_h_matrix_3d_h_
vgl_h_matrix_3d & set_rotation_roll_pitch_yaw(T yaw, T pitch, T roll)
Set to roll, pitch and yaw specified rotation.
bool read(std::istream &s)
Load H from ASCII file.
homogeneous plane in 3D projective space
point in projective 3D space
vgl_h_matrix_3d get_inverse() const
Return the inverse homography.
bool is_affine() const
vgl_h_matrix_3d & set_scale(T scale)
compose the current transform with a uniform scaling transformation, S.
vgl_h_matrix_3d & set_translation(T tx, T ty, T tz)
set H[0][3] = tx, H[1][3] = ty, and H[2][3] = tz, other elements unaltered.
vgl_h_matrix_3d(vnl_matrix_fixed< T, 4, 4 > const &M)
Constructor from a 4x4 matrix, and implicit cast from vnl_matrix_fixed<T,4,4>.
vgl_h_matrix_3d & set_affine(vnl_matrix_fixed< T, 3, 4 > const &M34)
set the transform to a general affine transform matrix.
vgl_h_matrix_3d & set(unsigned int row_index, unsigned int col_index, T value)
Set an element of the 4x4 homography matrix.
vgl_h_matrix_3d(vgl_h_matrix_3d< T > const &M)
Copy constructor.
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
vgl_h_matrix_3d & set_rotation_euler(T rz1, T ry, T rz2)
Set to rotation specified by Euler angles.
Represents a homogeneous 3D point.
Definition: vgl_fwd.h:9
vgl_h_matrix_3d()=default
vnl_matrix_fixed< T, 3, 3 > get_upper_3x3_matrix() const
vgl_homg_point_3d< T > operator()(vgl_homg_point_3d< T > const &p) const
Return the transformed point given by $q = {\tt H} p$.
bool projective_basis(std::vector< vgl_homg_point_3d< T > > const &five_points)
Compute transform to projective basis given five points, no 4 of which coplanar.
vgl_homg_plane_3d< T > correlation(vgl_homg_point_3d< T > const &p) const
vgl_homg_plane_3d< T > preimage(vgl_homg_plane_3d< T > const &l) const
Return the preimage of a transformed plane: $m = {\tt H} l$.
A 3-d pointset.
void get(vnl_matrix_fixed< T, 4, 4 > *M) const
Fill M with contents of the 4x4 homography matrix.
vgl_h_matrix_3d & set_rotation_matrix(vnl_matrix_fixed< T, 3, 3 > const &R)
Just the upper 3x3 part of the matrix is replaced by a rotation matrix.
vnl_vector_fixed< T, 3 > get_translation_vector() const
A class to hold a 3-d projective transformation matrix and to perform common operations using it e....
Definition: vgl_algo_fwd.h:12
Represents a Euclidean 3D plane.
Definition: vgl_fwd.h:23
vgl_point_3d< T > operator()(vgl_point_3d< T > const &p) const
operate directly on Euclidean points for convenience (no ideal points allowed).
bool operator==(vgl_h_matrix_3d< T > const &M) const
vgl_h_matrix_3d & set_identity()
initialize the transformation to identity.
vgl_homg_point_3d< T > operator *(vgl_homg_point_3d< T > const &p) const
Return the transformed point given by $q = {\tt H} p$.
vnl_matrix_fixed< T, 4, 4 > const & get_matrix() const
Return the 4x4 homography matrix.
std::istream & operator>>(std::istream &is, vgl_orient_box_3d< Type > &p)
Read box from stream.
vgl_homg_point_3d< T > get_translation() const
corresponds to translation for affine transformations.
#define l
bool is_identity() const
void polar_decomposition(vnl_matrix_fixed< T, 3, 3 > &S, vnl_matrix_fixed< T, 3, 3 > &R) const
polar decomposition of the upper 3x3 matrix, M = S*R, where S is a symmetric matrix and R is an ortho...
void set_reflection_plane(vgl_plane_3d< double > const &p)
set the transformation to a reflection about a plane.
bool is_euclidean() const
bool is_rotation() const
vgl_h_matrix_3d< T > get_upper_3x3() const
corresponds to rotation for Euclidean transformations.
vgl_h_matrix_3d & set_rotation_about_axis(vnl_vector_fixed< T, 3 > const &axis, T theta)
Set to rotation about an axis.
vnl_matrix_fixed< T, 4, 4 > t12_matrix_
~vgl_h_matrix_3d()=default
vgl_h_matrix_3d(T const *M)
Constructor from 4x4 row-storage C-array.