core/vgl/algo/vgl_h_matrix_1d.txx
Go to the documentation of this file.
00001 // This is core/vgl/algo/vgl_h_matrix_1d.txx
00002 #ifndef vgl_h_matrix_1d_txx_
00003 #define vgl_h_matrix_1d_txx_
00004 
00005 #include "vgl_h_matrix_1d.h"
00006 #include <vgl/vgl_homg_point_1d.h>
00007 #include <vnl/vnl_inverse.h>
00008 #include <vnl/vnl_vector_fixed.h>
00009 #include <vnl/algo/vnl_svd.h>
00010 #include <vcl_cstdlib.h> // for exit()
00011 #include <vcl_fstream.h>
00012 #include <vcl_cassert.h>
00013 # include <vcl_deprecated.h>
00014 
00015 //--------------------------------------------------------------------------------
00016 template <class T>
00017 vgl_h_matrix_1d<T>::vgl_h_matrix_1d(vcl_istream &is)
00018 {
00019   t12_matrix_.read_ascii(is);
00020 }
00021 
00022 template <class T>
00023 vgl_h_matrix_1d<T>::vgl_h_matrix_1d(vcl_vector<vgl_homg_point_1d<T> > const& points1,
00024                                     vcl_vector<vgl_homg_point_1d<T> > const& points2)
00025 {
00026   vnl_matrix<T> W;
00027   assert(points1.size() == points2.size());
00028   unsigned int numpoints = points1.size();
00029   if (numpoints < 3)
00030   {
00031     vcl_cerr << "\nvhl_h_matrix_1d - minimum of 3 points required\n";
00032     vcl_exit(0);
00033   }
00034 
00035   W.set_size(numpoints, 4);
00036 
00037   for (unsigned int i = 0; i < numpoints; i++)
00038   {
00039     T x1 = points1[i].x(), w1 = points1[i].w();
00040     T x2 = points2[i].x(), w2 = points2[i].w();
00041 
00042     W[i][0]=x1*w2;    W[i][1]=w1*w2;
00043     W[i][2]=-x1*x2;   W[i][3]=-w1*x2;
00044   }
00045 
00046   vnl_svd<T> SVD(W);
00047   t12_matrix_ = vnl_matrix_fixed<T,2,2>(SVD.nullvector().data_block()); // 4-dim. nullvector
00048 }
00049 
00050 // == OPERATIONS ==
00051 
00052 template <class T>
00053 vgl_homg_point_1d<T>
00054 vgl_h_matrix_1d<T>::operator()(vgl_homg_point_1d<T> const& p) const
00055 {
00056   vnl_vector_fixed<T,2> v = t12_matrix_ * vnl_vector_fixed<T,2>(p.x(),p.w());
00057   return vgl_homg_point_1d<T>(v[0], v[1]);
00058 }
00059 
00060 template <class T>
00061 vgl_homg_point_1d<T>
00062 vgl_h_matrix_1d<T>::preimage(vgl_homg_point_1d<T> const& q) const
00063 {
00064   vnl_vector_fixed<T,2> v = vnl_inverse(t12_matrix_) * vnl_vector_fixed<T,2>(q.x(),q.w());
00065   return vgl_homg_point_1d<T>(v[0], v[1]);
00066 }
00067 
00068 template <class T>
00069 vgl_h_matrix_1d<T>
00070 vgl_h_matrix_1d<T>::get_inverse() const
00071 {
00072   return vgl_h_matrix_1d<T>(vnl_inverse(t12_matrix_));
00073 }
00074 
00075 //-----------------------------------------------------------------------------
00076 template <class T>
00077 vcl_ostream& operator<<(vcl_ostream& s, vgl_h_matrix_1d<T> const& H)
00078 {
00079   return s << H.get_matrix();
00080 }
00081 
00082 template <class T>
00083 bool vgl_h_matrix_1d<T>::read(vcl_istream& s)
00084 {
00085   t12_matrix_.read_ascii(s);
00086   return s.good() || s.eof();
00087 }
00088 
00089 
00090 template <class T>
00091 vgl_h_matrix_1d<T>::vgl_h_matrix_1d(char const* filename)
00092 {
00093   vcl_ifstream f(filename);
00094   if (!f.good())
00095     vcl_cerr << "vgl_h_matrix_1d::read: Error opening " << filename << vcl_endl;
00096   else
00097     t12_matrix_.read_ascii(f);
00098 }
00099 
00100 template <class T>
00101 bool vgl_h_matrix_1d<T>::read(char const* filename)
00102 {
00103   vcl_ifstream f(filename);
00104   if (!f.good())
00105     vcl_cerr << "vgl_h_matrix_1d::read: Error opening " << filename << vcl_endl;
00106   return read(f);
00107 }
00108 
00109 // == DATA ACCESS ==
00110 
00111 //-----------------------------------------------------------------------------
00112 template <class T>
00113 T vgl_h_matrix_1d<T>::get(unsigned int row_index, unsigned int col_index) const
00114 {
00115   return t12_matrix_.get(row_index, col_index);
00116 }
00117 
00118 template <class T>
00119 void vgl_h_matrix_1d<T>::get(T *H) const
00120 {
00121   for (T const* iter = t12_matrix_.begin(); iter < t12_matrix_.end(); ++iter)
00122     *H++ = *iter;
00123 }
00124 
00125 template <class T>
00126 void vgl_h_matrix_1d<T>::get(vnl_matrix_fixed<T,2,2>* H) const
00127 {
00128   *H = t12_matrix_;
00129 }
00130 
00131 template <class T>
00132 void vgl_h_matrix_1d<T>::get(vnl_matrix<T>* H) const
00133 {
00134   VXL_DEPRECATED("vgl_h_matrix_1d<T>::get(vnl_matrix<T>*) const"); 
00135   *H = t12_matrix_.as_ref(); // size 2x2
00136 }
00137 
00138 template <class T>
00139 vgl_h_matrix_1d<T>&
00140 vgl_h_matrix_1d<T>::set(const T* H)
00141 {
00142   for (T* iter = t12_matrix_.begin(); iter < t12_matrix_.end(); ++iter)
00143     *iter = *H++;
00144   return *this;
00145 }
00146 
00147 template <class T>
00148 vgl_h_matrix_1d<T>&
00149 vgl_h_matrix_1d<T>::set(vnl_matrix_fixed<T,2,2> const& H)
00150 {
00151   t12_matrix_ = H;
00152   return *this;
00153 }
00154 
00155 template <class T>
00156 vgl_h_matrix_1d<T>&
00157 vgl_h_matrix_1d<T>::set_identity()
00158 {
00159   t12_matrix_.set_identity();
00160   return *this;
00161 }
00162 
00163 template <class T>
00164 vgl_h_matrix_1d<T>&
00165 vgl_h_matrix_1d<T>::set_scale(T scale)
00166 {
00167   t12_matrix_[0][0]*=scale;
00168   t12_matrix_[0][1]*=scale;
00169   return *this;
00170 }
00171 
00172 template <class T>
00173 vgl_h_matrix_1d<T>&
00174 vgl_h_matrix_1d<T>::set_translation(T tx)
00175 {
00176   t12_matrix_[0][1] = tx;
00177   return *this;
00178 }
00179 
00180 template <class T>
00181 vgl_h_matrix_1d<T>&
00182 vgl_h_matrix_1d<T>::set_affine(vnl_matrix_fixed<T,1,2> const& M12)
00183 {
00184   for (unsigned r = 0; r<1; ++r)
00185     for (unsigned c = 0; c<2; ++c)
00186       t12_matrix_[r][c] = M12[r][c];
00187   t12_matrix_[1][0] = T(0); t12_matrix_[1][1] = T(1);
00188   return *this;
00189 }
00190 
00191 //-------------------------------------------------------------------
00192 template <class T>
00193 bool vgl_h_matrix_1d<T>::projective_basis(vcl_vector<vgl_homg_point_1d<T> > const& points)
00194 {
00195   if (points.size()!=3)
00196     return false;
00197   vnl_vector_fixed<T,2> p0(points[0].x(), points[0].w());
00198   vnl_vector_fixed<T,2> p1(points[1].x(), points[1].w());
00199   vnl_vector_fixed<T,2> p2(points[2].x(), points[2].w());
00200   vnl_matrix_fixed<T,2,3> point_matrix;
00201   point_matrix.set_column(0, p0);
00202   point_matrix.set_column(1, p1);
00203   point_matrix.set_column(2, p2);
00204 
00205   if (! point_matrix.is_finite() || point_matrix.has_nans())
00206   {
00207     vcl_cerr << "vgl_h_matrix_1d<T>::projective_basis():\n"
00208              << " given points have infinite or NaN values\n";
00209     this->set_identity();
00210     return false;
00211   }
00212   vnl_svd<T> svd1(point_matrix.as_ref(), 1e-8); // size 2x3
00213   if (svd1.rank() < 2)
00214   {
00215     vcl_cerr << "vgl_h_matrix_1d<T>::projective_basis():\n"
00216              << " At least two out of the three points are nearly identical\n";
00217     this->set_identity();
00218     return false;
00219   }
00220 
00221   vnl_matrix_fixed<T,2,2> back_matrix;
00222   back_matrix.set_column(0, p0);
00223   back_matrix.set_column(1, p1);
00224 
00225   vnl_vector_fixed<T,2> scales_vector = vnl_inverse(back_matrix) * p2;
00226 
00227   back_matrix.set_column(0, scales_vector[0] * p0);
00228   back_matrix.set_column(1, scales_vector[1] * p1);
00229 
00230   if (! back_matrix.is_finite() || back_matrix.has_nans())
00231   {
00232     vcl_cerr << "vgl_h_matrix_1d<T>::projective_basis():\n"
00233              << " back matrix has infinite or NaN values\n";
00234     this->set_identity();
00235     return false;
00236   }
00237   this->set(vnl_inverse(back_matrix));
00238   return true;
00239 }
00240 
00241 template <class T>
00242 bool vgl_h_matrix_1d<T>::is_identity() const
00243 {
00244   return t12_matrix_.is_identity();
00245 }
00246 
00247 template <class T>
00248 bool vgl_h_matrix_1d<T>::is_rotation() const
00249 {
00250   // the only 1-D rotation is the identity transformation:
00251   return t12_matrix_.is_identity();
00252 }
00253 
00254 
00255 template <class T>
00256 bool vgl_h_matrix_1d<T>::is_euclidean() const
00257 {
00258   // no translational part, and scale 1:
00259   return t12_matrix_.get(0,0) == (T)1 &&
00260          t12_matrix_.get(1,0) == (T)0 &&
00261          t12_matrix_.get(1,1) == (T)1 ;
00262 }
00263 
00264 
00265 //----------------------------------------------------------------------------
00266 #undef VGL_H_MATRIX_1D_INSTANTIATE
00267 #define VGL_H_MATRIX_1D_INSTANTIATE(T) \
00268 template class vgl_h_matrix_1d<T >; \
00269 template vcl_ostream& operator << (vcl_ostream& s, vgl_h_matrix_1d<T > const& h); \
00270 template vcl_istream& operator >> (vcl_istream& s, vgl_h_matrix_1d<T >& h)
00271 
00272 #endif // vgl_h_matrix_1d_txx_