contrib/brl/bbas/imesh/algo/imesh_pca.h
Go to the documentation of this file.
00001 // This is brl/bbas/imesh/algo/imesh_pca.h
00002 #ifndef imesh_pca_h_
00003 #define imesh_pca_h_
00004 //:
00005 // \file
00006 // \brief Mesh PCA parameterization
00007 // \author Matt Leotta (mleotta@lems.brown.edu)
00008 // \date June 26, 2008
00009 //
00010 // \verbatim
00011 //  Modifications
00012 //   <none yet>
00013 // \endverbatim
00014 
00015 
00016 #include <imesh/imesh_mesh.h>
00017 #include <vcl_vector.h>
00018 #include <vcl_cassert.h>
00019 #include <vnl/vnl_vector.h>
00020 #include <vnl/vnl_matrix.h>
00021 #include <vpgl/vpgl_proj_camera.h>
00022 
00023 
00024 //: Principal Component Analysis on a set of mesh vertices
00025 class imesh_pca_mesh : public imesh_mesh
00026 {
00027  public:
00028   //: Default Constructor
00029   imesh_pca_mesh() {}
00030 
00031   //: Constructor from a vector of meshes with the same topology
00032   imesh_pca_mesh(const vcl_vector<imesh_mesh>& meshes);
00033 
00034   //: Constructor from a mesh, mean, standard deviations, and PC matrix
00035   imesh_pca_mesh(const imesh_mesh& mesh,
00036                  const vnl_vector<double>& mean,
00037                  const vnl_vector<double>& std_devs,
00038                  const vnl_matrix<double>& pc);
00039 
00040   //: Copy Constructor
00041   imesh_pca_mesh(const imesh_pca_mesh& other);
00042   
00043   //: Assignment operator
00044   imesh_pca_mesh& operator=(const imesh_pca_mesh& other);
00045 
00046   //: Initialize the PCA data (assuming mesh data is already set)
00047   //  Use this to add PCA data after a mesh has be loaded from a file
00048   void init(const vnl_vector<double>& mean,
00049             const vnl_vector<double>& std_devs,
00050             const vnl_matrix<double>& pc);
00051 
00052   //: Set the pca parameters
00053   void set_params(const vnl_vector<double>& p);
00054 
00055   //: Set an individual pca parameter
00056   // This is done by incremental difference, errors may accumulate
00057   // over many calls.
00058   void set_param(unsigned int i, double param);
00059 
00060   //: Access the params
00061   const vnl_vector<double>& params() const {return params_;}
00062 
00063   //: Access the principal components
00064   const vnl_matrix<double>& principal_comps() const {return pc_; }
00065 
00066   //: Access the standard deviations
00067   const vnl_vector<double>& std_devs() const {return std_devs_;}
00068 
00069   //: Reset all the PCA parameters to zero
00070   //  Returning to the mean mesh
00071   void set_mean();
00072 
00073   //: Project mesh vertices into the PCA parameter space
00074   vnl_vector<double> project(const imesh_vertex_array_base& verts) const;
00075 
00076   //: Access the vector of mean vertices
00077   const imesh_vertex_array_base& mean_vertices() const { return *mean_verts_; }
00078   imesh_vertex_array_base& mean_vertices() { return *mean_verts_; }
00079 
00080   //: Access the vector of mean vertices cast to a dimension
00081   template <unsigned int d>
00082   const imesh_vertex_array<d>& mean_vertices() const
00083   {
00084     assert(dynamic_cast<imesh_vertex_array<d>*>(mean_verts_.get()));
00085     return static_cast<const imesh_vertex_array<d>&>(*mean_verts_);
00086   }
00087   template <unsigned int d>
00088   imesh_vertex_array<d>& mean_vertices()
00089   {
00090     assert(dynamic_cast<imesh_vertex_array<d>*>(mean_verts_.get()));
00091     return static_cast<imesh_vertex_array<d>&>(*mean_verts_);
00092   }
00093 
00094  protected:
00095   //: compute and set the mean return the deviations matrix
00096   vnl_matrix<double> compute_mean(const vcl_vector<imesh_mesh>& meshes);
00097   //: Construct from a mesh with no variation
00098   imesh_pca_mesh(const imesh_mesh& mesh);
00099 
00100   vnl_vector<double> std_devs_;
00101   vnl_matrix<double> pc_;
00102   vcl_auto_ptr<imesh_vertex_array_base> mean_verts_;
00103 
00104   vnl_vector<double> params_;
00105 };
00106 
00107 
00108 //: Compute the image Jacobians at each vertex for PCA parameters in the result:
00109 //  Matrix n, row i is the image space derivative
00110 //  at vertex n with respect to the ith pca parameter
00111 vcl_vector<vnl_matrix<double> >
00112 imesh_pca_image_jacobians(const vpgl_proj_camera<double>& camera,
00113                           const imesh_pca_mesh& mesh);
00114 
00115 
00116 //: Read a PCA mesh from a mean mesh and a pca file
00117 imesh_pca_mesh imesh_read_pca(const vcl_string& mean_file,
00118                               const vcl_string& pca_file);
00119 
00120 //: Read a PCA file
00121 bool imesh_read_pca(const vcl_string& pca_file,
00122                     vnl_vector<double>& mean,
00123                     vnl_vector<double>& std_devs,
00124                     vnl_matrix<double>& pc);
00125 
00126 //: Write the mean mesh and PCA file
00127 void imesh_write_pca(const vcl_string& mesh_file,
00128                      const vcl_string& pca_file,
00129                      const imesh_pca_mesh& pmesh);
00130 
00131 //: Write a PCA file
00132 bool imesh_write_pca(const vcl_string& filename,
00133                      const vnl_vector<double>& mean,
00134                      const vnl_vector<double>& std_devs,
00135                      const vnl_matrix<double>& pc);
00136 
00137 
00138 #endif // imesh_pca_h_