vgl_h_matrix_1d.hxx
Go to the documentation of this file.
1 // This is core/vgl/algo/vgl_h_matrix_1d.hxx
2 #ifndef vgl_h_matrix_1d_hxx_
3 #define vgl_h_matrix_1d_hxx_
4 
5 #include <cstdlib>
6 #include <iostream>
7 #include <fstream>
8 #include "vgl_h_matrix_1d.h"
10 #include <vnl/vnl_inverse.h>
11 #include <vnl/vnl_vector_fixed.h>
12 #include <vnl/algo/vnl_svd.h>
13 #include <vcl_compiler_detection.h>
14 #ifdef _MSC_VER
15 # include <vcl_msvc_warnings.h>
16 #endif
17 #include <cassert>
18 # include <vcl_deprecated.h>
19 
20 //--------------------------------------------------------------------------------
21 template <class T>
23 {
24  t12_matrix_.read_ascii(is);
25 }
26 
27 template <class T>
29  std::vector<vgl_homg_point_1d<T> > const& points2)
30 {
31  vnl_matrix<T> W;
32  assert(points1.size() == points2.size());
33  unsigned int numpoints = points1.size();
34  if (numpoints < 3)
35  {
36  std::cerr << "\nvhl_h_matrix_1d - minimum of 3 points required\n";
37  std::exit(0);
38  }
39 
40  W.set_size(numpoints, 4);
41 
42  for (unsigned int i = 0; i < numpoints; i++)
43  {
44  T x1 = points1[i].x(), w1 = points1[i].w();
45  T x2 = points2[i].x(), w2 = points2[i].w();
46 
47  W[i][0]=x1*w2; W[i][1]=w1*w2;
48  W[i][2]=-x1*x2; W[i][3]=-w1*x2;
49  }
50 
51  vnl_svd<T> SVD(W);
52  t12_matrix_ = vnl_matrix_fixed<T,2,2>(SVD.nullvector().data_block()); // 4-dim. nullvector
53 }
54 
55 // == OPERATIONS ==
56 
57 template <class T>
60 {
61  vnl_vector_fixed<T,2> v = t12_matrix_ * vnl_vector_fixed<T,2>(p.x(),p.w());
62  return vgl_homg_point_1d<T>(v[0], v[1]);
63 }
64 
65 template <class T>
68 {
69  vnl_vector_fixed<T,2> v = vnl_inverse(t12_matrix_) * vnl_vector_fixed<T,2>(q.x(),q.w());
70  return vgl_homg_point_1d<T>(v[0], v[1]);
71 }
72 
73 template <class T>
76 {
77  return vgl_h_matrix_1d<T>(vnl_inverse(t12_matrix_));
78 }
79 
80 //-----------------------------------------------------------------------------
81 template <class T>
82 std::ostream& operator<<(std::ostream& s, vgl_h_matrix_1d<T> const& H)
83 {
84  return s << H.get_matrix();
85 }
86 
87 template <class T>
88 bool vgl_h_matrix_1d<T>::read(std::istream& s)
89 {
90  t12_matrix_.read_ascii(s);
91  return s.good() || s.eof();
92 }
93 
94 
95 template <class T>
97 {
98  std::ifstream f(filename);
99  if (!f.good())
100  std::cerr << "vgl_h_matrix_1d::read: Error opening " << filename << std::endl;
101  else
102  t12_matrix_.read_ascii(f);
103 }
104 
105 template <class T>
106 bool vgl_h_matrix_1d<T>::read(char const* filename)
107 {
108  std::ifstream f(filename);
109  if (!f.good())
110  std::cerr << "vgl_h_matrix_1d::read: Error opening " << filename << std::endl;
111  return read(f);
112 }
113 
114 // == DATA ACCESS ==
115 
116 //-----------------------------------------------------------------------------
117 template <class T>
118 T vgl_h_matrix_1d<T>::get(unsigned int row_index, unsigned int col_index) const
119 {
120  return t12_matrix_.get(row_index, col_index);
121 }
122 
123 template <class T>
124 void vgl_h_matrix_1d<T>::get(T *H) const
125 {
126  for (T const* iter = t12_matrix_.begin(); iter < t12_matrix_.end(); ++iter)
127  *H++ = *iter;
128 }
129 
130 template <class T>
131 void vgl_h_matrix_1d<T>::get(vnl_matrix_fixed<T,2,2>* H) const
132 {
133  *H = t12_matrix_;
134 }
135 
136 template <class T>
137 void vgl_h_matrix_1d<T>::get(vnl_matrix<T>* H) const
138 {
139  VXL_DEPRECATED_MACRO("vgl_h_matrix_1d<T>::get(vnl_matrix<T>*) const");
140  *H = t12_matrix_.as_ref(); // size 2x2
141 }
142 
143 template <class T>
146 {
147  for (T* iter = t12_matrix_.begin(); iter < t12_matrix_.end(); ++iter)
148  *iter = *H++;
149  return *this;
150 }
151 
152 template <class T>
154 vgl_h_matrix_1d<T>::set(vnl_matrix_fixed<T,2,2> const& H)
155 {
156  t12_matrix_ = H;
157  return *this;
158 }
159 
160 template <class T>
163 {
164  t12_matrix_.set_identity();
165  return *this;
166 }
167 
168 template <class T>
171 {
172  t12_matrix_[0][0]*=scale;
173  t12_matrix_[0][1]*=scale;
174  return *this;
175 }
176 
177 template <class T>
180 {
181  t12_matrix_[0][1] = tx;
182  return *this;
183 }
184 
185 template <class T>
187 vgl_h_matrix_1d<T>::set_affine(vnl_matrix_fixed<T,1,2> const& M12)
188 {
189  for (unsigned r = 0; r<1; ++r)
190  for (unsigned c = 0; c<2; ++c)
191  t12_matrix_[r][c] = M12[r][c];
192  t12_matrix_[1][0] = T(0); t12_matrix_[1][1] = T(1);
193  return *this;
194 }
195 
196 //-------------------------------------------------------------------
197 template <class T>
199 {
200  if (points.size()!=3)
201  return false;
202  vnl_vector_fixed<T,2> p0(points[0].x(), points[0].w());
203  vnl_vector_fixed<T,2> p1(points[1].x(), points[1].w());
204  vnl_vector_fixed<T,2> p2(points[2].x(), points[2].w());
205  vnl_matrix_fixed<T,2,3> point_matrix;
206  point_matrix.set_column(0, p0);
207  point_matrix.set_column(1, p1);
208  point_matrix.set_column(2, p2);
209 
210  if (! point_matrix.is_finite() || point_matrix.has_nans())
211  {
212  std::cerr << "vgl_h_matrix_1d<T>::projective_basis():\n"
213  << " given points have infinite or NaN values\n";
214  this->set_identity();
215  return false;
216  }
217  vnl_svd<T> svd1(point_matrix.as_ref(), 1e-8); // size 2x3
218  if (svd1.rank() < 2)
219  {
220  std::cerr << "vgl_h_matrix_1d<T>::projective_basis():\n"
221  << " At least two out of the three points are nearly identical\n";
222  this->set_identity();
223  return false;
224  }
225 
226  vnl_matrix_fixed<T,2,2> back_matrix;
227  back_matrix.set_column(0, p0);
228  back_matrix.set_column(1, p1);
229 
230  vnl_vector_fixed<T,2> scales_vector = vnl_inverse(back_matrix) * p2;
231 
232  back_matrix.set_column(0, scales_vector[0] * p0);
233  back_matrix.set_column(1, scales_vector[1] * p1);
234 
235  if (! back_matrix.is_finite() || back_matrix.has_nans())
236  {
237  std::cerr << "vgl_h_matrix_1d<T>::projective_basis():\n"
238  << " back matrix has infinite or NaN values\n";
239  this->set_identity();
240  return false;
241  }
242  this->set(vnl_inverse(back_matrix));
243  return true;
244 }
245 
246 template <class T>
248 {
249  return t12_matrix_.is_identity();
250 }
251 
252 template <class T>
254 {
255  // the only 1-D rotation is the identity transformation:
256  return t12_matrix_.is_identity();
257 }
258 
259 
260 template <class T>
262 {
263  // no translational part, and scale 1:
264  return t12_matrix_.get(0,0) == (T)1 &&
265  t12_matrix_.get(1,0) == (T)0 &&
266  t12_matrix_.get(1,1) == (T)1 ;
267 }
268 
269 
270 //----------------------------------------------------------------------------
271 #undef VGL_H_MATRIX_1D_INSTANTIATE
272 #define VGL_H_MATRIX_1D_INSTANTIATE(T) \
273 template class vgl_h_matrix_1d<T >; \
274 template std::ostream& operator << (std::ostream& s, vgl_h_matrix_1d<T > const& h); \
275 template std::istream& operator >> (std::istream& s, vgl_h_matrix_1d<T >& h)
276 
277 #endif // vgl_h_matrix_1d_hxx_
std::istream & read(std::istream &is)
Read from stream, possibly with formatting.
2x2 line-to-line projectivity
A class to hold a line-to-line projective transformation matrix and to perform common operations usin...
Definition: vgl_algo_fwd.h:10
a point in homogeneous 1-D space, i.e., a homogeneous pair (x,w)
vgl_h_matrix_1d & set_translation(T tx)
set H[0][1] = tx, other elements unaltered.
vgl_h_matrix_1d & set_scale(T scale)
compose the current transform with a uniform scaling transformation, S.
bool is_euclidean() const
std::ostream & operator<<(std::ostream &s, vgl_orient_box_3d< Type > const &p)
Write box to stream.
void get(vnl_matrix_fixed< T, 2, 2 > *M) const
Fill M with contents of the 2x2 homography matrix.
bool projective_basis(std::vector< vgl_homg_point_1d< T > > const &three_points)
transformation to projective basis (canonical frame).
#define v
Definition: vgl_vector_2d.h:74
vgl_h_matrix_1d & set_affine(vnl_matrix_fixed< T, 1, 2 > const &M12)
set the transform to a general affine transform matrix.
vgl_homg_point_1d< T > operator()(vgl_homg_point_1d< T > const &p) const
Return the transformed point given by $q = {\tt H} p$.
vgl_h_matrix_1d & set(T const *M)
Set to 2x2 row-stored matrix.
vnl_matrix_fixed< T, 2, 2 > const & get_matrix() const
Return the 2x2 homography matrix.
bool read(char const *filename)
Read H from file.
vgl_h_matrix_1d & set_identity()
initialize the transformation to identity.
bool is_rotation() const
bool is_identity() const
vgl_h_matrix_1d get_inverse() const
Return the inverse homography.
vgl_homg_point_1d< T > preimage(vgl_homg_point_1d< T > const &q) const
Return the transformed point given by $p = {\tt H}^{-1} q$.
Represents a homogeneous 1-D point, i.e., a homogeneous pair (x,w).
Definition: vgl_fwd.h:7
vgl_h_matrix_1d()=default