curvature_estimation_taubin.hpp
Go to the documentation of this file.
1 #ifndef PCL_FEATURES_IMPL_CURVATURE_ESTIMATION_TAUBIN_HPP_
2 #define PCL_FEATURES_IMPL_CURVATURE_ESTIMATION_TAUBIN_HPP_
3 
5 
6 template<typename PointInT, typename PointOutT> void pcl::CurvatureEstimationTaubin<PointInT, PointOutT>::computeFeature(
7  const Eigen::MatrixXd &samples, PointCloudOut &output)
8 {
9  const double MIN_NEIGHBORS = 10;
10 
11  this->time_taubin = 0.0;
12  this->time_curvature = 0.0;
13 
14  // allocate space to hold the indices and distances of the nearest neighbors
15  std::vector<int> nn_indices;
16  std::vector<float> nn_dists;
17 
18  // the output only contains finite values
19  output.is_dense = true;
20 
21  // the output contains features for <num_samples_> point neighborhoods
22  output.resize(samples.cols());
23 
24  // resize neighborhoods to store neighborhoods
25  neighborhoods_.resize(samples.cols());
26  neighborhood_centroids_.resize(samples.cols());
27 
28  // set-up an Organized Neighbor search
29  if (input_->isOrganized())
30  {
31  pcl::search::OrganizedNeighbor<PointXYZRGBA>::Ptr organized_neighbor(
32  new pcl::search::OrganizedNeighbor<PointXYZRGBA>());
33  organized_neighbor->setInputCloud(input_);
34  pcl::PointXYZRGBA search_point;
35 
36  // parallelization using OpenMP
37 #ifdef _OPENMP
38 #pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(num_threads_)
39 #endif
40  // iterate over samples matrix
41  for (int i = 0; i < samples.cols(); i++)
42  {
43  search_point.x = samples(0, i);
44  search_point.y = samples(1, i);
45  search_point.z = samples(2, i);
46  //~ printf(" %i: (%.2f, %.2f, %.2f) \n", i, search_point.x, search_point.y, search_point.z);
47 
48  // find points that lie inside the cylindrical shell
49  if (organized_neighbor->radiusSearch(search_point, search_radius_, nn_indices, nn_dists) < MIN_NEIGHBORS)
50  {
51  output.points[i].normal[0] = output.points[i].normal[1] = output.points[i].normal[2] =
52  std::numeric_limits<float>::quiet_NaN();
53  output.points[i].curvature_axis[0] = output.points[i].curvature_axis[1] = output.points[i].curvature_axis[2] =
54  output.points[i].normal[0];
55  output.points[i].curvature_centroid[0] = output.points[i].curvature_centroid[1] =
56  output.points[i].curvature_centroid[2] = output.points[i].normal[0];
57  output.points[i].median_curvature = output.points[i].normal[0];
58 
59  output.is_dense = false;
60  continue;
61  }
62  else
63  {
64  //~ printf("i: %i, nn_indices.size: %i\n", i, (int) nn_indices.size());
65  // compute feature at index using point neighborhood
66  computeFeature(nn_indices, i, output);
67 
68  // store neighborhood for later processing
69  neighborhoods_[i] = nn_indices;
70  neighborhood_centroids_[i] = i;
71  }
72  }
73  }
74  else
75  {
76  pcl::KdTreeFLANN<pcl::PointXYZRGBA>::Ptr tree(new pcl::KdTreeFLANN<pcl::PointXYZRGBA>());
77  tree->setInputCloud(input_);
78  pcl::PointXYZRGBA search_point;
79 
80  // parallelization using OpenMP
81 #ifdef _OPENMP
82 #pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(num_threads_)
83 #endif
84  // iterate over samples matrix
85  for (int i = 0; i < samples.cols(); i++)
86  {
87  search_point.x = samples(0, i);
88  search_point.y = samples(1, i);
89  search_point.z = samples(2, i);
90  //~ printf(" %i: (%.2f, %.2f, %.2f) \n", i, search_point.x, search_point.y, search_point.z);
91 
92  // find points that lie inside the cylindrical shell
93  if (tree->radiusSearch(search_point, search_radius_, nn_indices, nn_dists) < MIN_NEIGHBORS)
94  {
95  output.points[i].normal[0] = output.points[i].normal[1] = output.points[i].normal[2] =
96  std::numeric_limits<float>::quiet_NaN();
97  output.points[i].curvature_axis[0] = output.points[i].curvature_axis[1] = output.points[i].curvature_axis[2] =
98  output.points[i].normal[0];
99  output.points[i].curvature_centroid[0] = output.points[i].curvature_centroid[1] =
100  output.points[i].curvature_centroid[2] = output.points[i].normal[0];
101  output.points[i].median_curvature = output.points[i].normal[0];
102 
103  output.is_dense = false;
104  continue;
105  }
106  else
107  {
108  //~ printf("i: %i, nn_indices.size: %i\n", i, (int) nn_indices.size());
109  // compute feature at index using point neighborhood
110  computeFeature(nn_indices, i, output);
111 
112  // store neighborhood for later processing
113  neighborhoods_[i] = nn_indices;
114  neighborhood_centroids_[i] = i;
115  }
116  }
117  }
118 
119  int n = 0;
120  for (int i = 0; i < samples.cols(); i++)
121  {
122  if (neighborhoods_[i].size() >= MIN_NEIGHBORS)
123  n++;
124  }
125  printf(" Taubin fitting: %.3f sec\n", this->time_taubin);
126  printf(" Curvature estimation: %.3f sec\n", this->time_curvature);
127 }
128 
129 template<typename PointInT, typename PointOutT> void pcl::CurvatureEstimationTaubin<PointInT, PointOutT>::computeFeature(
130  PointCloudOut &output)
131 {
132  // allocate space to hold the indices and distances of the nearest neighbors
133  std::vector<int> nn_indices(k_);
134  std::vector<float> nn_dists(k_);
135 
136  // the output only contains finite values
137  output.is_dense = true;
138 
139  // the output contains features for <num_samples_> point neighborhoods
140  output.resize(num_samples_);
141 
142  // if the cloud is dense, do not check for NaNs / infs (saves some computation cycles)
143  if (input_->is_dense)
144  {
145  // if no indices given, create a random set of indices (neighborhood centroids)
146  if (indices_->size() != num_samples_)
147  {
148  std::srand(std::time(0)); // use current time as seed for random generator
149  indices_->resize(num_samples_);
150 
151  for (int i = 0; i < num_samples_; i++)
152  {
153  (*indices_)[i] = std::rand() % input_->points.size();
154  }
155  }
156  }
157  else // otherwise, check for NaNs and infs
158  {
159  // if no indices given, create a random set of indices (neighborhood centroids)
160  if (indices_->size() != num_samples_)
161  {
162  std::srand(std::time(0)); // use current time as seed for random generator
163  indices_->resize(num_samples_);
164 
165  for (int i = 0; i < num_samples_; i++)
166  {
167  int r = std::rand() % input_->points.size();
168 
169  while (!isFinite((*input_)[r]))
170  r = std::rand() % input_->points.size();
171 
172  (*indices_)[i] = r;
173  }
174  }
175  }
176 
177  // resize neighborhoods to store neighborhoods
178  neighborhoods_.resize(indices_->size());
179  neighborhood_centroids_.resize(indices_->size());
180 
181  // parallelization using OpenMP
182 #ifdef _OPENMP
183 #pragma omp parallel for shared (output) private (nn_indices, nn_dists) num_threads(num_threads_)
184 #endif
185 
186  // iterate over indices vector
187  for (std::size_t idx = 0; idx < indices_->size(); ++idx)
188  {
189  if (this->searchForNeighbors((*indices_)[idx], search_parameter_, nn_indices, nn_dists) == 0)
190  {
191  output.points[idx].normal[0] = output.points[idx].normal[1] = output.points[idx].normal[2] = std::numeric_limits<
192  float>::quiet_NaN();
193  output.points[idx].curvature_axis[0] = output.points[idx].curvature_axis[1] =
194  output.points[idx].curvature_axis[2] = output.points[idx].normal[0];
195  output.points[idx].curvature_centroid[0] = output.points[idx].curvature_centroid[1] =
196  output.points[idx].curvature_centroid[2] = output.points[idx].normal[0];
197  output.points[idx].median_curvature = output.points[idx].normal[0];
198 
199  output.is_dense = false;
200  continue;
201  }
202 
203  // compute feature at index using point neighborhood
204  computeFeature(nn_indices, idx, output);
205 
206  // store neighborhood for later processing
207  neighborhoods_[idx] = nn_indices;
208  neighborhood_centroids_[idx] = (*indices_)[idx];
209  }
210 }
211 
212 template<typename PointInT, typename PointOutT> void pcl::CurvatureEstimationTaubin<PointInT, PointOutT>::computeFeature(
213  const std::vector<int> &nn_indices, int index, PointCloudOut &output)
214 {
215  // perform Taubin fit
216  double t0 = omp_get_wtime();
217  Eigen::VectorXd quadric_parameters(10);
218  Eigen::Vector3d quadric_centroid;
219  Eigen::Matrix3d quadric_covariance_matrix;
220  this->fitQuadric(nn_indices, quadric_parameters, quadric_centroid, quadric_covariance_matrix);
221  this->time_taubin += omp_get_wtime() - t0;
222 
223  // estimate median curvature, normal axis, curvature axis, and curvature centroid
224  t0 = omp_get_wtime();
225  double median_curvature;
226  Eigen::Vector3d normal;
227  Eigen::Vector3d curvature_axis;
228  Eigen::Vector3d curvature_centroid;
229  this->estimateMedianCurvature(nn_indices, quadric_parameters, median_curvature, normal, curvature_axis,
230  curvature_centroid);
231  this->time_curvature += omp_get_wtime() - t0;
232 
233  // put median curvature, normal axis, curvature axis, and curvature centroid into cloud
234  output[index].normal[0] = normal[0];
235  output[index].normal[1] = normal[1];
236  output[index].normal[2] = normal[2];
237  output[index].curvature_axis[0] = curvature_axis[0];
238  output[index].curvature_axis[1] = curvature_axis[1];
239  output[index].curvature_axis[2] = curvature_axis[2];
240  output[index].curvature_centroid[0] = curvature_centroid[0];
241  output[index].curvature_centroid[1] = curvature_centroid[1];
242  output[index].curvature_centroid[2] = curvature_centroid[2];
243  output[index].median_curvature = median_curvature;
244 }
245 
246 #endif // PCL_FEATURES_IMPL_CURVATURE_ESTIMATION_TAUBIN_HPP_
void computeFeature(const Eigen::MatrixXd &samples, PointCloudOut &output)
Estimate the curvature for a set of point neighborhoods with given centroids.
Feature< PointInT, PointOutT >::PointCloudOut PointCloudOut


handle_detector
Author(s):
autogenerated on Mon Jun 10 2019 13:29:00