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