curvature_estimation_taubin.hpp
Go to the documentation of this file.
00001 #ifndef PCL_FEATURES_IMPL_CURVATURE_ESTIMATION_TAUBIN_HPP_
00002 #define PCL_FEATURES_IMPL_CURVATURE_ESTIMATION_TAUBIN_HPP_
00003 
00004 #include "curvature_estimation_taubin.h"
00005 
00006 template<typename PointInT, typename PointOutT> void pcl::CurvatureEstimationTaubin<PointInT, PointOutT>::computeFeature(
00007     const Eigen::MatrixXd &samples, PointCloudOut &output)
00008 {
00009   const double MIN_NEIGHBORS = 10;
00010 
00011   this->time_taubin = 0.0;
00012   this->time_curvature = 0.0;
00013 
00014   // allocate space to hold the indices and distances of the nearest neighbors
00015   std::vector<int> nn_indices;
00016   std::vector<float> nn_dists;
00017 
00018   // the output only contains finite values
00019   output.is_dense = true;
00020 
00021   // the output contains features for <num_samples_> point neighborhoods
00022   output.resize(samples.cols());
00023 
00024   // resize neighborhoods to store neighborhoods
00025   neighborhoods_.resize(samples.cols());
00026   neighborhood_centroids_.resize(samples.cols());
00027 
00028   // set-up an Organized Neighbor search
00029   if (input_->isOrganized())
00030   {
00031     pcl::search::OrganizedNeighbor<PointXYZRGBA>::Ptr organized_neighbor(
00032         new pcl::search::OrganizedNeighbor<PointXYZRGBA>());
00033     organized_neighbor->setInputCloud(input_);
00034     pcl::PointXYZRGBA search_point;
00035 
00036     // parallelization using OpenMP
00037 #ifdef _OPENMP
00038 #pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(num_threads_)
00039 #endif
00040     // iterate over samples matrix
00041     for (int i = 0; i < samples.cols(); i++)
00042     {
00043       search_point.x = samples(0, i);
00044       search_point.y = samples(1, i);
00045       search_point.z = samples(2, i);
00046       //~ printf("  %i: (%.2f, %.2f, %.2f) \n", i, search_point.x, search_point.y, search_point.z);
00047 
00048       // find points that lie inside the cylindrical shell
00049       if (organized_neighbor->radiusSearch(search_point, search_radius_, nn_indices, nn_dists) < MIN_NEIGHBORS)
00050       {
00051         output.points[i].normal[0] = output.points[i].normal[1] = output.points[i].normal[2] =
00052             std::numeric_limits<float>::quiet_NaN();
00053         output.points[i].curvature_axis[0] = output.points[i].curvature_axis[1] = output.points[i].curvature_axis[2] =
00054             output.points[i].normal[0];
00055         output.points[i].curvature_centroid[0] = output.points[i].curvature_centroid[1] =
00056             output.points[i].curvature_centroid[2] = output.points[i].normal[0];
00057         output.points[i].median_curvature = output.points[i].normal[0];
00058 
00059         output.is_dense = false;
00060         continue;
00061       }
00062       else
00063       {
00064         //~ printf("i: %i, nn_indices.size: %i\n", i, (int) nn_indices.size());
00065         // compute feature at index using point neighborhood
00066         computeFeature(nn_indices, i, output);
00067 
00068         // store neighborhood for later processing
00069         neighborhoods_[i] = nn_indices;
00070         neighborhood_centroids_[i] = i;
00071       }
00072     }
00073   }
00074   else
00075   {
00076     pcl::KdTreeFLANN<pcl::PointXYZRGBA>::Ptr tree(new pcl::KdTreeFLANN<pcl::PointXYZRGBA>());
00077     tree->setInputCloud(input_);
00078     pcl::PointXYZRGBA search_point;
00079 
00080     // parallelization using OpenMP
00081 #ifdef _OPENMP
00082 #pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(num_threads_)
00083 #endif
00084     // iterate over samples matrix
00085     for (int i = 0; i < samples.cols(); i++)
00086     {
00087       search_point.x = samples(0, i);
00088       search_point.y = samples(1, i);
00089       search_point.z = samples(2, i);
00090       //~ printf("  %i: (%.2f, %.2f, %.2f) \n", i, search_point.x, search_point.y, search_point.z);
00091 
00092       // find points that lie inside the cylindrical shell
00093       if (tree->radiusSearch(search_point, search_radius_, nn_indices, nn_dists) < MIN_NEIGHBORS)
00094       {
00095         output.points[i].normal[0] = output.points[i].normal[1] = output.points[i].normal[2] =
00096             std::numeric_limits<float>::quiet_NaN();
00097         output.points[i].curvature_axis[0] = output.points[i].curvature_axis[1] = output.points[i].curvature_axis[2] =
00098             output.points[i].normal[0];
00099         output.points[i].curvature_centroid[0] = output.points[i].curvature_centroid[1] =
00100             output.points[i].curvature_centroid[2] = output.points[i].normal[0];
00101         output.points[i].median_curvature = output.points[i].normal[0];
00102 
00103         output.is_dense = false;
00104         continue;
00105       }
00106       else
00107       {
00108         //~ printf("i: %i, nn_indices.size: %i\n", i, (int) nn_indices.size());
00109         // compute feature at index using point neighborhood
00110         computeFeature(nn_indices, i, output);
00111 
00112         // store neighborhood for later processing
00113         neighborhoods_[i] = nn_indices;
00114         neighborhood_centroids_[i] = i;
00115       }
00116     }
00117   }
00118 
00119   int n = 0;
00120   for (int i = 0; i < samples.cols(); i++)
00121   {
00122     if (neighborhoods_[i].size() >= MIN_NEIGHBORS)
00123       n++;
00124   }
00125   printf(" Taubin fitting: %.3f sec\n", this->time_taubin);
00126   printf(" Curvature estimation: %.3f sec\n", this->time_curvature);
00127 }
00128 
00129 template<typename PointInT, typename PointOutT> void pcl::CurvatureEstimationTaubin<PointInT, PointOutT>::computeFeature(
00130     PointCloudOut &output)
00131 {
00132   // allocate space to hold the indices and distances of the nearest neighbors
00133   std::vector<int> nn_indices(k_);
00134   std::vector<float> nn_dists(k_);
00135 
00136   // the output only contains finite values
00137   output.is_dense = true;
00138 
00139   // the output contains features for <num_samples_> point neighborhoods
00140   output.resize(num_samples_);
00141 
00142   // if the cloud is dense, do not check for NaNs / infs (saves some computation cycles)
00143   if (input_->is_dense)
00144   {
00145     // if no indices given, create a random set of indices (neighborhood centroids)
00146     if (indices_->size() != num_samples_)
00147     {
00148       std::srand(std::time(0)); // use current time as seed for random generator
00149       indices_->resize(num_samples_);
00150 
00151       for (int i = 0; i < num_samples_; i++)
00152       {
00153         (*indices_)[i] = std::rand() % input_->points.size();
00154       }
00155     }
00156   }
00157   else // otherwise, check for NaNs and infs
00158   {
00159     // if no indices given, create a random set of indices (neighborhood centroids)
00160     if (indices_->size() != num_samples_)
00161     {
00162       std::srand(std::time(0)); // use current time as seed for random generator
00163       indices_->resize(num_samples_);
00164 
00165       for (int i = 0; i < num_samples_; i++)
00166       {
00167         int r = std::rand() % input_->points.size();
00168 
00169         while (!isFinite((*input_)[r]))
00170           r = std::rand() % input_->points.size();
00171 
00172         (*indices_)[i] = r;
00173       }
00174     }
00175   }
00176 
00177   // resize neighborhoods to store neighborhoods
00178   neighborhoods_.resize(indices_->size());
00179   neighborhood_centroids_.resize(indices_->size());
00180 
00181   // parallelization using OpenMP
00182 #ifdef _OPENMP
00183 #pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(num_threads_)
00184 #endif
00185 
00186   // iterate over indices vector
00187   for (std::size_t idx = 0; idx < indices_->size(); ++idx)
00188   {
00189     if (this->searchForNeighbors((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
00190     {
00191       output.points[idx].normal[0] = output.points[idx].normal[1] = output.points[idx].normal[2] = std::numeric_limits<
00192           float>::quiet_NaN();
00193       output.points[idx].curvature_axis[0] = output.points[idx].curvature_axis[1] =
00194           output.points[idx].curvature_axis[2] = output.points[idx].normal[0];
00195       output.points[idx].curvature_centroid[0] = output.points[idx].curvature_centroid[1] =
00196           output.points[idx].curvature_centroid[2] = output.points[idx].normal[0];
00197       output.points[idx].median_curvature = output.points[idx].normal[0];
00198 
00199       output.is_dense = false;
00200       continue;
00201     }
00202 
00203     // compute feature at index using point neighborhood
00204     computeFeature(nn_indices, idx, output);
00205 
00206     // store neighborhood for later processing
00207     neighborhoods_[idx] = nn_indices;
00208     neighborhood_centroids_[idx] = (*indices_)[idx];
00209   }
00210 }
00211 
00212 template<typename PointInT, typename PointOutT> void pcl::CurvatureEstimationTaubin<PointInT, PointOutT>::computeFeature(
00213     const std::vector<int> &nn_indices, int index, PointCloudOut &output)
00214 {
00215   // perform Taubin fit
00216   double t0 = omp_get_wtime();
00217   Eigen::VectorXd quadric_parameters(10);
00218   Eigen::Vector3d quadric_centroid;
00219   Eigen::Matrix3d quadric_covariance_matrix;
00220   this->fitQuadric(nn_indices, quadric_parameters, quadric_centroid, quadric_covariance_matrix);
00221   this->time_taubin += omp_get_wtime() - t0;
00222 
00223   // estimate median curvature, normal axis, curvature axis, and curvature centroid
00224   t0 = omp_get_wtime();
00225   double median_curvature;
00226   Eigen::Vector3d normal;
00227   Eigen::Vector3d curvature_axis;
00228   Eigen::Vector3d curvature_centroid;
00229   this->estimateMedianCurvature(nn_indices, quadric_parameters, median_curvature, normal, curvature_axis,
00230                                 curvature_centroid);
00231   this->time_curvature += omp_get_wtime() - t0;
00232 
00233   // put median curvature, normal axis, curvature axis, and curvature centroid into cloud
00234   output[index].normal[0] = normal[0];
00235   output[index].normal[1] = normal[1];
00236   output[index].normal[2] = normal[2];
00237   output[index].curvature_axis[0] = curvature_axis[0];
00238   output[index].curvature_axis[1] = curvature_axis[1];
00239   output[index].curvature_axis[2] = curvature_axis[2];
00240   output[index].curvature_centroid[0] = curvature_centroid[0];
00241   output[index].curvature_centroid[1] = curvature_centroid[1];
00242   output[index].curvature_centroid[2] = curvature_centroid[2];
00243   output[index].median_curvature = median_curvature;
00244 }
00245 
00246 #endif // PCL_FEATURES_IMPL_CURVATURE_ESTIMATION_TAUBIN_HPP_


handle_detector
Author(s):
autogenerated on Thu Jun 6 2019 17:36:23