contrib/oxl/mvl/HMatrix2D.cxx
Go to the documentation of this file.
00001 // This is oxl/mvl/HMatrix2D.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 
00008 #include "HMatrix2D.h"
00009 #include <mvl/HomgOperator2D.h>
00010 #include <vnl/vnl_inverse.h>
00011 #include <vcl_fstream.h>
00012 
00013 //--------------------------------------------------------------
00014 //
00015 //: Default constructor
00016 HMatrix2D::HMatrix2D()
00017 {
00018 }
00019 
00020 //: Copy constructor
00021 HMatrix2D::HMatrix2D(const HMatrix2D& M)
00022 {
00023   t12_matrix_ = M.t12_matrix_;
00024 }
00025 
00026 
00027 //: Constructor from vcl_istream
00028 HMatrix2D::HMatrix2D(vcl_istream& s)
00029 {
00030   t12_matrix_.read_ascii(s);
00031 }
00032 
00033 //: Constructor from file
00034 HMatrix2D::HMatrix2D(char const* filename)
00035 {
00036   vcl_ifstream f(filename);
00037   if (!f.good())
00038     vcl_cerr << "HMatrix2D::read: Error opening " << filename << vcl_endl;
00039   else
00040     t12_matrix_.read_ascii(f);
00041 }
00042 
00043 //--------------------------------------------------------------
00044 //
00045 //: Constructor
00046 HMatrix2D::HMatrix2D(vnl_double_3x3 const& M):
00047   t12_matrix_ (M)
00048 {
00049 }
00050 
00051 //--------------------------------------------------------------
00052 //
00053 //: Constructor
00054 HMatrix2D::HMatrix2D (const double* H)
00055   : t12_matrix_ (H)
00056 {
00057 }
00058 
00059 //: Destructor
00060 HMatrix2D::~HMatrix2D()
00061 {
00062 }
00063 
00064 // == OPERATIONS ==
00065 
00066 //-----------------------------------------------------------------------------
00067 //
00068 //: Return the transformed point given by $ x_2 = {\tt H} x_1 $.
00069 
00070 HomgPoint2D HMatrix2D::transform_to_plane2(const HomgPoint2D& x1) const
00071 {
00072     return HomgPoint2D (t12_matrix_ * x1.get_vector());
00073 }
00074 
00075 
00076 //-----------------------------------------------------------------------------
00077 //
00078 //: Return the transformed line given by $ l_1 = {\tt H}^\top l_2 $.
00079 
00080 HomgLine2D HMatrix2D::transform_to_plane1(const HomgLine2D& l2) const
00081 {
00082   return HomgLine2D(t12_matrix_.transpose() * l2.get_vector());
00083 }
00084 
00085 //-----------------------------------------------------------------------------
00086 //: Return the transformed point $x_1$ given by $x_2 = H \, x_1$.
00087 // Note that this calculates the inverse of $H$ on every call.
00088 
00089 HomgPoint2D HMatrix2D::transform_to_plane1(const HomgPoint2D& x2) const
00090 {
00091   static bool warned = false;
00092   if (! warned) {
00093     vcl_cerr << "HMatrix2D::transform_to_plane1(HomgPoint2D): Warning: calculating inverse matrix\n";
00094     warned = true;
00095   }
00096   vnl_double_3x3 t21_matrix_ = this->get_inverse().get_matrix();
00097   return HomgPoint2D(t21_matrix_ * x2.get_vector());
00098 }
00099 
00100 //-----------------------------------------------------------------------------
00101 //: Return the transformed line $l_2$ given by $l_1=H^\top l_2$.
00102 // Note that this calculates the inverse of $H$ on every call.
00103 
00104 HomgLine2D HMatrix2D::transform_to_plane2(const HomgLine2D& l1) const
00105 {
00106   vcl_cerr << "HMatrix2D::transform_to_plane2(HomgLine2D): Warning: calculating inverse matrix\n";
00107   vnl_double_3x3 t21_matrix_ = this->get_inverse().get_matrix().transpose();
00108   return HomgLine2D(t21_matrix_ * l1.get_vector());
00109 }
00110 
00111 //-----------------------------------------------------------------------------
00112 //: Print H on vcl_ostream
00113 vcl_ostream& operator<<(vcl_ostream& s, const HMatrix2D& h)
00114 {
00115   return s << h.get_matrix();
00116 }
00117 
00118 //: Read H from vcl_istream
00119 vcl_istream& operator >> (vcl_istream& s, HMatrix2D& H)
00120 {
00121   H = HMatrix2D(s);
00122   return s;
00123 }
00124 
00125 //: Read H from vcl_istream
00126 bool HMatrix2D::read(vcl_istream& s)
00127 {
00128   return t12_matrix_.read_ascii(s);
00129 }
00130 
00131 //: Read H from file
00132 bool HMatrix2D::read(char const* filename)
00133 {
00134   vcl_ifstream f(filename);
00135   if (!f.good())
00136     vcl_cerr << "HMatrix2D::read: Error opening " << filename << vcl_endl;
00137   return read(f);
00138 }
00139 
00140 // == DATA ACCESS ==
00141 
00142 //-----------------------------------------------------------------------------
00143 //: Get matrix element at (row_index, col_index)
00144 double HMatrix2D::get (unsigned int row_index, unsigned int col_index) const
00145 {
00146   return t12_matrix_. get (row_index, col_index);
00147 }
00148 
00149 //: Fill H with contents of this
00150 void HMatrix2D::get (double *H) const
00151 {
00152   for (int row_index = 0; row_index < 3; row_index++)
00153     for (int col_index = 0; col_index < 3; col_index++)
00154       *H++ = t12_matrix_. get (row_index, col_index);
00155 }
00156 
00157 //: Fill H with contents of this
00158 void HMatrix2D::get (vnl_matrix<double>* H) const
00159 {
00160   *H = t12_matrix_.as_ref(); // size 3x3
00161 }
00162 
00163 //: Set to identity
00164 void HMatrix2D::set_identity ()
00165 {
00166   t12_matrix_.set_identity();
00167 }
00168 
00169 //: Set to 3x3 row-stored matrix
00170 void HMatrix2D::set (const double *H)
00171 {
00172   for (int row_index = 0; row_index < 3; row_index++)
00173     for (int col_index = 0; col_index < 3; col_index++)
00174       t12_matrix_. put (row_index, col_index, *H++);
00175 }
00176 
00177 //: Set to given vnl_matrix
00178 void HMatrix2D::set (vnl_double_3x3 const& H)
00179 {
00180   t12_matrix_ = H;
00181 }
00182 
00183 //: Return inverse of this homography
00184 HMatrix2D HMatrix2D::get_inverse() const
00185 {
00186   return vnl_inverse(t12_matrix_);
00187 }
00188 
00189 //: Return new axis-aligned bounding box after (x0,y0) -> (x1,y1) have been pre-multiplied by H.
00190 vnl_double_4 HMatrix2D::transform_bounding_box(double /*x0*/, double /*y0*/, double /*x1*/, double /*y1*/)
00191 {
00192   vcl_cerr << "FIXME: HMatrix2D::transform_bounding_box() is not yet implemented\n";
00193   return vnl_double_4();
00194 
00195 #if 0
00196   // Find bbox of transformed image
00197   BoundingBox<double, 2> dest_bbox;
00198   double logo_bbox[][2] = {
00199     {x0, y0},
00200     {x1, y0},
00201     {x0, y1},
00202     {x1, y1}
00203   };
00204   for (int k = 0; k < 4; ++k) {
00205     HomgPoint2D corner(logo_bbox[k][0], logo_bbox[k][1], 1);
00206     corner = (*this) * corner;
00207     double s = 1.0/corner[2];
00208     dest_bbox.update(corner[0]*s, corner[1]*s);
00209   }
00210 
00211   double* min = dest_bbox.get_min();
00212   double* max = dest_bbox.get_max();
00213   return vnl_double_4(min[0], min[1], max[0], max[1]);
00214 #endif
00215 }
00216