Point Cloud Library (PCL)  1.8.1-dev
pca.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, Willow Garage, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of the copyright holder(s) nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id$
37  */
38 
39 #ifndef PCL_PCA_H
40 #define PCL_PCA_H
41 
42 #include <pcl/pcl_base.h>
43 #include <pcl/pcl_macros.h>
44 
45 namespace pcl
46 {
47  /** Principal Component analysis (PCA) class.\n
48  * Principal components are extracted by singular values decomposition on the
49  * covariance matrix of the centered input cloud. Available data after pca computation
50  * are the mean of the input data, the eigenvalues (in descending order) and
51  * corresponding eigenvectors.\n
52  * Other methods allow projection in the eigenspace, reconstruction from eigenspace and
53  * update of the eigenspace with a new datum (according Matej Artec, Matjaz Jogan and
54  * Ales Leonardis: "Incremental PCA for On-line Visual Learning and Recognition").
55  *
56  * \author Nizar Sallem
57  * \ingroup common
58  */
59  template <typename PointT>
60  class PCA : public pcl::PCLBase <PointT>
61  {
62  public:
64  typedef typename Base::PointCloud PointCloud;
69 
70  using Base::input_;
71  using Base::indices_;
72  using Base::initCompute;
73  using Base::setInputCloud;
74 
75  /** Updating method flag */
76  enum FLAG
77  {
78  /** keep the new basis vectors if possible */
80  /** preserve subspace dimension */
82  };
83 
84  /** \brief Default Constructor
85  * \param basis_only flag to compute only the PCA basis
86  */
87  PCA (bool basis_only = false)
88  : Base ()
89  , compute_done_ (false)
90  , basis_only_ (basis_only)
91  , eigenvectors_ ()
92  , coefficients_ ()
93  , mean_ ()
94  , eigenvalues_ ()
95  {}
96 
97  /** \brief Constructor with direct computation
98  * X input m*n matrix (ie n vectors of R(m))
99  * basis_only flag to compute only the PCA basis
100  */
101  PCL_DEPRECATED ("Use PCA (bool basis_only); setInputCloud (X.makeShared ()); instead")
102  PCA (const pcl::PointCloud<PointT>& X, bool basis_only = false);
103 
104  /** Copy Constructor
105  * \param[in] pca PCA object
106  */
107  PCA (PCA const & pca)
108  : Base (pca)
109  , compute_done_ (pca.compute_done_)
110  , basis_only_ (pca.basis_only_)
111  , eigenvectors_ (pca.eigenvectors_)
112  , coefficients_ (pca.coefficients_)
113  , mean_ (pca.mean_)
114  , eigenvalues_ (pca.eigenvalues_)
115  {}
116 
117  /** Assignment operator
118  * \param[in] pca PCA object
119  */
120  inline PCA&
121  operator= (PCA const & pca)
122  {
123  eigenvectors_ = pca.eigenvectors_;
124  coefficients_ = pca.coefficients_;
125  eigenvalues_ = pca.eigenvalues_;
126  mean_ = pca.mean_;
127  return (*this);
128  }
129 
130  /** \brief Provide a pointer to the input dataset
131  * \param cloud the const boost shared pointer to a PointCloud message
132  */
133  inline void
135  {
136  Base::setInputCloud (cloud);
137  compute_done_ = false;
138  }
139 
140  /** \brief Provide a pointer to the vector of indices that represents the input data.
141  * \param[in] indices a pointer to the indices that represent the input data.
142  */
143  virtual void
144  setIndices (const IndicesPtr &indices)
145  {
146  Base::setIndices (indices);
147  compute_done_ = false;
148  }
149 
150  /** \brief Provide a pointer to the vector of indices that represents the input data.
151  * \param[in] indices a pointer to the indices that represent the input data.
152  */
153  virtual void
154  setIndices (const IndicesConstPtr &indices)
155  {
156  Base::setIndices (indices);
157  compute_done_ = false;
158  }
159 
160  /** \brief Provide a pointer to the vector of indices that represents the input data.
161  * \param[in] indices a pointer to the indices that represent the input data.
162  */
163  virtual void
165  {
166  Base::setIndices (indices);
167  compute_done_ = false;
168  }
169 
170  /** \brief Set the indices for the points laying within an interest region of
171  * the point cloud.
172  * \note you shouldn't call this method on unorganized point clouds!
173  * \param[in] row_start the offset on rows
174  * \param[in] col_start the offset on columns
175  * \param[in] nb_rows the number of rows to be considered row_start included
176  * \param[in] nb_cols the number of columns to be considered col_start included
177  */
178  virtual void
179  setIndices (size_t row_start, size_t col_start, size_t nb_rows, size_t nb_cols)
180  {
181  Base::setIndices (row_start, col_start, nb_rows, nb_cols);
182  compute_done_ = false;
183  }
184 
185  /** \brief Mean accessor
186  * \throw InitFailedException
187  */
188  inline Eigen::Vector4f&
190  {
191  if (!compute_done_)
192  initCompute ();
193  if (!compute_done_)
194  PCL_THROW_EXCEPTION (InitFailedException,
195  "[pcl::PCA::getMean] PCA initCompute failed");
196  return (mean_);
197  }
198 
199  /** Eigen Vectors accessor
200  * \throw InitFailedException
201  */
202  inline Eigen::Matrix3f&
204  {
205  if (!compute_done_)
206  initCompute ();
207  if (!compute_done_)
208  PCL_THROW_EXCEPTION (InitFailedException,
209  "[pcl::PCA::getEigenVectors] PCA initCompute failed");
210  return (eigenvectors_);
211  }
212 
213  /** Eigen Values accessor
214  * \throw InitFailedException
215  */
216  inline Eigen::Vector3f&
218  {
219  if (!compute_done_)
220  initCompute ();
221  if (!compute_done_)
222  PCL_THROW_EXCEPTION (InitFailedException,
223  "[pcl::PCA::getEigenVectors] PCA getEigenValues failed");
224  return (eigenvalues_);
225  }
226 
227  /** Coefficients accessor
228  * \throw InitFailedException
229  */
230  inline Eigen::MatrixXf&
232  {
233  if (!compute_done_)
234  initCompute ();
235  if (!compute_done_)
236  PCL_THROW_EXCEPTION (InitFailedException,
237  "[pcl::PCA::getEigenVectors] PCA getCoefficients failed");
238  return (coefficients_);
239  }
240 
241  /** update PCA with a new point
242  * \param[in] input input point
243  * \param[in] flag update flag
244  * \throw InitFailedException
245  */
246  inline void
247  update (const PointT& input, FLAG flag = preserve);
248 
249  /** Project point on the eigenspace.
250  * \param[in] input point from original dataset
251  * \param[out] projection the point in eigen vectors space
252  * \throw InitFailedException
253  */
254  inline void
255  project (const PointT& input, PointT& projection);
256 
257  /** Project cloud on the eigenspace.
258  * \param[in] input cloud from original dataset
259  * \param[out] projection the cloud in eigen vectors space
260  * \throw InitFailedException
261  */
262  inline void
263  project (const PointCloud& input, PointCloud& projection);
264 
265  /** Reconstruct point from its projection
266  * \param[in] projection point from eigenvector space
267  * \param[out] input reconstructed point
268  * \throw InitFailedException
269  */
270  inline void
271  reconstruct (const PointT& projection, PointT& input);
272 
273  /** Reconstruct cloud from its projection
274  * \param[in] projection cloud from eigenvector space
275  * \param[out] input reconstructed cloud
276  * \throw InitFailedException
277  */
278  inline void
279  reconstruct (const PointCloud& projection, PointCloud& input);
280 
281  private:
282  inline bool
283  initCompute ();
284 
285  bool compute_done_;
286  bool basis_only_;
287  Eigen::Matrix3f eigenvectors_;
288  Eigen::MatrixXf coefficients_;
289  Eigen::Vector4f mean_;
290  Eigen::Vector3f eigenvalues_;
291  }; // class PCA
292 } // namespace pcl
293 
294 #include <pcl/common/impl/pca.hpp>
295 
296 #endif // PCL_PCA_H
297 
Base::PointCloud PointCloud
Definition: pca.h:64
Principal Component analysis (PCA) class.
Definition: pca.h:60
PointCloud::ConstPtr PointCloudConstPtr
Definition: pcl_base.h:73
preserve subspace dimension
Definition: pca.h:81
boost::shared_ptr< std::vector< int > > IndicesPtr
Definition: pcl_base.h:60
Base::PointCloudPtr PointCloudPtr
Definition: pca.h:65
FLAG
Updating method flag.
Definition: pca.h:76
PCA & operator=(PCA const &pca)
Assignment operator.
Definition: pca.h:121
Base::PointCloudConstPtr PointCloudConstPtr
Definition: pca.h:66
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition: pcl_base.h:153
Base::PointIndicesConstPtr PointIndicesConstPtr
Definition: pca.h:68
virtual void setIndices(size_t row_start, size_t col_start, size_t nb_rows, size_t nb_cols)
Set the indices for the points laying within an interest region of the point cloud.
Definition: pca.h:179
virtual void setIndices(const PointIndicesConstPtr &indices)
Provide a pointer to the vector of indices that represents the input data.
Definition: pca.h:164
boost::shared_ptr< PointIndices > PointIndicesPtr
Definition: pcl_base.h:75
pcl::PCLBase< PointT > Base
Definition: pca.h:63
void update(const PointT &input, FLAG flag=preserve)
update PCA with a new point
Definition: pca.hpp:105
virtual void setIndices(const IndicesPtr &indices)
Provide a pointer to the vector of indices that represents the input data.
Definition: pca.h:144
bool initCompute()
This method should get called before starting the actual computation.
Definition: pcl_base.hpp:139
PointCloud::Ptr PointCloudPtr
Definition: pcl_base.h:72
void reconstruct(const PointT &projection, PointT &input)
Reconstruct point from its projection.
Definition: pca.hpp:217
void project(const PointT &input, PointT &projection)
Project point on the eigenspace.
Definition: pca.hpp:175
boost::shared_ptr< PointIndices const > PointIndicesConstPtr
Definition: pcl_base.h:76
PCL base class.
Definition: pcl_base.h:68
An exception thrown when init can not be performed should be used in all the PCLBase class inheritant...
Definition: exceptions.h:194
Eigen::Vector4f & getMean()
Mean accessor.
Definition: pca.h:189
virtual void setIndices(const IndicesPtr &indices)
Provide a pointer to the vector of indices that represents the input data.
Definition: pcl_base.hpp:73
Base::PointIndicesPtr PointIndicesPtr
Definition: pca.h:67
Eigen::Matrix3f & getEigenVectors()
Eigen Vectors accessor.
Definition: pca.h:203
Eigen::MatrixXf & getCoefficients()
Coefficients accessor.
Definition: pca.h:231
PCA(bool basis_only=false)
Default Constructor.
Definition: pca.h:87
virtual void setInputCloud(const PointCloudConstPtr &cloud)
Provide a pointer to the input dataset.
Definition: pcl_base.hpp:66
boost::shared_ptr< const std::vector< int > > IndicesConstPtr
Definition: pcl_base.h:61
Eigen::Vector3f & getEigenValues()
Eigen Values accessor.
Definition: pca.h:217
PointCloudConstPtr input_
The input point cloud dataset.
Definition: pcl_base.h:150
keep the new basis vectors if possible
Definition: pca.h:79
A point structure representing Euclidean xyz coordinates, and the RGB color.
void setInputCloud(const PointCloudConstPtr &cloud)
Provide a pointer to the input dataset.
Definition: pca.h:134
virtual void setIndices(const IndicesConstPtr &indices)
Provide a pointer to the vector of indices that represents the input data.
Definition: pca.h:154