Point Cloud Library (PCL)  1.14.0-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 #pragma once
40 
41 #include <pcl/pcl_base.h>
42 #include <pcl/pcl_macros.h>
43 
44 namespace pcl
45 {
46  /** Principal Component analysis (PCA) class.\n
47  * Principal components are extracted by singular values decomposition on the
48  * covariance matrix of the centered input cloud. Available data after pca computation
49  * are:\n
50  * - The Mean of the input data\n
51  * - The Eigenvectors: Ordered set of vectors representing the resultant principal components and the eigenspace cartesian basis (right-handed coordinate system).\n
52  * - The Eigenvalues: Eigenvectors correspondent loadings ordered in descending order.\n\n
53  * Other methods allow projection in the eigenspace, reconstruction from eigenspace and
54  * update of the eigenspace with a new datum (according Matej Artec, Matjaz Jogan and
55  * Ales Leonardis: "Incremental PCA for On-line Visual Learning and Recognition").
56  *
57  * \author Nizar Sallem
58  * \ingroup common
59  */
60  template <typename PointT>
61  class PCA : public pcl::PCLBase <PointT>
62  {
63  public:
65  using PointCloud = typename Base::PointCloud;
70 
71  using Base::input_;
72  using Base::indices_;
73  using Base::initCompute;
74  using Base::setInputCloud;
75 
76  /** Updating method flag */
77  enum FLAG
78  {
79  /** keep the new basis vectors if possible */
81  /** preserve subspace dimension */
82  preserve
83  };
84 
85  /** \brief Default Constructor
86  * \param basis_only flag to compute only the PCA basis
87  */
88  PCA (bool basis_only = false)
89  : Base ()
90  , basis_only_ (basis_only)
91  {}
92 
93  /** Copy Constructor
94  * \param[in] pca PCA object
95  */
96  PCA (PCA const & pca)
97  : Base (pca)
98  , compute_done_ (pca.compute_done_)
99  , basis_only_ (pca.basis_only_)
100  , eigenvectors_ (pca.eigenvectors_)
101  , coefficients_ (pca.coefficients_)
102  , mean_ (pca.mean_)
103  , eigenvalues_ (pca.eigenvalues_)
104  {}
105 
106  /** Assignment operator
107  * \param[in] pca PCA object
108  */
109  inline PCA&
110  operator= (PCA const & pca)
111  {
112  eigenvectors_ = pca.eigenvectors_;
113  coefficients_ = pca.coefficients_;
114  eigenvalues_ = pca.eigenvalues_;
115  mean_ = pca.mean_;
116  return (*this);
117  }
118 
119  /** \brief Provide a pointer to the input dataset
120  * \param cloud the const boost shared pointer to a PointCloud message
121  */
122  inline void
123  setInputCloud (const PointCloudConstPtr &cloud) override
124  {
125  Base::setInputCloud (cloud);
126  compute_done_ = false;
127  }
128 
129  /** \brief Provide a pointer to the vector of indices that represents the input data.
130  * \param[in] indices a pointer to the indices that represent the input data.
131  */
132  void
133  setIndices (const IndicesPtr &indices) override
134  {
135  Base::setIndices (indices);
136  compute_done_ = false;
137  }
138 
139  /** \brief Provide a pointer to the vector of indices that represents the input data.
140  * \param[in] indices a pointer to the indices that represent the input data.
141  */
142  void
143  setIndices (const IndicesConstPtr &indices) override
144  {
145  Base::setIndices (indices);
146  compute_done_ = false;
147  }
148 
149  /** \brief Provide a pointer to the vector of indices that represents the input data.
150  * \param[in] indices a pointer to the indices that represent the input data.
151  */
152  void
153  setIndices (const PointIndicesConstPtr &indices) override
154  {
155  Base::setIndices (indices);
156  compute_done_ = false;
157  }
158 
159  /** \brief Set the indices for the points laying within an interest region of
160  * the point cloud.
161  * \note you shouldn't call this method on unorganized point clouds!
162  * \param[in] row_start the offset on rows
163  * \param[in] col_start the offset on columns
164  * \param[in] nb_rows the number of rows to be considered row_start included
165  * \param[in] nb_cols the number of columns to be considered col_start included
166  */
167  void
168  setIndices (std::size_t row_start, std::size_t col_start, std::size_t nb_rows, std::size_t nb_cols) override
169  {
170  Base::setIndices (row_start, col_start, nb_rows, nb_cols);
171  compute_done_ = false;
172  }
173 
174  /** \brief Mean accessor
175  * \throw InitFailedException
176  */
177  inline Eigen::Vector4f&
179  {
180  if (!compute_done_)
181  initCompute ();
182  if (!compute_done_)
183  PCL_THROW_EXCEPTION (InitFailedException,
184  "[pcl::PCA::getMean] PCA initCompute failed");
185  return (mean_);
186  }
187 
188  /** Eigen Vectors accessor
189  * \return Column ordered eigenvectors, representing the eigenspace cartesian basis (right-handed coordinate system).
190  * \throw InitFailedException
191  */
192  inline Eigen::Matrix3f&
194  {
195  if (!compute_done_)
196  initCompute ();
197  if (!compute_done_)
198  PCL_THROW_EXCEPTION (InitFailedException,
199  "[pcl::PCA::getEigenVectors] PCA initCompute failed");
200  return (eigenvectors_);
201  }
202 
203  /** Eigen Values accessor
204  * \throw InitFailedException
205  */
206  inline Eigen::Vector3f&
208  {
209  if (!compute_done_)
210  initCompute ();
211  if (!compute_done_)
212  PCL_THROW_EXCEPTION (InitFailedException,
213  "[pcl::PCA::getEigenVectors] PCA getEigenValues failed");
214  return (eigenvalues_);
215  }
216 
217  /** Coefficients accessor
218  * \throw InitFailedException
219  */
220  inline Eigen::MatrixXf&
222  {
223  if (!compute_done_)
224  initCompute ();
225  if (!compute_done_)
226  PCL_THROW_EXCEPTION (InitFailedException,
227  "[pcl::PCA::getEigenVectors] PCA getCoefficients failed");
228  return (coefficients_);
229  }
230 
231  /** update PCA with a new point
232  * \param[in] input input point
233  * \param[in] flag update flag
234  * \throw InitFailedException
235  */
236  inline void
237  update (const PointT& input, FLAG flag = preserve);
238 
239  /** Project point on the eigenspace.
240  * \param[in] input point from original dataset
241  * \param[out] projection the point in eigen vectors space
242  * \throw InitFailedException
243  */
244  inline void
245  project (const PointT& input, PointT& projection);
246 
247  /** Project cloud on the eigenspace.
248  * \param[in] input cloud from original dataset
249  * \param[out] projection the cloud in eigen vectors space
250  * \throw InitFailedException
251  */
252  inline void
253  project (const PointCloud& input, PointCloud& projection);
254 
255  /** Reconstruct point from its projection
256  * \param[in] projection point from eigenvector space
257  * \param[out] input reconstructed point
258  * \throw InitFailedException
259  */
260  inline void
261  reconstruct (const PointT& projection, PointT& input);
262 
263  /** Reconstruct cloud from its projection
264  * \param[in] projection cloud from eigenvector space
265  * \param[out] input reconstructed cloud
266  * \throw InitFailedException
267  */
268  inline void
269  reconstruct (const PointCloud& projection, PointCloud& input);
270  private:
271  inline bool
272  initCompute ();
273 
274  bool compute_done_{false};
275  bool basis_only_;
276  Eigen::Matrix3f eigenvectors_;
277  Eigen::MatrixXf coefficients_;
278  Eigen::Vector4f mean_;
279  Eigen::Vector3f eigenvalues_;
280  }; // class PCA
281 } // namespace pcl
282 
283 #include <pcl/common/impl/pca.hpp>
An exception thrown when init can not be performed should be used in all the PCLBase class inheritant...
Definition: exceptions.h:196
Principal Component analysis (PCA) class.
Definition: pca.h:62
typename Base::PointCloudConstPtr PointCloudConstPtr
Definition: pca.h:67
Eigen::Vector4f & getMean()
Mean accessor.
Definition: pca.h:178
void setInputCloud(const PointCloudConstPtr &cloud) override
Provide a pointer to the input dataset.
Definition: pca.h:123
FLAG
Updating method flag.
Definition: pca.h:78
@ preserve
preserve subspace dimension
Definition: pca.h:82
@ increase
keep the new basis vectors if possible
Definition: pca.h:80
void project(const PointT &input, PointT &projection)
Project point on the eigenspace.
Definition: pca.hpp:166
PCA & operator=(PCA const &pca)
Assignment operator.
Definition: pca.h:110
Eigen::Vector3f & getEigenValues()
Eigen Values accessor.
Definition: pca.h:207
void update(const PointT &input, FLAG flag=preserve)
update PCA with a new point
Definition: pca.hpp:96
void setIndices(std::size_t row_start, std::size_t col_start, std::size_t nb_rows, std::size_t nb_cols) override
Set the indices for the points laying within an interest region of the point cloud.
Definition: pca.h:168
typename Base::PointCloudPtr PointCloudPtr
Definition: pca.h:66
Eigen::MatrixXf & getCoefficients()
Coefficients accessor.
Definition: pca.h:221
PCA(bool basis_only=false)
Default Constructor.
Definition: pca.h:88
PCA(PCA const &pca)
Copy Constructor.
Definition: pca.h:96
void setIndices(const PointIndicesConstPtr &indices) override
Provide a pointer to the vector of indices that represents the input data.
Definition: pca.h:153
typename Base::PointIndicesConstPtr PointIndicesConstPtr
Definition: pca.h:69
Eigen::Matrix3f & getEigenVectors()
Eigen Vectors accessor.
Definition: pca.h:193
typename Base::PointCloud PointCloud
Definition: pca.h:65
void setIndices(const IndicesConstPtr &indices) override
Provide a pointer to the vector of indices that represents the input data.
Definition: pca.h:143
void reconstruct(const PointT &projection, PointT &input)
Reconstruct point from its projection.
Definition: pca.hpp:208
void setIndices(const IndicesPtr &indices) override
Provide a pointer to the vector of indices that represents the input data.
Definition: pca.h:133
typename Base::PointIndicesPtr PointIndicesPtr
Definition: pca.h:68
PCL base class.
Definition: pcl_base.h:70
PointCloudConstPtr input_
The input point cloud dataset.
Definition: pcl_base.h:147
virtual void setInputCloud(const PointCloudConstPtr &cloud)
Provide a pointer to the input dataset.
Definition: pcl_base.hpp:65
typename PointCloud::Ptr PointCloudPtr
Definition: pcl_base.h:73
typename PointCloud::ConstPtr PointCloudConstPtr
Definition: pcl_base.h:74
pcl::PointCloud< PointT > PointCloud
Definition: pcl_base.h:72
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition: pcl_base.h:150
virtual void setIndices(const IndicesPtr &indices)
Provide a pointer to the vector of indices that represents the input data.
Definition: pcl_base.hpp:72
bool initCompute()
This method should get called before starting the actual computation.
Definition: pcl_base.hpp:138
PointIndices::ConstPtr PointIndicesConstPtr
Definition: pcl_base.h:77
PointIndices::Ptr PointIndicesPtr
Definition: pcl_base.h:76
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: point_cloud.h:173
shared_ptr< const Indices > IndicesConstPtr
Definition: pcl_base.h:59
shared_ptr< Indices > IndicesPtr
Definition: pcl_base.h:58
Defines all the PCL and non-PCL macros used.
A point structure representing Euclidean xyz coordinates, and the RGB color.