contrib/mul/m23d/m23d_ortho_rigid_builder.h
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \author Tim Cootes
00004 // \brief Implementation of the Tomasi & Kanade reconstruction algorithm
00005 
00006 #ifndef m2d3_ortho_rigid_builder_h_
00007 #define m2d3_ortho_rigid_builder_h_
00008 
00009 #include <vnl/vnl_matrix.h>
00010 #include <vcl_vector.h>
00011 
00012 #include <vgl/vgl_point_2d.h>
00013 #include <vgl/vgl_point_3d.h>
00014 
00015 //: Reconstruct 3D point positions given multiple 2D orthographic projections.
00016 //  Implementation of the Tomasi & Kanade reconstruction algorithm.
00017 //  Generates projection matrix, P, and 3D point matrix P3D, such that
00018 //  P2D = P.P3D.  Uncertainty in projection is constrained by setting
00019 //  the projection for the first shape to the identity (1 0 0; 0 1 0)
00020 //
00021 //  The ambiguity in the sign of the z ordinates is fixed by arranging that
00022 //  the first non-zero z ordinate should be negative.
00023 //
00024 //  Note that the 2D point sets will be normalised so that their CoG is
00025 //  at the origin.  The resulting 3D shape will also have its CoG at the origin.
00026 //
00027 // changes by dac (Jan 08)
00028 // - added some extra interface functions
00029 // - added new constraint code
00030 // - added code to ensure poss definite correction matrix
00031 
00032 class m23d_ortho_rigid_builder
00033 {
00034  private:
00035 //===========================private workspace variables========================
00036 
00037   //: 3 x np matrix, each column containing one 3D point
00038   vnl_matrix<double> P3D_;
00039 
00040   //: The 2ns x 3 projection matrix
00041   //  Each 2x3 sub-matrix is a scaled orthographic projection matrix
00042   vnl_matrix<double> P_;
00043 
00044   //: The CoG of each shape supplied to reconstruct()
00045   //  This has been subtracted from each example to centre on the origin
00046   //  Centred data stored in P2Dc_
00047   vcl_vector<vgl_point_2d<double> > cog_;
00048 
00049   //: Centred version of the 2D views supplied to reconstruct()
00050   //  Each 2D shape has been translated so that its CoG is at the origin
00051   vnl_matrix<double> P2Dc_;
00052 
00053 //=============================private functions================================
00054 
00055   //: Modify projection matrices so they are scaled orthographic projections
00056   //  $ P = s(I|0)*R $
00057   void make_pure_projections();
00058 
00059   //: find matrix Q using constraints on matrix P which must contain orthonormal projects in each (2*3) submatrix for each frame
00060   void find_correction_matrix( vnl_matrix<double>& Q,
00061                                const vnl_matrix<double>& P);
00062 
00063   //: find matrix Q using constraints on matrix P which must contain
00064   // From two rows of a projection matrix (a+b) find six constraints
00065   // used to compute (QQt) symmetric matrix
00066   void compute_one_row_of_constraints( vnl_vector<double>& c,
00067                                        const vnl_vector<double>& a,
00068                                        const vnl_vector<double>& b);
00069 
00070   //: find matrix Q using constraints on matrix P which must contain orthonormal projects in each (2*3) submatrix for each frame.
00071   // old method
00072   void find_correction_matrix_alt( vnl_matrix<double>& Q,
00073                                    const vnl_matrix<double>& P);
00074 
00075   //: Return 3d pts given 3*np matrix
00076   void mat_to_3d_pts( vcl_vector< vgl_point_3d<double> >& pts,
00077                       const vnl_matrix<double>& M) const;
00078 
00079  public:
00080   //: Reconstruct structure of 3D points given multiple 2D views
00081   //  Data assumed to be scaled orthographic projections
00082   //  The result is stored in the shape_3d() matrix.
00083   //  The estimated projection matrices are stored in the projections() matrix
00084   //  \param P2D 2ns x np matrix. Rows contain alternating x's and y's from 2D shapes
00085   void reconstruct(const vnl_matrix<double>& P2D);
00086 
00087   //: Reconstruct structure from set of 2d pts
00088   // Formulates measurement matrix P2D then calls reconstruct function above
00089   void reconstruct(const vcl_vector< vcl_vector< vgl_point_2d<double> > >& pt_vec_list );
00090 
00091   //: Refine estimates of projection and structure
00092   void refine();
00093 
00094 //===========================Access functions===================================
00095 
00096   //: Return 3 x np matrix, each column containing one 3D point
00097   //  Points are centred on the origin
00098   const vnl_matrix<double>& shape_3d() const { return P3D_; }
00099 
00100   //: The 2ns x 3 projection matrix
00101   //  Each 2x3 sub-matrix is a scaled orthographic projection matrix
00102   const vnl_matrix<double>& projections() const { return P_; }
00103 
00104   //: Centred version of the 2D views supplied to reconstruct()
00105   //  Each 2D shape has been translated so that its CoG is at the origin
00106   const vnl_matrix<double>& centred_views() const { return P2Dc_; }
00107 
00108   //: Return 3d pts given 3*np matrix
00109   void get_shape_3d_pts( vcl_vector< vgl_point_3d<double> >& pts ) const;
00110 #if 0
00111   { mat_to_3d_pts( pts, P3D_); }
00112 #endif
00113 
00114   //: Get back 3d pts rotated and shifted for each frame
00115   void recon_shapes(vcl_vector< vcl_vector< vgl_point_3d<double> > >& pt_vec_list ) const;
00116 
00117   //: Flip z coords
00118   // may need to do this to fix z coord ambiguity
00119   void flip_z_coords();
00120 };
00121 
00122 #endif // m2d3_ortho_rigid_builder_h_