|
Point Cloud Library (PCL)
1.5.1
|
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 ¢roid) 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 ¢roid) 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 ¢roid) 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 ¢roid, 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 ¢roid, 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 ¢roid, 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 ¢roid, 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 ¢roid, 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 ¢roid, 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 ¢roid) 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 ¢roid) 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 ¢roid) 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 ¢roid) 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 ¢roid) 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 ¢roid) 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 ¢roid, 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 ¢roid, 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 ¢roid, 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 ¢roid, 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 ¢roid, 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 ¢roid) 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 ¢roid) 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 ¢roid) 00955 { 00956 return (pcl::computeNDCentroid<PointT> (cloud, indices.indices, centroid)); 00957 } 00958 00959 #endif //#ifndef PCL_COMMON_IMPL_CENTROID_H_ 00960
1.8.0