Point Cloud Library (PCL)  1.5.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
centroid.hpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2009-present, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * $Id: centroid.hpp 4702 2012-02-23 09:39:33Z gedikli $
00035  *
00036  */
00037 
00038 #ifndef PCL_COMMON_IMPL_CENTROID_H_
00039 #define PCL_COMMON_IMPL_CENTROID_H_
00040 
00041 #include "pcl/ros/conversions.h"
00042 #include <boost/mpl/size.hpp>
00043 
00045 template <typename PointT> inline unsigned int
00046 pcl::compute3DCentroid (const pcl::PointCloud<PointT> &cloud, Eigen::Vector4f &centroid)
00047 {
00048   if (cloud.points.empty ())
00049     return (0);
00050 
00051   // Initialize to 0
00052   centroid.setZero ();
00053   // For each point in the cloud
00054   // If the data is dense, we don't need to check for NaN
00055   if (cloud.is_dense)
00056   {
00057     for (size_t i = 0; i < cloud.points.size (); ++i)
00058       centroid += cloud.points[i].getVector4fMap ();
00059     centroid[3] = 0;
00060     centroid /= cloud.points.size ();
00061 
00062     return (cloud.points.size ());
00063   }
00064   // NaN or Inf values could exist => check for them
00065   else
00066   {
00067     unsigned cp = 0;
00068     for (size_t i = 0; i < cloud.points.size (); ++i)
00069     {
00070       // Check if the point is invalid
00071       if (!isFinite (cloud [i]))
00072         continue;
00073 
00074       centroid += cloud[i].getVector4fMap ();
00075       ++cp;
00076     }
00077     centroid[3] = 0;
00078     centroid /= cp;
00079 
00080     return (cp);
00081   }
00082 }
00083 
00085 template <typename PointT> inline unsigned int
00086 pcl::compute3DCentroid (const pcl::PointCloud<PointT> &cloud, const std::vector<int> &indices,
00087                         Eigen::Vector4f &centroid)
00088 {
00089   if (indices.empty ())
00090     return (0);
00091 
00092   // Initialize to 0
00093   centroid.setZero ();
00094   // If the data is dense, we don't need to check for NaN
00095   if (cloud.is_dense)
00096   {
00097     for (size_t i = 0; i < indices.size (); ++i)
00098       centroid += cloud.points[indices[i]].getVector4fMap ();
00099     centroid[3] = 0;
00100     centroid /= (float) indices.size ();
00101     return (indices.size ());
00102   }
00103   // NaN or Inf values could exist => check for them
00104   else
00105   {
00106     unsigned cp = 0;
00107     for (size_t i = 0; i < indices.size (); ++i)
00108     {
00109       // Check if the point is invalid
00110       if (!isFinite (cloud [indices[i]]))
00111         continue;
00112 
00113       centroid += cloud[indices[i]].getVector4fMap ();
00114       ++cp;
00115     }
00116     centroid[3] = 0.0f;
00117     centroid /= (float) cp;
00118     return (cp);
00119   }
00120 }
00121 
00123 template <typename PointT> inline unsigned int
00124 pcl::compute3DCentroid (const pcl::PointCloud<PointT> &cloud,
00125                         const pcl::PointIndices &indices, Eigen::Vector4f &centroid)
00126 {
00127   return (pcl::compute3DCentroid<PointT> (cloud, indices.indices, centroid));
00128 }
00129 
00131 template <typename PointT> inline unsigned
00132 pcl::computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00133                               const Eigen::Vector4f &centroid,
00134                               Eigen::Matrix3f &covariance_matrix)
00135 {
00136   if (cloud.points.empty ())
00137     return (0);
00138 
00139   // Initialize to 0
00140   covariance_matrix.setZero ();
00141 
00142   unsigned point_count;
00143   // If the data is dense, we don't need to check for NaN
00144   if (cloud.is_dense)
00145   {
00146     point_count = cloud.size ();
00147     // For each point in the cloud
00148     for (size_t i = 0; i < point_count; ++i)
00149     {
00150       Eigen::Vector4f pt = cloud [i].getVector4fMap () - centroid;
00151 
00152       covariance_matrix (1, 1) += pt.y () * pt.y ();
00153       covariance_matrix (1, 2) += pt.y () * pt.z ();
00154 
00155       covariance_matrix (2, 2) += pt.z () * pt.z ();
00156 
00157       pt *= pt.x ();
00158       covariance_matrix (0, 0) += pt.x ();
00159       covariance_matrix (0, 1) += pt.y ();
00160       covariance_matrix (0, 2) += pt.z ();
00161     }
00162   }
00163   // NaN or Inf values could exist => check for them
00164   else
00165   {
00166     point_count = 0;
00167     // For each point in the cloud
00168     for (size_t i = 0; i < cloud.size (); ++i)
00169     {
00170       // Check if the point is invalid
00171       if (!isFinite (cloud [i]))
00172         continue;
00173 
00174       Eigen::Vector4f pt = cloud [i].getVector4fMap () - centroid;
00175 
00176       covariance_matrix (1, 1) += pt.y () * pt.y ();
00177       covariance_matrix (1, 2) += pt.y () * pt.z ();
00178 
00179       covariance_matrix (2, 2) += pt.z () * pt.z ();
00180 
00181       pt *= pt.x ();
00182       covariance_matrix (0, 0) += pt.x ();
00183       covariance_matrix (0, 1) += pt.y ();
00184       covariance_matrix (0, 2) += pt.z ();
00185       ++point_count;
00186     }
00187   }
00188   covariance_matrix (1, 0) = covariance_matrix (0, 1);
00189   covariance_matrix (2, 0) = covariance_matrix (0, 2);
00190   covariance_matrix (2, 1) = covariance_matrix (1, 2);
00191 
00192   return (point_count);
00193 }
00194 
00196 template <typename PointT> inline unsigned int
00197 pcl::computeCovarianceMatrixNormalized (const pcl::PointCloud<PointT> &cloud,
00198                                         const Eigen::Vector4f &centroid,
00199                                         Eigen::Matrix3f &covariance_matrix)
00200 {
00201   unsigned point_count = pcl::computeCovarianceMatrix (cloud, centroid, covariance_matrix);
00202   if (point_count != 0)
00203     covariance_matrix /= point_count;
00204   return (point_count);
00205 }
00206 
00208 template <typename PointT> inline unsigned int
00209 pcl::computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00210                               const std::vector<int> &indices,
00211                               const Eigen::Vector4f &centroid,
00212                               Eigen::Matrix3f &covariance_matrix)
00213 {
00214   if (indices.empty ())
00215     return (0);
00216 
00217   // Initialize to 0
00218   covariance_matrix.setZero ();
00219 
00220   unsigned point_count;
00221   // If the data is dense, we don't need to check for NaN
00222   if (cloud.is_dense)
00223   {
00224     point_count = indices.size ();
00225     // For each point in the cloud
00226     for (size_t i = 0; i < point_count; ++i)
00227     {
00228       Eigen::Vector4f pt = cloud.points[indices[i]].getVector4fMap () - centroid;
00229 
00230       covariance_matrix (1, 1) += pt.y () * pt.y ();
00231       covariance_matrix (1, 2) += pt.y () * pt.z ();
00232 
00233       covariance_matrix (2, 2) += pt.z () * pt.z ();
00234 
00235       pt *= pt.x ();
00236       covariance_matrix (0, 0) += pt.x ();
00237       covariance_matrix (0, 1) += pt.y ();
00238       covariance_matrix (0, 2) += pt.z ();
00239     }
00240   }
00241   // NaN or Inf values could exist => check for them
00242   else
00243   {
00244     point_count = 0;
00245     // For each point in the cloud
00246     for (size_t i = 0; i < indices.size (); ++i)
00247     {
00248       // Check if the point is invalid
00249       if (!isFinite (cloud[indices[i]]))
00250         continue;
00251 
00252       Eigen::Vector4f pt = cloud[indices[i]].getVector4fMap () - centroid;
00253 
00254       covariance_matrix (1, 1) += pt.y () * pt.y ();
00255       covariance_matrix (1, 2) += pt.y () * pt.z ();
00256 
00257       covariance_matrix (2, 2) += pt.z () * pt.z ();
00258 
00259       pt *= pt.x ();
00260       covariance_matrix (0, 0) += pt.x ();
00261       covariance_matrix (0, 1) += pt.y ();
00262       covariance_matrix (0, 2) += pt.z ();
00263       ++point_count;
00264     }
00265   }
00266   covariance_matrix (1, 0) = covariance_matrix (0, 1);
00267   covariance_matrix (2, 0) = covariance_matrix (0, 2);
00268   covariance_matrix (2, 1) = covariance_matrix (1, 2);
00269   return (point_count);
00270 }
00271 
00273 template <typename PointT> inline unsigned int
00274 pcl::computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00275                               const pcl::PointIndices &indices,
00276                               const Eigen::Vector4f &centroid,
00277                               Eigen::Matrix3f &covariance_matrix)
00278 {
00279   return (pcl::computeCovarianceMatrix<PointT> (cloud, indices.indices, centroid, covariance_matrix));
00280 }
00281 
00283 template <typename PointT> inline unsigned int
00284 pcl::computeCovarianceMatrixNormalized (const pcl::PointCloud<PointT> &cloud,
00285                                         const std::vector<int> &indices,
00286                                         const Eigen::Vector4f &centroid,
00287                                         Eigen::Matrix3f &covariance_matrix)
00288 {
00289   unsigned point_count = pcl::computeCovarianceMatrix (cloud, indices, centroid, covariance_matrix);
00290   if (point_count != 0)
00291     covariance_matrix /= point_count;
00292 
00293   return point_count;
00294 }
00295 
00297 template <typename PointT> inline unsigned int
00298 pcl::computeCovarianceMatrixNormalized (const pcl::PointCloud<PointT> &cloud,
00299                                         const pcl::PointIndices &indices,
00300                                         const Eigen::Vector4f &centroid,
00301                                         Eigen::Matrix3f &covariance_matrix)
00302 {
00303   unsigned point_count = pcl::computeCovarianceMatrix (cloud, indices.indices, centroid, covariance_matrix);
00304   if (point_count != 0)
00305     covariance_matrix /= point_count;
00306 
00307   return point_count;
00308 }
00309 
00311 template <typename PointT> inline unsigned int
00312 pcl::computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00313                               Eigen::Matrix3f &covariance_matrix)
00314 {
00315   // create the buffer on the stack which is much faster than using cloud.points[indices[i]] and centroid as a buffer
00316   Eigen::Matrix<float, 1, 6, Eigen::RowMajor> accu = Eigen::Matrix<float, 1, 6, Eigen::RowMajor>::Zero ();
00317 
00318   unsigned int point_count;
00319   if (cloud.is_dense)
00320   {
00321     point_count = cloud.size ();
00322     // For each point in the cloud
00323     for (size_t i = 0; i < point_count; ++i)
00324     {
00325       accu [0] += cloud[i].x * cloud[i].x;
00326       accu [1] += cloud[i].x * cloud[i].y;
00327       accu [2] += cloud[i].x * cloud[i].z;
00328       accu [3] += cloud[i].y * cloud[i].y;
00329       accu [4] += cloud[i].y * cloud[i].z;
00330       accu [5] += cloud[i].z * cloud[i].z;
00331     }
00332   }
00333   else
00334   {
00335     point_count = 0;
00336     for (size_t i = 0; i < cloud.points.size (); ++i)
00337     {
00338       if (!isFinite (cloud[i]))
00339         continue;
00340 
00341       accu [0] += cloud[i].x * cloud[i].x;
00342       accu [1] += cloud[i].x * cloud[i].y;
00343       accu [2] += cloud[i].x * cloud[i].z;
00344       accu [3] += cloud[i].y * cloud[i].y;
00345       accu [4] += cloud[i].y * cloud[i].z;
00346       accu [5] += cloud[i].z * cloud[i].z;
00347       ++point_count;
00348     }
00349   }
00350 
00351   if (point_count != 0)
00352   {
00353     accu /= (float) point_count;
00354     covariance_matrix.coeffRef (0) = accu [0];
00355     covariance_matrix.coeffRef (1) = covariance_matrix.coeffRef (3) = accu [1];
00356     covariance_matrix.coeffRef (2) = covariance_matrix.coeffRef (6) = accu [2];
00357     covariance_matrix.coeffRef (4) = accu [3];
00358     covariance_matrix.coeffRef (5) = covariance_matrix.coeffRef (7) = accu [4];
00359     covariance_matrix.coeffRef (8) = accu [5];
00360   }
00361   return (point_count);
00362 }
00363 
00365 template <typename PointT> inline unsigned int
00366 pcl::computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00367                          const std::vector<int> &indices,
00368                          Eigen::Matrix3f &covariance_matrix)
00369 {
00370   Eigen::Matrix<float, 1, 6, Eigen::RowMajor> accu = Eigen::Matrix<float, 1, 6, Eigen::RowMajor>::Zero ();
00371 
00372   unsigned int point_count;
00373   if (cloud.is_dense)
00374   {
00375     point_count = indices.size ();
00376     for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
00377     {
00378       //const PointT& point = cloud[*iIt];
00379       accu [0] += cloud[*iIt].x * cloud[*iIt].x;
00380       accu [1] += cloud[*iIt].x * cloud[*iIt].y;
00381       accu [2] += cloud[*iIt].x * cloud[*iIt].z;
00382       accu [3] += cloud[*iIt].y * cloud[*iIt].y;
00383       accu [4] += cloud[*iIt].y * cloud[*iIt].z;
00384       accu [5] += cloud[*iIt].z * cloud[*iIt].z;
00385     }
00386   }
00387   else
00388   {
00389     point_count = 0;
00390     for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
00391     {
00392       if (!isFinite (cloud[*iIt]))
00393         continue;
00394 
00395       ++point_count;
00396       accu [0] += cloud[*iIt].x * cloud[*iIt].x;
00397       accu [1] += cloud[*iIt].x * cloud[*iIt].y;
00398       accu [2] += cloud[*iIt].x * cloud[*iIt].z;
00399       accu [3] += cloud[*iIt].y * cloud[*iIt].y;
00400       accu [4] += cloud[*iIt].y * cloud[*iIt].z;
00401       accu [5] += cloud[*iIt].z * cloud[*iIt].z;
00402     }
00403   }
00404   if (point_count != 0)
00405   {
00406     accu /= (float) point_count;
00407     covariance_matrix.coeffRef (0) = accu [0];
00408     covariance_matrix.coeffRef (1) = covariance_matrix.coeffRef (3) = accu [1];
00409     covariance_matrix.coeffRef (2) = covariance_matrix.coeffRef (6) = accu [2];
00410     covariance_matrix.coeffRef (4) = accu [3];
00411     covariance_matrix.coeffRef (5) = covariance_matrix.coeffRef (7) = accu [4];
00412     covariance_matrix.coeffRef (8) = accu [5];
00413   }
00414   return (point_count);
00415 }
00416 
00417 template <typename PointT> inline unsigned int
00418 pcl::computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00419                               const pcl::PointIndices &indices,
00420                               Eigen::Matrix3f &covariance_matrix)
00421 {
00422   return computeCovarianceMatrix (cloud, indices.indices, covariance_matrix);
00423 }
00424 
00426 template <typename PointT> inline unsigned int
00427 pcl::computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00428                               Eigen::Matrix3d &covariance_matrix)
00429 {
00430   // create the buffer on the stack which is much faster than using cloud.points[indices[i]] and centroid as a buffer
00431   Eigen::Matrix<double, 1, 6, Eigen::RowMajor> accu = Eigen::Matrix<double, 1, 6, Eigen::RowMajor>::Zero ();
00432 
00433   unsigned int point_count;
00434   if (cloud.is_dense)
00435   {
00436     point_count = cloud.size ();
00437     // For each point in the cloud
00438     for (size_t i = 0; i < point_count; ++i)
00439     {
00440       accu [0] += cloud[i].x * cloud[i].x;
00441       accu [1] += cloud[i].x * cloud[i].y;
00442       accu [2] += cloud[i].x * cloud[i].z;
00443       accu [3] += cloud[i].y * cloud[i].y;
00444       accu [4] += cloud[i].y * cloud[i].z;
00445       accu [5] += cloud[i].z * cloud[i].z;
00446     }
00447   }
00448   else
00449   {
00450     point_count = 0;
00451     for (size_t i = 0; i < cloud.points.size (); ++i)
00452     {
00453       if (!isFinite (cloud[i]))
00454         continue;
00455 
00456       accu [0] += cloud[i].x * cloud[i].x;
00457       accu [1] += cloud[i].x * cloud[i].y;
00458       accu [2] += cloud[i].x * cloud[i].z;
00459       accu [3] += cloud[i].y * cloud[i].y;
00460       accu [4] += cloud[i].y * cloud[i].z;
00461       accu [5] += cloud[i].z * cloud[i].z;
00462       ++point_count;
00463     }
00464   }
00465 
00466   if (point_count != 0)
00467   {
00468     accu /= (double) point_count;
00469     covariance_matrix.coeffRef (0) = accu [0];
00470     covariance_matrix.coeffRef (1) = covariance_matrix.coeffRef (3) = accu [1];
00471     covariance_matrix.coeffRef (2) = covariance_matrix.coeffRef (6) = accu [2];
00472     covariance_matrix.coeffRef (4) = accu [3];
00473     covariance_matrix.coeffRef (5) = covariance_matrix.coeffRef (7) = accu [4];
00474     covariance_matrix.coeffRef (8) = accu [5];
00475   }
00476   return (point_count);
00477 }
00478 
00480 template <typename PointT> inline unsigned int
00481 pcl::computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00482                               const std::vector<int> &indices,
00483                               Eigen::Matrix3d &covariance_matrix)
00484 {
00485   // create the buffer on the stack which is much faster than using cloud.points[indices[i]] and centroid as a buffer
00486   Eigen::Matrix<double, 1, 6, Eigen::RowMajor> accu = Eigen::Matrix<double, 1, 6, Eigen::RowMajor>::Zero ();
00487 
00488   unsigned int point_count;
00489   if (cloud.is_dense)
00490   {
00491     point_count = indices.size ();
00492     for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
00493     {
00494       //const PointT& point = cloud[*iIt];
00495       accu [0] += cloud[*iIt].x * cloud[*iIt].x;
00496       accu [1] += cloud[*iIt].x * cloud[*iIt].y;
00497       accu [2] += cloud[*iIt].x * cloud[*iIt].z;
00498       accu [3] += cloud[*iIt].y * cloud[*iIt].y;
00499       accu [4] += cloud[*iIt].y * cloud[*iIt].z;
00500       accu [5] += cloud[*iIt].z * cloud[*iIt].z;
00501     }
00502   }
00503   else
00504   {
00505     point_count = 0;
00506     for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
00507     {
00508       if (!isFinite (cloud[*iIt]))
00509         continue;
00510 
00511       ++point_count;
00512       accu [0] += cloud[*iIt].x * cloud[*iIt].x;
00513       accu [1] += cloud[*iIt].x * cloud[*iIt].y;
00514       accu [2] += cloud[*iIt].x * cloud[*iIt].z;
00515       accu [3] += cloud[*iIt].y * cloud[*iIt].y;
00516       accu [4] += cloud[*iIt].y * cloud[*iIt].z;
00517       accu [5] += cloud[*iIt].z * cloud[*iIt].z;
00518     }
00519   }
00520   if (point_count != 0)
00521   {
00522     accu /= (double) point_count;
00523     covariance_matrix.coeffRef (0) = accu [0];
00524     covariance_matrix.coeffRef (1) = covariance_matrix.coeffRef (3) = accu [1];
00525     covariance_matrix.coeffRef (2) = covariance_matrix.coeffRef (6) = accu [2];
00526     covariance_matrix.coeffRef (4) = accu [3];
00527     covariance_matrix.coeffRef (5) = covariance_matrix.coeffRef (7) = accu [4];
00528     covariance_matrix.coeffRef (8) = accu [5];
00529   }
00530   return (point_count);
00531 }
00532 
00533 template <typename PointT> inline unsigned int
00534 pcl::computeCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00535                               const pcl::PointIndices &indices,
00536                               Eigen::Matrix3d &covariance_matrix)
00537 {
00538   return computeCovarianceMatrix (cloud, indices.indices, covariance_matrix);
00539 }
00540 
00542 template <typename PointT> inline unsigned int
00543 pcl::computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00544                                      Eigen::Matrix3f &covariance_matrix,
00545                                      Eigen::Vector4f &centroid)
00546 {
00547   // create the buffer on the stack which is much faster than using cloud.points[indices[i]] and centroid as a buffer
00548   Eigen::Matrix<float, 1, 9, Eigen::RowMajor> accu = Eigen::Matrix<float, 1, 9, Eigen::RowMajor>::Zero ();
00549   unsigned point_count;
00550   if (cloud.is_dense)
00551   {
00552     point_count = cloud.size ();
00553     // For each point in the cloud
00554     for (size_t i = 0; i < point_count; ++i)
00555     {
00556       accu [0] += cloud[i].x * cloud[i].x;
00557       accu [1] += cloud[i].x * cloud[i].y;
00558       accu [2] += cloud[i].x * cloud[i].z;
00559       accu [3] += cloud[i].y * cloud[i].y; // 4
00560       accu [4] += cloud[i].y * cloud[i].z; // 5
00561       accu [5] += cloud[i].z * cloud[i].z; // 8
00562       accu [6] += cloud[i].x;
00563       accu [7] += cloud[i].y;
00564       accu [8] += cloud[i].z;
00565     }
00566   }
00567   else
00568   {
00569     point_count = 0;
00570     for (size_t i = 0; i < cloud.points.size (); ++i)
00571     {
00572       if (!isFinite (cloud[i]))
00573         continue;
00574 
00575       accu [0] += cloud[i].x * cloud[i].x;
00576       accu [1] += cloud[i].x * cloud[i].y;
00577       accu [2] += cloud[i].x * cloud[i].z;
00578       accu [3] += cloud[i].y * cloud[i].y;
00579       accu [4] += cloud[i].y * cloud[i].z;
00580       accu [5] += cloud[i].z * cloud[i].z;
00581       accu [6] += cloud[i].x;
00582       accu [7] += cloud[i].y;
00583       accu [8] += cloud[i].z;
00584       ++point_count;
00585     }
00586   }
00587   accu /= (float) point_count;
00588   if (point_count != 0)
00589   {
00590     centroid.head<3> () = accu.tail<3> ();
00591     centroid[3] = 0;
00592     covariance_matrix.coeffRef (0) = accu [0] - accu [6] * accu [6];
00593     covariance_matrix.coeffRef (1) = accu [1] - accu [6] * accu [7];
00594     covariance_matrix.coeffRef (2) = accu [2] - accu [6] * accu [8];
00595     covariance_matrix.coeffRef (4) = accu [3] - accu [7] * accu [7];
00596     covariance_matrix.coeffRef (5) = accu [4] - accu [7] * accu [8];
00597     covariance_matrix.coeffRef (8) = accu [5] - accu [8] * accu [8];
00598     covariance_matrix.coeffRef (3) = covariance_matrix.coeff (1);
00599     covariance_matrix.coeffRef (6) = covariance_matrix.coeff (2);
00600     covariance_matrix.coeffRef (7) = covariance_matrix.coeff (5);
00601   }
00602   return (point_count);
00603 }
00604 
00606 template <typename PointT> inline unsigned int
00607 pcl::computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00608                                 const std::vector<int> &indices,
00609                                 Eigen::Matrix3f &covariance_matrix,
00610                                 Eigen::Vector4f &centroid)
00611 {
00612   // create the buffer on the stack which is much faster than using cloud.points[indices[i]] and centroid as a buffer
00613   Eigen::Matrix<float, 1, 9, Eigen::RowMajor> accu = Eigen::Matrix<float, 1, 9, Eigen::RowMajor>::Zero ();
00614   unsigned int point_count;
00615   if (cloud.is_dense)
00616   {
00617     point_count = indices.size ();
00618     for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
00619     {
00620       //const PointT& point = cloud[*iIt];
00621       accu [0] += cloud[*iIt].x * cloud[*iIt].x;
00622       accu [1] += cloud[*iIt].x * cloud[*iIt].y;
00623       accu [2] += cloud[*iIt].x * cloud[*iIt].z;
00624       accu [3] += cloud[*iIt].y * cloud[*iIt].y;
00625       accu [4] += cloud[*iIt].y * cloud[*iIt].z;
00626       accu [5] += cloud[*iIt].z * cloud[*iIt].z;
00627       accu [6] += cloud[*iIt].x;
00628       accu [7] += cloud[*iIt].y;
00629       accu [8] += cloud[*iIt].z;
00630     }
00631   }
00632   else
00633   {
00634     point_count = 0;
00635     for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
00636     {
00637       if (!isFinite (cloud[*iIt]))
00638         continue;
00639 
00640       ++point_count;
00641       accu [0] += cloud[*iIt].x * cloud[*iIt].x;
00642       accu [1] += cloud[*iIt].x * cloud[*iIt].y;
00643       accu [2] += cloud[*iIt].x * cloud[*iIt].z;
00644       accu [3] += cloud[*iIt].y * cloud[*iIt].y; // 4
00645       accu [4] += cloud[*iIt].y * cloud[*iIt].z; // 5
00646       accu [5] += cloud[*iIt].z * cloud[*iIt].z; // 8
00647       accu [6] += cloud[*iIt].x;
00648       accu [7] += cloud[*iIt].y;
00649       accu [8] += cloud[*iIt].z;
00650     }
00651   }
00652 
00653   accu /= (float) point_count;
00654   Eigen::Vector3f vec = accu.tail<3> ();
00655   centroid.head<3> () = vec;//= accu.tail<3> ();
00656   centroid[3] = 0;
00657   covariance_matrix.coeffRef (0) = accu [0] - accu [6] * accu [6];
00658   covariance_matrix.coeffRef (1) = accu [1] - accu [6] * accu [7];
00659   covariance_matrix.coeffRef (2) = accu [2] - accu [6] * accu [8];
00660   covariance_matrix.coeffRef (4) = accu [3] - accu [7] * accu [7];
00661   covariance_matrix.coeffRef (5) = accu [4] - accu [7] * accu [8];
00662   covariance_matrix.coeffRef (8) = accu [5] - accu [8] * accu [8];
00663   covariance_matrix.coeffRef (3) = covariance_matrix.coeff (1);
00664   covariance_matrix.coeffRef (6) = covariance_matrix.coeff (2);
00665   covariance_matrix.coeffRef (7) = covariance_matrix.coeff (5);
00666 
00667   return (point_count);
00668 }
00669 
00671 template <typename PointT> inline unsigned int
00672 pcl::computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00673                                 const pcl::PointIndices &indices,
00674                                 Eigen::Matrix3f &covariance_matrix,
00675                                 Eigen::Vector4f &centroid)
00676 {
00677   return (computeMeanAndCovarianceMatrix (cloud, indices.indices, covariance_matrix, centroid));
00678 }
00679 
00681 template <typename PointT> inline unsigned int
00682 pcl::computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00683                                      Eigen::Matrix3d &covariance_matrix,
00684                                      Eigen::Vector4d &centroid)
00685 {
00686   // create the buffer on the stack which is much faster than using cloud.points[indices[i]] and centroid as a buffer
00687   Eigen::Matrix<double, 1, 9, Eigen::RowMajor> accu = Eigen::Matrix<double, 1, 9, Eigen::RowMajor>::Zero ();
00688   unsigned int point_count;
00689   if (cloud.is_dense)
00690   {
00691     point_count = cloud.size ();
00692     // For each point in the cloud
00693     for (size_t i = 0; i < point_count; ++i)
00694     {
00695       accu [0] += cloud[i].x * cloud[i].x;
00696       accu [1] += cloud[i].x * cloud[i].y;
00697       accu [2] += cloud[i].x * cloud[i].z;
00698       accu [3] += cloud[i].y * cloud[i].y;
00699       accu [4] += cloud[i].y * cloud[i].z;
00700       accu [5] += cloud[i].z * cloud[i].z;
00701       accu [6] += cloud[i].x;
00702       accu [7] += cloud[i].y;
00703       accu [8] += cloud[i].z;
00704     }
00705   }
00706   else
00707   {
00708     point_count = 0;
00709     for (size_t i = 0; i < cloud.points.size (); ++i)
00710     {
00711       if (!isFinite (cloud[i]))
00712         continue;
00713 
00714       accu [0] += cloud[i].x * cloud[i].x;
00715       accu [1] += cloud[i].x * cloud[i].y;
00716       accu [2] += cloud[i].x * cloud[i].z;
00717       accu [3] += cloud[i].y * cloud[i].y;
00718       accu [4] += cloud[i].y * cloud[i].z;
00719       accu [5] += cloud[i].z * cloud[i].z;
00720       accu [6] += cloud[i].x;
00721       accu [7] += cloud[i].y;
00722       accu [8] += cloud[i].z;
00723       ++point_count;
00724     }
00725   }
00726 
00727   if (point_count != 0)
00728   {
00729     accu /= (double) point_count;
00730     centroid.head<3> () = accu.tail<3> ();
00731     centroid[3] = 0;
00732     covariance_matrix.coeffRef (0) = accu [0] - accu [6] * accu [6];
00733     covariance_matrix.coeffRef (1) = accu [1] - accu [6] * accu [7];
00734     covariance_matrix.coeffRef (2) = accu [2] - accu [6] * accu [8];
00735     covariance_matrix.coeffRef (4) = accu [3] - accu [7] * accu [7];
00736     covariance_matrix.coeffRef (5) = accu [4] - accu [7] * accu [8];
00737     covariance_matrix.coeffRef (8) = accu [5] - accu [8] * accu [8];
00738     covariance_matrix.coeffRef (3) = covariance_matrix.coeff (1);
00739     covariance_matrix.coeffRef (6) = covariance_matrix.coeff (2);
00740     covariance_matrix.coeffRef (7) = covariance_matrix.coeff (5);
00741   }
00742   return (point_count);
00743 }
00744 
00746 template <typename PointT> inline unsigned int
00747 pcl::computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00748                                 const std::vector<int> &indices,
00749                                 Eigen::Matrix3d &covariance_matrix,
00750                                 Eigen::Vector4d &centroid)
00751 {
00752   // create the buffer on the stack which is much faster than using cloud.points[indices[i]] and centroid as a buffer
00753   Eigen::Matrix<double, 1, 9, Eigen::RowMajor> accu = Eigen::Matrix<double, 1, 9, Eigen::RowMajor>::Zero ();
00754   unsigned point_count;
00755   if (cloud.is_dense)
00756   {
00757     point_count = indices.size ();
00758     for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
00759     {
00760       //const PointT& point = cloud[*iIt];
00761       accu [0] += cloud[*iIt].x * cloud[*iIt].x;
00762       accu [1] += cloud[*iIt].x * cloud[*iIt].y;
00763       accu [2] += cloud[*iIt].x * cloud[*iIt].z;
00764       accu [3] += cloud[*iIt].y * cloud[*iIt].y;
00765       accu [4] += cloud[*iIt].y * cloud[*iIt].z;
00766       accu [5] += cloud[*iIt].z * cloud[*iIt].z;
00767       accu [6] += cloud[*iIt].x;
00768       accu [7] += cloud[*iIt].y;
00769       accu [8] += cloud[*iIt].z;
00770     }
00771   }
00772   else
00773   {
00774     point_count = 0;
00775     for (std::vector<int>::const_iterator iIt = indices.begin (); iIt != indices.end (); ++iIt)
00776     {
00777       if (!isFinite (cloud[*iIt]))
00778         continue;
00779 
00780       ++point_count;
00781       accu [0] += cloud[*iIt].x * cloud[*iIt].x;
00782       accu [1] += cloud[*iIt].x * cloud[*iIt].y;
00783       accu [2] += cloud[*iIt].x * cloud[*iIt].z;
00784       accu [3] += cloud[*iIt].y * cloud[*iIt].y; // 4
00785       accu [4] += cloud[*iIt].y * cloud[*iIt].z; // 5
00786       accu [5] += cloud[*iIt].z * cloud[*iIt].z; // 8
00787       accu [6] += cloud[*iIt].x;
00788       accu [7] += cloud[*iIt].y;
00789       accu [8] += cloud[*iIt].z;
00790     }
00791   }
00792 
00793   if (point_count != 0)
00794   {
00795     accu /= (double) point_count;
00796     Eigen::Vector3f vec = accu.tail<3> ();
00797     centroid.head<3> () = vec;//= accu.tail<3> ();
00798     centroid[3] = 0;
00799     covariance_matrix.coeffRef (0) = accu [0] - accu [6] * accu [6];
00800     covariance_matrix.coeffRef (1) = accu [1] - accu [6] * accu [7];
00801     covariance_matrix.coeffRef (2) = accu [2] - accu [6] * accu [8];
00802     covariance_matrix.coeffRef (4) = accu [3] - accu [7] * accu [7];
00803     covariance_matrix.coeffRef (5) = accu [4] - accu [7] * accu [8];
00804     covariance_matrix.coeffRef (8) = accu [5] - accu [8] * accu [8];
00805     covariance_matrix.coeffRef (3) = covariance_matrix.coeff (1);
00806     covariance_matrix.coeffRef (6) = covariance_matrix.coeff (2);
00807     covariance_matrix.coeffRef (7) = covariance_matrix.coeff (5);
00808   }
00809   return (point_count);
00810 }
00811 
00813 template <typename PointT> inline unsigned int
00814 pcl::computeMeanAndCovarianceMatrix (const pcl::PointCloud<PointT> &cloud,
00815                                   const pcl::PointIndices &indices,
00816                                   Eigen::Matrix3d &covariance_matrix,
00817                                   Eigen::Vector4d &centroid)
00818 {
00819   return (computeMeanAndCovarianceMatrix (cloud, indices.indices, covariance_matrix, centroid));
00820 }
00822 template <typename PointT> void
00823 pcl::demeanPointCloud (const pcl::PointCloud<PointT> &cloud_in,
00824                        const Eigen::Vector4f &centroid,
00825                        pcl::PointCloud<PointT> &cloud_out)
00826 {
00827   cloud_out = cloud_in;
00828 
00829   // Subtract the centroid from cloud_in
00830   for (size_t i = 0; i < cloud_in.points.size (); ++i)
00831     cloud_out.points[i].getVector4fMap () -= centroid;
00832 }
00833 
00835 template <typename PointT> void
00836 pcl::demeanPointCloud (const pcl::PointCloud<PointT> &cloud_in,
00837                        const std::vector<int> &indices,
00838                        const Eigen::Vector4f &centroid,
00839                        pcl::PointCloud<PointT> &cloud_out)
00840 {
00841   cloud_out.header = cloud_in.header;
00842   cloud_out.is_dense = cloud_in.is_dense;
00843   if (indices.size () == cloud_in.points.size ())
00844   {
00845     cloud_out.width    = cloud_in.width;
00846     cloud_out.height   = cloud_in.height;
00847   }
00848   else
00849   {
00850     cloud_out.width    = indices.size ();
00851     cloud_out.height   = 1;
00852   }
00853   cloud_out.points.resize (indices.size ());
00854 
00855   // Subtract the centroid from cloud_in
00856   for (size_t i = 0; i < indices.size (); ++i)
00857     cloud_out.points[i].getVector4fMap () = cloud_in.points[indices[i]].getVector4fMap () -
00858                                             centroid;
00859 }
00860 
00862 template <typename PointT> void
00863 pcl::demeanPointCloud (const pcl::PointCloud<PointT> &cloud_in,
00864                        const Eigen::Vector4f &centroid,
00865                        Eigen::MatrixXf &cloud_out)
00866 {
00867   size_t npts = cloud_in.points.size ();
00868 
00869   cloud_out = Eigen::MatrixXf::Zero (4, npts);        // keep the data aligned
00870 
00871   for (size_t i = 0; i < npts; ++i)
00872     // One column at a time
00873     cloud_out.block<4, 1> (0, i) = cloud_in.points[i].getVector4fMap () - centroid;
00874 
00875   // Make sure we zero the 4th dimension out (1 row, N columns)
00876   cloud_out.block (3, 0, 1, npts).setZero ();
00877 }
00878 
00880 template <typename PointT> void
00881 pcl::demeanPointCloud (const pcl::PointCloud<PointT> &cloud_in,
00882                        const std::vector<int> &indices,
00883                        const Eigen::Vector4f &centroid,
00884                        Eigen::MatrixXf &cloud_out)
00885 {
00886   size_t npts = indices.size ();
00887 
00888   cloud_out = Eigen::MatrixXf::Zero (4, npts);        // keep the data aligned
00889 
00890   for (size_t i = 0; i < npts; ++i)
00891     // One column at a time
00892     cloud_out.block<4, 1> (0, i) = cloud_in.points[indices[i]].getVector4fMap () - centroid;
00893 
00894   // Make sure we zero the 4th dimension out (1 row, N columns)
00895   cloud_out.block (3, 0, 1, npts).setZero ();
00896 }
00897 
00899 template <typename PointT> void
00900 pcl::demeanPointCloud (const pcl::PointCloud<PointT> &cloud_in,
00901                        const pcl::PointIndices &indices,
00902                        const Eigen::Vector4f &centroid,
00903                        Eigen::MatrixXf &cloud_out)
00904 {
00905   return (pcl::demeanPointCloud (cloud_in, indices.indices, centroid, cloud_out));
00906 }
00907 
00909 template <typename PointT> inline void
00910 pcl::computeNDCentroid (const pcl::PointCloud<PointT> &cloud, Eigen::VectorXf &centroid)
00911 {
00912   typedef typename pcl::traits::fieldList<PointT>::type FieldList;
00913 
00914   // Get the size of the fields
00915   centroid.setZero (boost::mpl::size<FieldList>::value);
00916 
00917   if (cloud.points.empty ())
00918     return;
00919   // Iterate over each point
00920   int size = cloud.points.size ();
00921   for (int i = 0; i < size; ++i)
00922   {
00923     // Iterate over each dimension
00924     pcl::for_each_type <FieldList> (NdCentroidFunctor <PointT> (cloud.points[i], centroid));
00925   }
00926   centroid /= size;
00927 }
00928 
00930 template <typename PointT> inline void
00931 pcl::computeNDCentroid (const pcl::PointCloud<PointT> &cloud, const std::vector<int> &indices,
00932                         Eigen::VectorXf &centroid)
00933 {
00934   typedef typename pcl::traits::fieldList<PointT>::type FieldList;
00935 
00936   // Get the size of the fields
00937   centroid.setZero (boost::mpl::size<FieldList>::value);
00938 
00939   if (indices.empty ())
00940     return;
00941   // Iterate over each point
00942   int nr_points = indices.size ();
00943   for (int i = 0; i < nr_points; ++i)
00944   {
00945     // Iterate over each dimension
00946     pcl::for_each_type <FieldList> (NdCentroidFunctor <PointT> (cloud.points[indices[i]], centroid));
00947   }
00948   centroid /= nr_points;
00949 }
00950 
00952 template <typename PointT> inline void
00953 pcl::computeNDCentroid (const pcl::PointCloud<PointT> &cloud,
00954                         const pcl::PointIndices &indices, Eigen::VectorXf &centroid)
00955 {
00956   return (pcl::computeNDCentroid<PointT> (cloud, indices.indices, centroid));
00957 }
00958 
00959 #endif  //#ifndef PCL_COMMON_IMPL_CENTROID_H_
00960