sbacam.h
Go to the documentation of this file.
00001 // g2o - General Graph Optimization
00002 // Copyright (C) 2011 Kurt Konolige
00003 // 
00004 // g2o is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser General Public License as published
00006 // by the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // g2o is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00027 
00028 #ifndef _SBACam_
00029 #define _SBACam_
00030 
00031 #include "g2o/stuff/misc.h"
00032 #include "g2o/stuff/macros.h"
00033 #include "se3quat.h"
00034 #include <Eigen/Core>
00035 #include <Eigen/Geometry>
00036 
00037 // this seems to have to go outside of the AISNav namespace...
00038 //USING_PART_OF_NAMESPACE_EIGEN;
00039 
00040 namespace g2o {
00041   using namespace Eigen;
00042   typedef  Matrix<double, 6, 1> Vector6d;
00043   
00044   // useful types
00045   //  typedef  Matrix<double, 6, 6> Matrix6d;
00046 
00047   class SBACam: public SE3Quat
00048   {
00049     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00050 
00051    public:
00052     // camera matrix and stereo baseline
00053     Matrix3d Kcam; 
00054     double baseline;
00055 
00056     // transformations
00057     Matrix<double,3,4> w2n; // transform from world to node coordinates
00058     Matrix<double,3,4> w2i; // transform from world to image coordinates
00059 
00060     // Derivatives of the rotation matrix transpose wrt quaternion xyz, used for
00061     // calculating Jacobian wrt pose of a projection.
00062     Matrix3d dRdx, dRdy, dRdz;
00063 
00064     // initialize an object
00065   SBACam()
00066     {
00067       SE3Quat();
00068       setKcam(1,1,0.5,0.5,0);   // unit image projection
00069     }
00070 
00071 
00072     // set the object pose
00073   SBACam(Quaterniond  r_, Vector3d t_) : SE3Quat(r_, t_)
00074     {
00075       setTransform();
00076       setProjection();
00077       setDr();
00078     }
00079 
00080   SBACam(const SE3Quat& p) : SE3Quat(p) {
00081     setTransform();
00082     setProjection();
00083     setDr();
00084   }
00085 
00086     // update from the linear solution
00087     //defined in se3quat
00088     void update(const Vector6d& update)
00089     {
00090       //      std::cout << "UPDATE " << update.transpose() << std::endl;
00091       // position update
00092       _t += update.head(3);
00093       // small quaternion update
00094       Quaterniond qr;
00095       qr.vec() = update.segment<3>(3); 
00096       qr.w() = sqrt(1.0 - qr.vec().squaredNorm()); // should always be positive
00097       _r *= qr;                 // post-multiply
00098       _r.normalize();           
00099       setTransform();
00100       setProjection();
00101       setDr();
00102       //      std::cout << t.transpose() << std::endl;
00103       //      std::cout << r.coeffs().transpose() << std::endl;
00104     }
00105 
00106     // transforms
00107     static void transformW2F(Matrix<double,3,4> &m, 
00108                              const Vector3d &trans, 
00109                              const Quaterniond &qrot)
00110     {
00111       m.block<3,3>(0,0) = qrot.toRotationMatrix().transpose();
00112       m.col(3).setZero();         // make sure there's no translation
00113       Vector4d tt;
00114       tt.head(3) = trans;
00115       tt[3] = 1.0;
00116       m.col(3) = -m*tt;
00117     }
00118 
00119     static void transformF2W(Matrix<double,3,4> &m, 
00120                              const Vector3d &trans, 
00121                              const Quaterniond &qrot)
00122     {
00123       m.block<3,3>(0,0) = qrot.toRotationMatrix();
00124       m.col(3) = trans;
00125     }
00126 
00127     // set up camera matrix
00128     void setKcam(double fx, double fy, double cx, double cy, double tx)
00129     { 
00130       Kcam.setZero();
00131       Kcam(0,0) = fx;
00132       Kcam(1,1) = fy;
00133       Kcam(0,2) = cx;
00134       Kcam(1,2) = cy;
00135       Kcam(2,2) = 1.0;
00136       baseline = tx;
00137       setProjection();
00138       setDr();
00139     }
00140 
00141     // set transform from world to cam coords
00142     void setTransform()  { transformW2F(w2n,_t,_r); }
00143 
00144     // Set up world-to-image projection matrix (w2i), assumes camera parameters
00145     // are filled.
00146     void setProjection() { w2i = Kcam * w2n; }
00147 
00148     // sets angle derivatives
00149     void setDr()
00150     {
00151       // inefficient, just for testing
00152       // use simple multiplications and additions for production code in calculating dRdx,y,z
00153       Matrix3d dRidx, dRidy, dRidz;
00154       dRidx << 0.0,0.0,0.0,  
00155         0.0,0.0,2.0,
00156         0.0,-2.0,0.0;
00157       dRidy  << 0.0,0.0,-2.0,
00158         0.0,0.0,0.0,
00159         2.0,0.0,0.0;
00160       dRidz  << 0.0,2.0,0.0,  
00161         -2.0,0.0,0.0,
00162         0.0,0.0,0.0;
00163 
00164       // for dS'*R', with dS the incremental change
00165       dRdx = dRidx * w2n.block<3,3>(0,0);
00166       dRdy = dRidy * w2n.block<3,3>(0,0);
00167       dRdz = dRidz * w2n.block<3,3>(0,0);
00168     }
00169 
00170   };
00171 
00172 
00173   // human-readable SBACam object
00174   inline std::ostream& operator <<(std::ostream& out_str,
00175                                    const SBACam& cam)
00176   {
00177     out_str << cam.translation().transpose() << std::endl;
00178     out_str << cam.rotation().coeffs().transpose() << std::endl << std::endl;
00179     out_str << cam.Kcam << std::endl << std::endl;
00180     out_str << cam.w2n << std::endl << std::endl;
00181     out_str << cam.w2i << std::endl << std::endl;
00182 
00183     return out_str;
00184   };
00185 
00186 
00187   //
00188   // class for edges from vps to points with normals
00189   //
00190 
00191   class EdgeNormal
00192   {
00193     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00194 
00195    public:
00196     // point position
00197     Vector3d pos;
00198 
00199     // unit normal
00200     Vector3d normal;
00201 
00202     // rotation matrix for normal
00203     Matrix3d R; 
00204 
00205     // initialize an object
00206     EdgeNormal()
00207       {
00208         pos.setZero();
00209         normal << 0, 0, 1;
00210         makeRot();
00211       }
00212 
00213     // set up rotation matrix
00214     void makeRot()
00215     {
00216       Vector3d y;
00217       y << 0, 1, 0;
00218       R.row(2) = normal;
00219       y = y - normal(1)*normal;
00220       y.normalize();            // need to check if y is close to 0
00221       R.row(1) = y;
00222       R.row(0) = normal.cross(R.row(1));
00223       //      cout << normal.transpose() << endl;
00224       //      cout << R << endl << endl;
00225       //      cout << R*R.transpose() << endl << endl;
00226     }
00227 
00228   };
00229 
00230 } // end namespace
00231 
00232 
00233 #endif  // SBACam


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:32:23