Point Cloud Library (PCL)  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
principal_curvatures.hpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-2011, Willow Garage, Inc.
00006  *
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions and the following
00017  *     disclaimer in the documentation and/or other materials provided
00018  *     with the distribution.
00019  *   * Neither the name of Willow Garage, Inc. nor the names of its
00020  *     contributors may be used to endorse or promote products derived
00021  *     from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  * $Id: principal_curvatures.hpp 3755 2011-12-31 23:45:30Z rusu $
00037  *
00038  */
00039 
00040 #ifndef PCL_FEATURES_IMPL_PRINCIPAL_CURVATURES_H_
00041 #define PCL_FEATURES_IMPL_PRINCIPAL_CURVATURES_H_
00042 
00043 #include "pcl/features/principal_curvatures.h"
00044 
00046 template <typename PointInT, typename PointNT, typename PointOutT> void
00047 pcl::PrincipalCurvaturesEstimation<PointInT, PointNT, PointOutT>::computePointPrincipalCurvatures (
00048       const pcl::PointCloud<PointNT> &normals, int p_idx, const std::vector<int> &indices,
00049       float &pcx, float &pcy, float &pcz, float &pc1, float &pc2)
00050 {
00051   EIGEN_ALIGN16 Eigen::Matrix3f I = Eigen::Matrix3f::Identity ();
00052   Eigen::Vector3f n_idx (normals.points[p_idx].normal[0], normals.points[p_idx].normal[1], normals.points[p_idx].normal[2]);
00053   EIGEN_ALIGN16 Eigen::Matrix3f M = I - n_idx * n_idx.transpose ();    // projection matrix (into tangent plane)
00054 
00055   // Project normals into the tangent plane
00056   Eigen::Vector3f normal;
00057   projected_normals_.resize (indices.size ());
00058   xyz_centroid_.setZero ();
00059   for (size_t idx = 0; idx < indices.size(); ++idx)
00060   {
00061     normal[0] = normals.points[indices[idx]].normal[0];
00062     normal[1] = normals.points[indices[idx]].normal[1];
00063     normal[2] = normals.points[indices[idx]].normal[2];
00064 
00065     projected_normals_[idx] = M * normal;
00066     xyz_centroid_ += projected_normals_[idx];
00067   }
00068 
00069   // Estimate the XYZ centroid
00070   xyz_centroid_ /= indices.size ();
00071 
00072   // Initialize to 0
00073   covariance_matrix_.setZero ();
00074 
00075   double demean_xy, demean_xz, demean_yz;
00076   // For each point in the cloud
00077   for (size_t idx = 0; idx < indices.size (); ++idx)
00078   {
00079     demean_ = projected_normals_[idx] - xyz_centroid_;
00080 
00081     demean_xy = demean_[0] * demean_[1];
00082     demean_xz = demean_[0] * demean_[2];
00083     demean_yz = demean_[1] * demean_[2];
00084 
00085     covariance_matrix_(0, 0) += demean_[0] * demean_[0];
00086     covariance_matrix_(0, 1) += demean_xy;
00087     covariance_matrix_(0, 2) += demean_xz;
00088 
00089     covariance_matrix_(1, 0) += demean_xy;
00090     covariance_matrix_(1, 1) += demean_[1] * demean_[1];
00091     covariance_matrix_(1, 2) += demean_yz;
00092 
00093     covariance_matrix_(2, 0) += demean_xz;
00094     covariance_matrix_(2, 1) += demean_yz;
00095     covariance_matrix_(2, 2) += demean_[2] * demean_[2];
00096   }
00097 
00098   // Extract the eigenvalues and eigenvectors
00099   //Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> ei_symm (covariance_matrix_);
00100   //eigenvalues_  = ei_symm.eigenvalues ();
00101   //eigenvectors_ = ei_symm.eigenvectors ();
00102   pcl::eigen33 (covariance_matrix_, eigenvectors_, eigenvalues_);
00103  
00104   pcx = eigenvectors_ (0, 2);
00105   pcy = eigenvectors_ (1, 2);
00106   pcz = eigenvectors_ (2, 2);
00107   float indices_size = 1.0f / indices.size ();
00108   pc1 = eigenvalues_ (2) * indices_size;
00109   pc2 = eigenvalues_ (1) * indices_size;
00110 }
00111 
00112 
00114 template <typename PointInT, typename PointNT, typename PointOutT> void
00115 pcl::PrincipalCurvaturesEstimation<PointInT, PointNT, PointOutT>::computeFeature (PointCloudOut &output)
00116 {
00117   // Allocate enough space to hold the results
00118   // \note This resize is irrelevant for a radiusSearch ().
00119   std::vector<int> nn_indices (k_);
00120   std::vector<float> nn_dists (k_);
00121 
00122   output.is_dense = true;
00123   // Save a few cycles by not checking every point for NaN/Inf values if the cloud is set to dense
00124   if (input_->is_dense)
00125   {
00126     // Iterating over the entire index vector
00127     for (size_t idx = 0; idx < indices_->size (); ++idx)
00128     {
00129       if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
00130       {
00131         output.points[idx].principal_curvature[0] = output.points[idx].principal_curvature[1] = output.points[idx].principal_curvature[2] = 
00132           output.points[idx].pc1 = output.points[idx].pc2 = std::numeric_limits<float>::quiet_NaN ();
00133         output.is_dense = false;
00134         continue;
00135       }
00136 
00137       // Estimate the principal curvatures at each patch
00138       computePointPrincipalCurvatures (*normals_, (*indices_)[idx], nn_indices,
00139                                        output.points[idx].principal_curvature[0], output.points[idx].principal_curvature[1], output.points[idx].principal_curvature[2],
00140                                        output.points[idx].pc1, output.points[idx].pc2);
00141     }
00142   }
00143   else
00144   {
00145     // Iterating over the entire index vector
00146     for (size_t idx = 0; idx < indices_->size (); ++idx)
00147     {
00148       if (!isFinite ((*input_)[(*indices_)[idx]]) ||
00149           this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
00150       {
00151         output.points[idx].principal_curvature[0] = output.points[idx].principal_curvature[1] = output.points[idx].principal_curvature[2] = 
00152           output.points[idx].pc1 = output.points[idx].pc2 = std::numeric_limits<float>::quiet_NaN ();
00153         output.is_dense = false;
00154         continue;
00155       }
00156 
00157       // Estimate the principal curvatures at each patch
00158       computePointPrincipalCurvatures (*normals_, (*indices_)[idx], nn_indices,
00159                                        output.points[idx].principal_curvature[0], output.points[idx].principal_curvature[1], output.points[idx].principal_curvature[2],
00160                                        output.points[idx].pc1, output.points[idx].pc2);
00161     }
00162   }
00163 }
00165 template <typename PointInT, typename PointNT> void
00166 pcl::PrincipalCurvaturesEstimation<PointInT, PointNT, Eigen::MatrixXf>::computeFeature (pcl::PointCloud<Eigen::MatrixXf> &output)
00167 {
00168   // Resize the output dataset
00169   output.points.resize (indices_->size (), 5);
00170 
00171   // Allocate enough space to hold the results
00172   // \note This resize is irrelevant for a radiusSearch ().
00173   std::vector<int> nn_indices (k_);
00174   std::vector<float> nn_dists (k_);
00175 
00176   output.is_dense = true;
00177   // Save a few cycles by not checking every point for NaN/Inf values if the cloud is set to dense
00178   if (input_->is_dense)
00179   {
00180     // Iterating over the entire index vector
00181     for (size_t idx = 0; idx < indices_->size (); ++idx)
00182     {
00183       if (this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
00184       {
00185         output.points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
00186         output.is_dense = false;
00187         continue;
00188       }
00189 
00190       // Estimate the principal curvatures at each patch
00191       this->computePointPrincipalCurvatures (*normals_, (*indices_)[idx], nn_indices,
00192                                        output.points (idx, 0), output.points (idx, 1), output.points (idx, 2),
00193                                        output.points (idx, 3), output.points (idx, 4));
00194     }
00195   }
00196   else
00197   {
00198     // Iterating over the entire index vector
00199     for (size_t idx = 0; idx < indices_->size (); ++idx)
00200     {
00201       if (!isFinite ((*input_)[(*indices_)[idx]]) ||
00202           this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
00203       {
00204         output.points.row (idx).setConstant (std::numeric_limits<float>::quiet_NaN ());
00205         output.is_dense = false;
00206         continue;
00207       }
00208 
00209       // Estimate the principal curvatures at each patch
00210       this->computePointPrincipalCurvatures (*normals_, (*indices_)[idx], nn_indices,
00211                                        output.points (idx, 0), output.points (idx, 1), output.points (idx, 2),
00212                                        output.points (idx, 3), output.points (idx, 4));
00213     }
00214   }
00215 }
00216 
00217 #define PCL_INSTANTIATE_PrincipalCurvaturesEstimation(T,NT,OutT) template class PCL_EXPORTS pcl::PrincipalCurvaturesEstimation<T,NT,OutT>;
00218 
00219 #endif    // PCL_FEATURES_IMPL_PRINCIPAL_CURVATURES_H_ 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines